am 9200a867: am 6f088df9: am 44551060: Allow using third-party HTTP/... stacks for per-network URLs.

* commit '9200a867a71b02c0147b0a9670f1e141d398aa43':
  Allow using third-party HTTP/... stacks for per-network URLs.
This commit is contained in:
Lorenzo Colitti
2014-07-31 03:11:12 +00:00
committed by Android Git Automerger
3 changed files with 111 additions and 21 deletions

View File

@@ -17477,10 +17477,15 @@ package android.net {
method public java.net.URL getBoundURL(java.net.URL) throws java.net.MalformedURLException;
method public java.net.InetAddress getByName(java.lang.String) throws java.net.UnknownHostException;
method public javax.net.SocketFactory getSocketFactory();
method public static void setNetworkBoundURLFactory(android.net.NetworkBoundURLFactory);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
}
public abstract interface NetworkBoundURLFactory {
method public abstract java.net.URL getBoundURL(android.net.Network, java.net.URL) throws java.net.MalformedURLException;
}
public final class NetworkCapabilities implements android.os.Parcelable {
ctor public NetworkCapabilities(android.net.NetworkCapabilities);
method public int describeContents();

View File

@@ -16,6 +16,7 @@
package android.net;
import android.net.NetworkBoundURLFactory;
import android.net.NetworkUtils;
import android.os.Parcelable;
import android.os.Parcel;
@@ -29,6 +30,8 @@ import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.net.URL;
import java.net.URLStreamHandler;
import java.util.concurrent.atomic.AtomicReference;
import javax.net.SocketFactory;
import com.android.okhttp.HostResolver;
@@ -52,8 +55,8 @@ public class Network implements Parcelable {
// Objects used to perform per-network operations such as getSocketFactory
// and getBoundURL, and a lock to protect access to them.
private NetworkBoundSocketFactory mNetworkBoundSocketFactory = null;
private OkHttpClient mOkHttpClient = null;
private volatile NetworkBoundSocketFactory mNetworkBoundSocketFactory = null;
private volatile OkHttpClient mOkHttpClient = null;
private Object mLock = new Object();
/**
@@ -174,36 +177,83 @@ public class Network implements Parcelable {
* {@code Network}.
*/
public SocketFactory getSocketFactory() {
synchronized (mLock) {
if (mNetworkBoundSocketFactory == null) {
mNetworkBoundSocketFactory = new NetworkBoundSocketFactory(netId);
if (mNetworkBoundSocketFactory == null) {
synchronized (mLock) {
if (mNetworkBoundSocketFactory == null) {
mNetworkBoundSocketFactory = new NetworkBoundSocketFactory(netId);
}
}
}
return mNetworkBoundSocketFactory;
}
/** The default NetworkBoundURLFactory, used if setNetworkBoundURLFactory is never called. */
private static final NetworkBoundURLFactory DEFAULT_URL_FACTORY = new NetworkBoundURLFactory() {
public URL getBoundURL(final Network network, URL url) throws MalformedURLException {
if (network.mOkHttpClient == null) {
synchronized (network.mLock) {
if (network.mOkHttpClient == null) {
HostResolver hostResolver = new HostResolver() {
@Override
public InetAddress[] getAllByName(String host)
throws UnknownHostException {
return network.getAllByName(host);
}
};
network.mOkHttpClient = new OkHttpClient()
.setSocketFactory(network.getSocketFactory())
.setHostResolver(hostResolver);
}
}
}
String protocol = url.getProtocol();
URLStreamHandler handler = network.mOkHttpClient.createURLStreamHandler(protocol);
if (handler == null) {
// OkHttpClient only supports HTTP and HTTPS and returns a null URLStreamHandler if
// passed another protocol.
throw new MalformedURLException("Invalid URL or unrecognized protocol " + protocol);
}
return new URL(url, "", handler);
}
};
private static AtomicReference<NetworkBoundURLFactory> sNetworkBoundURLFactory =
new AtomicReference <NetworkBoundURLFactory>(DEFAULT_URL_FACTORY);
/**
* Returns a {@link URL} based on the given URL but bound to this {@code Network}.
* Note that if this {@code Network} ever disconnects, this factory and any URL object it
* produced in the past or future will cease to work.
* Returns a {@link URL} based on the given URL but bound to this {@code Network},
* such that opening the URL will send all network traffic on this Network.
*
* Note that if this {@code Network} ever disconnects, any URL object generated by this method
* in the past or future will cease to work.
*
* The returned URL may have a {@link URLStreamHandler} explicitly set, which may not be the
* handler generated by the factory set with {@link java.net.URL.setURLStreamHandlerFactory}. To
* affect the {@code URLStreamHandler}s of URLs returned by this method, call
* {@link #setNetworkBoundURLFactory}.
*
* Because the returned URLs may have an explicit {@code URLStreamHandler} set, using them as a
* context when constructing other URLs and explicitly specifying a {@code URLStreamHandler} may
* result in URLs that are no longer bound to the same {@code Network}.
*
* The default implementation only supports {@code HTTP} and {@code HTTPS} URLs.
*
* @return a {@link URL} bound to this {@code Network}.
*/
public URL getBoundURL(URL url) throws MalformedURLException {
synchronized (mLock) {
if (mOkHttpClient == null) {
HostResolver hostResolver = new HostResolver() {
@Override
public InetAddress[] getAllByName(String host) throws UnknownHostException {
return Network.this.getAllByName(host);
}
};
mOkHttpClient = new OkHttpClient()
.setSocketFactory(getSocketFactory())
.setHostResolver(hostResolver);
}
return sNetworkBoundURLFactory.get().getBoundURL(this, url);
}
/**
* Sets the {@link NetworkBoundURLFactory} to be used by future {@link #getBoundURL} calls.
* If {@code null}, clears any factory that was previously specified.
*/
public static void setNetworkBoundURLFactory(NetworkBoundURLFactory factory) {
if (factory == null) {
factory = DEFAULT_URL_FACTORY;
}
return new URL(url, "", mOkHttpClient.createURLStreamHandler(url.getProtocol()));
sNetworkBoundURLFactory.set(factory);
}
// implement the Parcelable interface

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net;
import java.net.MalformedURLException;
import java.net.URL;
/**
* An interface that describes a factory for network-specific {@link URL} objects.
*/
public interface NetworkBoundURLFactory {
/**
* Returns a {@link URL} based on the given URL but bound to the specified {@code Network},
* such that opening the URL will send all network traffic on the specified Network.
*
* @return a {@link URL} bound to this {@code Network}.
* @throws MalformedURLException if the URL was not valid, or this factory cannot handle the
* specified URL (e.g., if it does not support the protocol of the URL).
*/
public URL getBoundURL(Network network, URL url) throws MalformedURLException;
}