Merge changes I6abd2221,I2c149d29,I45d22857,I1f879b2c,If4986a25, ...
am: 6c0106b57f Change-Id: I86bc83e2bd859b48017f12832e9ff0080ec162b8
This commit is contained in:
@@ -32,6 +32,7 @@ import java.util.Collections;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
/**
|
||||
* Describes the properties of a network link.
|
||||
@@ -48,13 +49,13 @@ import java.util.Objects;
|
||||
public final class LinkProperties implements Parcelable {
|
||||
// The interface described by the network link.
|
||||
private String mIfaceName;
|
||||
private ArrayList<LinkAddress> mLinkAddresses = new ArrayList<LinkAddress>();
|
||||
private ArrayList<InetAddress> mDnses = new ArrayList<InetAddress>();
|
||||
private ArrayList<InetAddress> mValidatedPrivateDnses = new ArrayList<InetAddress>();
|
||||
private ArrayList<LinkAddress> mLinkAddresses = new ArrayList<>();
|
||||
private ArrayList<InetAddress> mDnses = new ArrayList<>();
|
||||
private ArrayList<InetAddress> mValidatedPrivateDnses = new ArrayList<>();
|
||||
private boolean mUsePrivateDns;
|
||||
private String mPrivateDnsServerName;
|
||||
private String mDomains;
|
||||
private ArrayList<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
|
||||
private ArrayList<RouteInfo> mRoutes = new ArrayList<>();
|
||||
private ProxyInfo mHttpProxy;
|
||||
private int mMtu;
|
||||
// in the format "rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max"
|
||||
@@ -66,15 +67,14 @@ public final class LinkProperties implements Parcelable {
|
||||
|
||||
// Stores the properties of links that are "stacked" above this link.
|
||||
// Indexed by interface name to allow modification and to prevent duplicates being added.
|
||||
private Hashtable<String, LinkProperties> mStackedLinks =
|
||||
new Hashtable<String, LinkProperties>();
|
||||
private Hashtable<String, LinkProperties> mStackedLinks = new Hashtable<>();
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static class CompareResult<T> {
|
||||
public final List<T> removed = new ArrayList<T>();
|
||||
public final List<T> added = new ArrayList<T>();
|
||||
public final List<T> removed = new ArrayList<>();
|
||||
public final List<T> added = new ArrayList<>();
|
||||
|
||||
public CompareResult() {}
|
||||
|
||||
@@ -93,12 +93,9 @@ public final class LinkProperties implements Parcelable {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String retVal = "removed=[";
|
||||
for (T addr : removed) retVal += addr.toString() + ",";
|
||||
retVal += "] added=[";
|
||||
for (T addr : added) retVal += addr.toString() + ",";
|
||||
retVal += "]";
|
||||
return retVal;
|
||||
return "removed=[" + TextUtils.join(",", removed)
|
||||
+ "] added=[" + TextUtils.join(",", added)
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +117,7 @@ public final class LinkProperties implements Parcelable {
|
||||
public static ProvisioningChange compareProvisioning(
|
||||
LinkProperties before, LinkProperties after) {
|
||||
if (before.isProvisioned() && after.isProvisioned()) {
|
||||
// On dualstack networks, DHCPv4 renewals can occasionally fail.
|
||||
// On dual-stack networks, DHCPv4 renewals can occasionally fail.
|
||||
// When this happens, IPv6-reachable services continue to function
|
||||
// normally but IPv4-only services (naturally) fail.
|
||||
//
|
||||
@@ -131,7 +128,7 @@ public final class LinkProperties implements Parcelable {
|
||||
//
|
||||
// For users, this is confusing and unexpected behaviour, and is
|
||||
// not necessarily easy to diagnose. Therefore, we treat changing
|
||||
// from a dualstack network to an IPv6-only network equivalent to
|
||||
// from a dual-stack network to an IPv6-only network equivalent to
|
||||
// a total loss of provisioning.
|
||||
//
|
||||
// For one such example of this, see b/18867306.
|
||||
@@ -139,7 +136,7 @@ public final class LinkProperties implements Parcelable {
|
||||
// Additionally, losing IPv6 provisioning can result in TCP
|
||||
// connections getting stuck until timeouts fire and other
|
||||
// baffling failures. Therefore, loss of either IPv4 or IPv6 on a
|
||||
// previously dualstack network is deemed a lost of provisioning.
|
||||
// previously dual-stack network is deemed a lost of provisioning.
|
||||
if ((before.isIPv4Provisioned() && !after.isIPv4Provisioned()) ||
|
||||
(before.isIPv6Provisioned() && !after.isIPv6Provisioned())) {
|
||||
return ProvisioningChange.LOST_PROVISIONING;
|
||||
@@ -165,22 +162,19 @@ public final class LinkProperties implements Parcelable {
|
||||
*/
|
||||
public LinkProperties(LinkProperties source) {
|
||||
if (source != null) {
|
||||
mIfaceName = source.getInterfaceName();
|
||||
for (LinkAddress l : source.getLinkAddresses()) mLinkAddresses.add(l);
|
||||
for (InetAddress i : source.getDnsServers()) mDnses.add(i);
|
||||
for (InetAddress i : source.getValidatedPrivateDnsServers()) {
|
||||
mValidatedPrivateDnses.add(i);
|
||||
}
|
||||
mIfaceName = source.mIfaceName;
|
||||
mLinkAddresses.addAll(source.mLinkAddresses);
|
||||
mDnses.addAll(source.mDnses);
|
||||
mValidatedPrivateDnses.addAll(source.mValidatedPrivateDnses);
|
||||
mUsePrivateDns = source.mUsePrivateDns;
|
||||
mPrivateDnsServerName = source.mPrivateDnsServerName;
|
||||
mDomains = source.getDomains();
|
||||
for (RouteInfo r : source.getRoutes()) mRoutes.add(r);
|
||||
mHttpProxy = (source.getHttpProxy() == null) ?
|
||||
null : new ProxyInfo(source.getHttpProxy());
|
||||
mDomains = source.mDomains;
|
||||
mRoutes.addAll(source.mRoutes);
|
||||
mHttpProxy = (source.mHttpProxy == null) ? null : new ProxyInfo(source.mHttpProxy);
|
||||
for (LinkProperties l: source.mStackedLinks.values()) {
|
||||
addStackedLink(l);
|
||||
}
|
||||
setMtu(source.getMtu());
|
||||
setMtu(source.mMtu);
|
||||
mTcpBufferSizes = source.mTcpBufferSizes;
|
||||
}
|
||||
}
|
||||
@@ -194,7 +188,7 @@ public final class LinkProperties implements Parcelable {
|
||||
*/
|
||||
public void setInterfaceName(String iface) {
|
||||
mIfaceName = iface;
|
||||
ArrayList<RouteInfo> newRoutes = new ArrayList<RouteInfo>(mRoutes.size());
|
||||
ArrayList<RouteInfo> newRoutes = new ArrayList<>(mRoutes.size());
|
||||
for (RouteInfo route : mRoutes) {
|
||||
newRoutes.add(routeWithInterface(route));
|
||||
}
|
||||
@@ -214,8 +208,8 @@ public final class LinkProperties implements Parcelable {
|
||||
* @hide
|
||||
*/
|
||||
public List<String> getAllInterfaceNames() {
|
||||
List<String> interfaceNames = new ArrayList<String>(mStackedLinks.size() + 1);
|
||||
if (mIfaceName != null) interfaceNames.add(new String(mIfaceName));
|
||||
List<String> interfaceNames = new ArrayList<>(mStackedLinks.size() + 1);
|
||||
if (mIfaceName != null) interfaceNames.add(mIfaceName);
|
||||
for (LinkProperties stacked: mStackedLinks.values()) {
|
||||
interfaceNames.addAll(stacked.getAllInterfaceNames());
|
||||
}
|
||||
@@ -229,11 +223,11 @@ public final class LinkProperties implements Parcelable {
|
||||
* prefix lengths for each address. This is a simplified utility alternative to
|
||||
* {@link LinkProperties#getLinkAddresses}.
|
||||
*
|
||||
* @return An umodifiable {@link List} of {@link InetAddress} for this link.
|
||||
* @return An unmodifiable {@link List} of {@link InetAddress} for this link.
|
||||
* @hide
|
||||
*/
|
||||
public List<InetAddress> getAddresses() {
|
||||
List<InetAddress> addresses = new ArrayList<InetAddress>();
|
||||
List<InetAddress> addresses = new ArrayList<>();
|
||||
for (LinkAddress linkAddress : mLinkAddresses) {
|
||||
addresses.add(linkAddress.getAddress());
|
||||
}
|
||||
@@ -245,7 +239,7 @@ public final class LinkProperties implements Parcelable {
|
||||
* @hide
|
||||
*/
|
||||
public List<InetAddress> getAllAddresses() {
|
||||
List<InetAddress> addresses = new ArrayList<InetAddress>();
|
||||
List<InetAddress> addresses = new ArrayList<>();
|
||||
for (LinkAddress linkAddress : mLinkAddresses) {
|
||||
addresses.add(linkAddress.getAddress());
|
||||
}
|
||||
@@ -322,8 +316,7 @@ public final class LinkProperties implements Parcelable {
|
||||
* @hide
|
||||
*/
|
||||
public List<LinkAddress> getAllLinkAddresses() {
|
||||
List<LinkAddress> addresses = new ArrayList<LinkAddress>();
|
||||
addresses.addAll(mLinkAddresses);
|
||||
List<LinkAddress> addresses = new ArrayList<>(mLinkAddresses);
|
||||
for (LinkProperties stacked: mStackedLinks.values()) {
|
||||
addresses.addAll(stacked.getAllLinkAddresses());
|
||||
}
|
||||
@@ -391,7 +384,7 @@ public final class LinkProperties implements Parcelable {
|
||||
/**
|
||||
* Returns all the {@link InetAddress} for DNS servers on this link.
|
||||
*
|
||||
* @return An umodifiable {@link List} of {@link InetAddress} for DNS servers on
|
||||
* @return An unmodifiable {@link List} of {@link InetAddress} for DNS servers on
|
||||
* this link.
|
||||
*/
|
||||
public List<InetAddress> getDnsServers() {
|
||||
@@ -643,7 +636,7 @@ public final class LinkProperties implements Parcelable {
|
||||
* @hide
|
||||
*/
|
||||
public void ensureDirectlyConnectedRoutes() {
|
||||
for (LinkAddress addr: mLinkAddresses) {
|
||||
for (LinkAddress addr : mLinkAddresses) {
|
||||
addRoute(new RouteInfo(addr, null, mIfaceName));
|
||||
}
|
||||
}
|
||||
@@ -653,8 +646,7 @@ public final class LinkProperties implements Parcelable {
|
||||
* @hide
|
||||
*/
|
||||
public List<RouteInfo> getAllRoutes() {
|
||||
List<RouteInfo> routes = new ArrayList<>();
|
||||
routes.addAll(mRoutes);
|
||||
List<RouteInfo> routes = new ArrayList<>(mRoutes);
|
||||
for (LinkProperties stacked: mStackedLinks.values()) {
|
||||
routes.addAll(stacked.getAllRoutes());
|
||||
}
|
||||
@@ -685,7 +677,7 @@ public final class LinkProperties implements Parcelable {
|
||||
/**
|
||||
* Adds a stacked link.
|
||||
*
|
||||
* If there is already a stacked link with the same interfacename as link,
|
||||
* If there is already a stacked link with the same interface name as link,
|
||||
* that link is replaced with link. Otherwise, link is added to the list
|
||||
* of stacked links. If link is null, nothing changes.
|
||||
*
|
||||
@@ -725,9 +717,9 @@ public final class LinkProperties implements Parcelable {
|
||||
*/
|
||||
public @NonNull List<LinkProperties> getStackedLinks() {
|
||||
if (mStackedLinks.isEmpty()) {
|
||||
return Collections.EMPTY_LIST;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<LinkProperties> stacked = new ArrayList<LinkProperties>();
|
||||
List<LinkProperties> stacked = new ArrayList<>();
|
||||
for (LinkProperties link : mStackedLinks.values()) {
|
||||
stacked.add(new LinkProperties(link));
|
||||
}
|
||||
@@ -761,57 +753,76 @@ public final class LinkProperties implements Parcelable {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String ifaceName = (mIfaceName == null ? "" : "InterfaceName: " + mIfaceName + " ");
|
||||
// Space as a separator, so no need for spaces at start/end of the individual fragments.
|
||||
final StringJoiner resultJoiner = new StringJoiner(" ", "{", "}");
|
||||
|
||||
String linkAddresses = "LinkAddresses: [";
|
||||
for (LinkAddress addr : mLinkAddresses) linkAddresses += addr.toString() + ",";
|
||||
linkAddresses += "] ";
|
||||
if (mIfaceName != null) {
|
||||
resultJoiner.add("InterfaceName:");
|
||||
resultJoiner.add(mIfaceName);
|
||||
}
|
||||
|
||||
String dns = "DnsAddresses: [";
|
||||
for (InetAddress addr : mDnses) dns += addr.getHostAddress() + ",";
|
||||
dns += "] ";
|
||||
resultJoiner.add("LinkAddresses: [");
|
||||
if (!mLinkAddresses.isEmpty()) {
|
||||
resultJoiner.add(TextUtils.join(",", mLinkAddresses));
|
||||
}
|
||||
resultJoiner.add("]");
|
||||
|
||||
String usePrivateDns = "UsePrivateDns: " + mUsePrivateDns + " ";
|
||||
resultJoiner.add("DnsAddresses: [");
|
||||
if (!mDnses.isEmpty()) {
|
||||
resultJoiner.add(TextUtils.join(",", mDnses));
|
||||
}
|
||||
resultJoiner.add("]");
|
||||
|
||||
if (mUsePrivateDns) {
|
||||
resultJoiner.add("UsePrivateDns: true");
|
||||
}
|
||||
|
||||
String privateDnsServerName = "";
|
||||
if (mPrivateDnsServerName != null) {
|
||||
privateDnsServerName = "PrivateDnsServerName: " + mPrivateDnsServerName + " ";
|
||||
resultJoiner.add("PrivateDnsServerName:");
|
||||
resultJoiner.add(mPrivateDnsServerName);
|
||||
}
|
||||
|
||||
String validatedPrivateDns = "";
|
||||
if (!mValidatedPrivateDnses.isEmpty()) {
|
||||
validatedPrivateDns = "ValidatedPrivateDnsAddresses: [";
|
||||
for (InetAddress addr : mValidatedPrivateDnses) {
|
||||
validatedPrivateDns += addr.getHostAddress() + ",";
|
||||
final StringJoiner validatedPrivateDnsesJoiner =
|
||||
new StringJoiner(",", "ValidatedPrivateDnsAddresses: [", "]");
|
||||
for (final InetAddress addr : mValidatedPrivateDnses) {
|
||||
validatedPrivateDnsesJoiner.add(addr.getHostAddress());
|
||||
}
|
||||
validatedPrivateDns += "] ";
|
||||
resultJoiner.add(validatedPrivateDnsesJoiner.toString());
|
||||
}
|
||||
|
||||
String domainName = "Domains: " + mDomains;
|
||||
resultJoiner.add("Domains:");
|
||||
resultJoiner.add(mDomains);
|
||||
|
||||
String mtu = " MTU: " + mMtu;
|
||||
resultJoiner.add("MTU:");
|
||||
resultJoiner.add(Integer.toString(mMtu));
|
||||
|
||||
String tcpBuffSizes = "";
|
||||
if (mTcpBufferSizes != null) {
|
||||
tcpBuffSizes = " TcpBufferSizes: " + mTcpBufferSizes;
|
||||
resultJoiner.add("TcpBufferSizes:");
|
||||
resultJoiner.add(mTcpBufferSizes);
|
||||
}
|
||||
|
||||
String routes = " Routes: [";
|
||||
for (RouteInfo route : mRoutes) routes += route.toString() + ",";
|
||||
routes += "] ";
|
||||
String proxy = (mHttpProxy == null ? "" : " HttpProxy: " + mHttpProxy.toString() + " ");
|
||||
resultJoiner.add("Routes: [");
|
||||
if (!mRoutes.isEmpty()) {
|
||||
resultJoiner.add(TextUtils.join(",", mRoutes));
|
||||
}
|
||||
resultJoiner.add("]");
|
||||
|
||||
String stacked = "";
|
||||
if (mStackedLinks.values().size() > 0) {
|
||||
stacked += " Stacked: [";
|
||||
for (LinkProperties link: mStackedLinks.values()) {
|
||||
stacked += " [" + link.toString() + " ],";
|
||||
if (mHttpProxy != null) {
|
||||
resultJoiner.add("HttpProxy:");
|
||||
resultJoiner.add(mHttpProxy.toString());
|
||||
}
|
||||
|
||||
final Collection<LinkProperties> stackedLinksValues = mStackedLinks.values();
|
||||
if (!stackedLinksValues.isEmpty()) {
|
||||
final StringJoiner stackedLinksJoiner = new StringJoiner(",", "Stacked: [", "]");
|
||||
for (final LinkProperties lp : stackedLinksValues) {
|
||||
stackedLinksJoiner.add("[ " + lp + " ]");
|
||||
}
|
||||
stacked += "] ";
|
||||
resultJoiner.add(stackedLinksJoiner.toString());
|
||||
}
|
||||
return "{" + ifaceName + linkAddresses + routes + dns + usePrivateDns
|
||||
+ privateDnsServerName + validatedPrivateDns + domainName + mtu + tcpBuffSizes + proxy
|
||||
+ stacked + "}";
|
||||
|
||||
return resultJoiner.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1028,7 +1039,7 @@ public final class LinkProperties implements Parcelable {
|
||||
if (mDomains == null) {
|
||||
if (targetDomains != null) return false;
|
||||
} else {
|
||||
if (mDomains.equals(targetDomains) == false) return false;
|
||||
if (!mDomains.equals(targetDomains)) return false;
|
||||
}
|
||||
return (mDnses.size() == targetDnses.size()) ?
|
||||
mDnses.containsAll(targetDnses) : false;
|
||||
@@ -1130,7 +1141,6 @@ public final class LinkProperties implements Parcelable {
|
||||
return Objects.equals(mTcpBufferSizes, target.mTcpBufferSizes);
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Compares this {@code LinkProperties} instance against the target
|
||||
* LinkProperties in {@code obj}. Two LinkPropertieses are equal if
|
||||
@@ -1145,13 +1155,14 @@ public final class LinkProperties implements Parcelable {
|
||||
* @param obj the object to be tested for equality.
|
||||
* @return {@code true} if both objects are equal, {@code false} otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
|
||||
if (!(obj instanceof LinkProperties)) return false;
|
||||
|
||||
LinkProperties target = (LinkProperties) obj;
|
||||
/**
|
||||
/*
|
||||
* This method does not check that stacked interfaces are equal, because
|
||||
* stacked interfaces are not so much a property of the link as a
|
||||
* description of connections between links.
|
||||
@@ -1258,12 +1269,13 @@ public final class LinkProperties implements Parcelable {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* generate hashcode based on significant fields
|
||||
* Generate hashcode based on significant fields
|
||||
*
|
||||
* Equal objects must produce the same hash code, while unequal objects
|
||||
* may have the same hash codes.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ((null == mIfaceName) ? 0 : mIfaceName.hashCode()
|
||||
+ mLinkAddresses.size() * 31
|
||||
@@ -1313,7 +1325,7 @@ public final class LinkProperties implements Parcelable {
|
||||
} else {
|
||||
dest.writeByte((byte)0);
|
||||
}
|
||||
ArrayList<LinkProperties> stackedLinks = new ArrayList(mStackedLinks.values());
|
||||
ArrayList<LinkProperties> stackedLinks = new ArrayList<>(mStackedLinks.values());
|
||||
dest.writeList(stackedLinks);
|
||||
}
|
||||
|
||||
@@ -1331,7 +1343,7 @@ public final class LinkProperties implements Parcelable {
|
||||
}
|
||||
int addressCount = in.readInt();
|
||||
for (int i = 0; i < addressCount; i++) {
|
||||
netProp.addLinkAddress((LinkAddress) in.readParcelable(null));
|
||||
netProp.addLinkAddress(in.readParcelable(null));
|
||||
}
|
||||
addressCount = in.readInt();
|
||||
for (int i = 0; i < addressCount; i++) {
|
||||
@@ -1353,10 +1365,10 @@ public final class LinkProperties implements Parcelable {
|
||||
netProp.setTcpBufferSizes(in.readString());
|
||||
addressCount = in.readInt();
|
||||
for (int i = 0; i < addressCount; i++) {
|
||||
netProp.addRoute((RouteInfo) in.readParcelable(null));
|
||||
netProp.addRoute(in.readParcelable(null));
|
||||
}
|
||||
if (in.readByte() == 1) {
|
||||
netProp.setHttpProxy((ProxyInfo) in.readParcelable(null));
|
||||
netProp.setHttpProxy(in.readParcelable(null));
|
||||
}
|
||||
ArrayList<LinkProperties> stackedLinks = new ArrayList<LinkProperties>();
|
||||
in.readList(stackedLinks, LinkProperties.class.getClassLoader());
|
||||
@@ -1377,10 +1389,9 @@ public final class LinkProperties implements Parcelable {
|
||||
*/
|
||||
public static boolean isValidMtu(int mtu, boolean ipv6) {
|
||||
if (ipv6) {
|
||||
if (mtu >= MIN_MTU_V6 && mtu <= MAX_MTU) return true;
|
||||
return mtu >= MIN_MTU_V6 && mtu <= MAX_MTU;
|
||||
} else {
|
||||
if (mtu >= MIN_MTU && mtu <= MAX_MTU) return true;
|
||||
return mtu >= MIN_MTU && mtu <= MAX_MTU;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ public class Network implements Parcelable {
|
||||
|
||||
/**
|
||||
* Specify whether or not Private DNS should be bypassed when attempting
|
||||
* to use {@link getAllByName()}/{@link getByName()} methods on the given
|
||||
* to use {@link #getAllByName(String)}/{@link #getByName(String)} methods on the given
|
||||
* instance for hostname resolution.
|
||||
*
|
||||
* @hide
|
||||
@@ -169,13 +169,6 @@ public class Network implements Parcelable {
|
||||
* A {@code SocketFactory} that produces {@code Socket}'s bound to this network.
|
||||
*/
|
||||
private class NetworkBoundSocketFactory extends SocketFactory {
|
||||
private final int mNetId;
|
||||
|
||||
public NetworkBoundSocketFactory(int netId) {
|
||||
super();
|
||||
mNetId = netId;
|
||||
}
|
||||
|
||||
private Socket connectToHost(String host, int port, SocketAddress localAddress)
|
||||
throws IOException {
|
||||
// Lookup addresses only on this Network.
|
||||
@@ -201,7 +194,8 @@ public class Network implements Parcelable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
|
||||
public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
|
||||
throws IOException {
|
||||
return connectToHost(host, port, new InetSocketAddress(localHost, localPort));
|
||||
}
|
||||
|
||||
@@ -265,7 +259,7 @@ public class Network implements Parcelable {
|
||||
if (mNetworkBoundSocketFactory == null) {
|
||||
synchronized (mLock) {
|
||||
if (mNetworkBoundSocketFactory == null) {
|
||||
mNetworkBoundSocketFactory = new NetworkBoundSocketFactory(netId);
|
||||
mNetworkBoundSocketFactory = new NetworkBoundSocketFactory();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -475,7 +469,7 @@ public class Network implements Parcelable {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Network == false) return false;
|
||||
if (!(obj instanceof Network)) return false;
|
||||
Network other = (Network)obj;
|
||||
return this.netId == other.netId;
|
||||
}
|
||||
|
||||
@@ -155,6 +155,7 @@ import com.android.server.connectivity.NetworkNotificationManager;
|
||||
import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
|
||||
import com.android.server.connectivity.PacManager;
|
||||
import com.android.server.connectivity.PermissionMonitor;
|
||||
import com.android.server.connectivity.ProxyTracker;
|
||||
import com.android.server.connectivity.Tethering;
|
||||
import com.android.server.connectivity.Vpn;
|
||||
import com.android.server.connectivity.tethering.TetheringDependencies;
|
||||
@@ -429,15 +430,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
private int mNetTransitionWakeLockTimeout;
|
||||
private final PowerManager.WakeLock mPendingIntentWakeLock;
|
||||
|
||||
// track the current default http proxy - tell the world if we get a new one (real change)
|
||||
private volatile ProxyInfo mDefaultProxy = null;
|
||||
private final Object mProxyLock = new Object();
|
||||
private boolean mDefaultProxyDisabled = false;
|
||||
|
||||
// track the global proxy.
|
||||
private ProxyInfo mGlobalProxy = null;
|
||||
|
||||
private PacManager mPacManager = null;
|
||||
// A helper object to track the current default HTTP proxy. ConnectivityService needs to tell
|
||||
// the world when it changes.
|
||||
private final ProxyTracker mProxyTracker;
|
||||
|
||||
final private SettingsObserver mSettingsObserver;
|
||||
|
||||
@@ -761,6 +756,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
mPolicyManagerInternal = checkNotNull(
|
||||
LocalServices.getService(NetworkPolicyManagerInternal.class),
|
||||
"missing NetworkPolicyManagerInternal");
|
||||
mProxyTracker = new ProxyTracker(context, mHandler, EVENT_PROXY_HAS_CHANGED);
|
||||
|
||||
mKeyStore = KeyStore.getInstance();
|
||||
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
@@ -871,8 +867,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
final DataConnectionStats dataConnectionStats = new DataConnectionStats(mContext);
|
||||
dataConnectionStats.startMonitoring();
|
||||
|
||||
mPacManager = new PacManager(mContext, mHandler, EVENT_PROXY_HAS_CHANGED);
|
||||
|
||||
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||
|
||||
mKeepaliveTracker = new KeepaliveTracker(mHandler);
|
||||
@@ -1001,7 +995,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
throw new IllegalStateException("No free netIds");
|
||||
}
|
||||
|
||||
private NetworkState getFilteredNetworkState(int networkType, int uid, boolean ignoreBlocked) {
|
||||
private NetworkState getFilteredNetworkState(int networkType, int uid) {
|
||||
if (mLegacyTypeTracker.isTypeSupported(networkType)) {
|
||||
final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
|
||||
final NetworkState state;
|
||||
@@ -1019,7 +1013,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
state = new NetworkState(info, new LinkProperties(), capabilities,
|
||||
null, null, null);
|
||||
}
|
||||
filterNetworkStateForUid(state, uid, ignoreBlocked);
|
||||
filterNetworkStateForUid(state, uid, false);
|
||||
return state;
|
||||
} else {
|
||||
return NetworkState.EMPTY;
|
||||
@@ -1224,7 +1218,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
return state.networkInfo;
|
||||
}
|
||||
}
|
||||
final NetworkState state = getFilteredNetworkState(networkType, uid, false);
|
||||
final NetworkState state = getFilteredNetworkState(networkType, uid);
|
||||
return state.networkInfo;
|
||||
}
|
||||
|
||||
@@ -1259,7 +1253,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
public Network getNetworkForType(int networkType) {
|
||||
enforceAccessPermission();
|
||||
final int uid = Binder.getCallingUid();
|
||||
NetworkState state = getFilteredNetworkState(networkType, uid, false);
|
||||
NetworkState state = getFilteredNetworkState(networkType, uid);
|
||||
if (!isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid, false)) {
|
||||
return state.network;
|
||||
}
|
||||
@@ -3325,22 +3319,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
nai.networkMonitor.forceReevaluation(uid);
|
||||
}
|
||||
|
||||
private ProxyInfo getDefaultProxy() {
|
||||
// this information is already available as a world read/writable jvm property
|
||||
// so this API change wouldn't have a benefit. It also breaks the passing
|
||||
// of proxy info to all the JVMs.
|
||||
// enforceAccessPermission();
|
||||
synchronized (mProxyLock) {
|
||||
ProxyInfo ret = mGlobalProxy;
|
||||
if ((ret == null) && !mDefaultProxyDisabled) ret = mDefaultProxy;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProxyInfo getProxyForNetwork(Network network) {
|
||||
if (network == null) return getDefaultProxy();
|
||||
final ProxyInfo globalProxy = getGlobalProxy();
|
||||
if (network == null) return mProxyTracker.getDefaultProxy();
|
||||
final ProxyInfo globalProxy = mProxyTracker.getGlobalProxy();
|
||||
if (globalProxy != null) return globalProxy;
|
||||
if (!NetworkUtils.queryUserAccess(Binder.getCallingUid(), network.netId)) return null;
|
||||
// Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which
|
||||
@@ -3354,80 +3336,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
// Convert empty ProxyInfo's to null as null-checks are used to determine if proxies are present
|
||||
// (e.g. if mGlobalProxy==null fall back to network-specific proxy, if network-specific
|
||||
// proxy is null then there is no proxy in place).
|
||||
private ProxyInfo canonicalizeProxyInfo(ProxyInfo proxy) {
|
||||
if (proxy != null && TextUtils.isEmpty(proxy.getHost())
|
||||
&& (proxy.getPacFileUrl() == null || Uri.EMPTY.equals(proxy.getPacFileUrl()))) {
|
||||
proxy = null;
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
|
||||
// ProxyInfo equality function with a couple modifications over ProxyInfo.equals() to make it
|
||||
// better for determining if a new proxy broadcast is necessary:
|
||||
// 1. Canonicalize empty ProxyInfos to null so an empty proxy compares equal to null so as to
|
||||
// avoid unnecessary broadcasts.
|
||||
// 2. Make sure all parts of the ProxyInfo's compare true, including the host when a PAC URL
|
||||
// is in place. This is important so legacy PAC resolver (see com.android.proxyhandler)
|
||||
// changes aren't missed. The legacy PAC resolver pretends to be a simple HTTP proxy but
|
||||
// actually uses the PAC to resolve; this results in ProxyInfo's with PAC URL, host and port
|
||||
// all set.
|
||||
private boolean proxyInfoEqual(ProxyInfo a, ProxyInfo b) {
|
||||
a = canonicalizeProxyInfo(a);
|
||||
b = canonicalizeProxyInfo(b);
|
||||
// ProxyInfo.equals() doesn't check hosts when PAC URLs are present, but we need to check
|
||||
// hosts even when PAC URLs are present to account for the legacy PAC resolver.
|
||||
return Objects.equals(a, b) && (a == null || Objects.equals(a.getHost(), b.getHost()));
|
||||
}
|
||||
|
||||
public void setGlobalProxy(ProxyInfo proxyProperties) {
|
||||
@Override
|
||||
public void setGlobalProxy(final ProxyInfo proxyProperties) {
|
||||
enforceConnectivityInternalPermission();
|
||||
|
||||
synchronized (mProxyLock) {
|
||||
if (proxyProperties == mGlobalProxy) return;
|
||||
if (proxyProperties != null && proxyProperties.equals(mGlobalProxy)) return;
|
||||
if (mGlobalProxy != null && mGlobalProxy.equals(proxyProperties)) return;
|
||||
|
||||
String host = "";
|
||||
int port = 0;
|
||||
String exclList = "";
|
||||
String pacFileUrl = "";
|
||||
if (proxyProperties != null && (!TextUtils.isEmpty(proxyProperties.getHost()) ||
|
||||
!Uri.EMPTY.equals(proxyProperties.getPacFileUrl()))) {
|
||||
if (!proxyProperties.isValid()) {
|
||||
if (DBG)
|
||||
log("Invalid proxy properties, ignoring: " + proxyProperties.toString());
|
||||
return;
|
||||
}
|
||||
mGlobalProxy = new ProxyInfo(proxyProperties);
|
||||
host = mGlobalProxy.getHost();
|
||||
port = mGlobalProxy.getPort();
|
||||
exclList = mGlobalProxy.getExclusionListAsString();
|
||||
if (!Uri.EMPTY.equals(proxyProperties.getPacFileUrl())) {
|
||||
pacFileUrl = proxyProperties.getPacFileUrl().toString();
|
||||
}
|
||||
} else {
|
||||
mGlobalProxy = null;
|
||||
}
|
||||
ContentResolver res = mContext.getContentResolver();
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST, host);
|
||||
Settings.Global.putInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, port);
|
||||
Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST,
|
||||
exclList);
|
||||
Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_PAC, pacFileUrl);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
|
||||
if (mGlobalProxy == null) {
|
||||
proxyProperties = mDefaultProxy;
|
||||
}
|
||||
sendProxyBroadcast(proxyProperties);
|
||||
}
|
||||
mProxyTracker.setGlobalProxy(proxyProperties);
|
||||
}
|
||||
|
||||
private void loadGlobalProxy() {
|
||||
@@ -3449,20 +3361,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (mProxyLock) {
|
||||
mGlobalProxy = proxyProperties;
|
||||
synchronized (mProxyTracker.mProxyLock) {
|
||||
mProxyTracker.mGlobalProxy = proxyProperties;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ProxyInfo getGlobalProxy() {
|
||||
// this information is already available as a world read/writable jvm property
|
||||
// so this API change wouldn't have a benefit. It also breaks the passing
|
||||
// of proxy info to all the JVMs.
|
||||
// enforceAccessPermission();
|
||||
synchronized (mProxyLock) {
|
||||
return mGlobalProxy;
|
||||
}
|
||||
return mProxyTracker.getGlobalProxy();
|
||||
}
|
||||
|
||||
private void handleApplyDefaultProxy(ProxyInfo proxy) {
|
||||
@@ -3470,9 +3378,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
&& Uri.EMPTY.equals(proxy.getPacFileUrl())) {
|
||||
proxy = null;
|
||||
}
|
||||
synchronized (mProxyLock) {
|
||||
if (mDefaultProxy != null && mDefaultProxy.equals(proxy)) return;
|
||||
if (mDefaultProxy == proxy) return; // catches repeated nulls
|
||||
synchronized (mProxyTracker.mProxyLock) {
|
||||
if (mProxyTracker.mDefaultProxy != null && mProxyTracker.mDefaultProxy.equals(proxy)) {
|
||||
return;
|
||||
}
|
||||
if (mProxyTracker.mDefaultProxy == proxy) return; // catches repeated nulls
|
||||
if (proxy != null && !proxy.isValid()) {
|
||||
if (DBG) log("Invalid proxy properties, ignoring: " + proxy.toString());
|
||||
return;
|
||||
@@ -3483,18 +3393,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
// global (to get the correct local port), and send a broadcast.
|
||||
// TODO: Switch PacManager to have its own message to send back rather than
|
||||
// reusing EVENT_HAS_CHANGED_PROXY and this call to handleApplyDefaultProxy.
|
||||
if ((mGlobalProxy != null) && (proxy != null)
|
||||
if ((mProxyTracker.mGlobalProxy != null) && (proxy != null)
|
||||
&& (!Uri.EMPTY.equals(proxy.getPacFileUrl()))
|
||||
&& proxy.getPacFileUrl().equals(mGlobalProxy.getPacFileUrl())) {
|
||||
mGlobalProxy = proxy;
|
||||
sendProxyBroadcast(mGlobalProxy);
|
||||
&& proxy.getPacFileUrl().equals(mProxyTracker.mGlobalProxy.getPacFileUrl())) {
|
||||
mProxyTracker.mGlobalProxy = proxy;
|
||||
mProxyTracker.sendProxyBroadcast(mProxyTracker.mGlobalProxy);
|
||||
return;
|
||||
}
|
||||
mDefaultProxy = proxy;
|
||||
mProxyTracker.mDefaultProxy = proxy;
|
||||
|
||||
if (mGlobalProxy != null) return;
|
||||
if (!mDefaultProxyDisabled) {
|
||||
sendProxyBroadcast(proxy);
|
||||
if (mProxyTracker.mGlobalProxy != null) return;
|
||||
if (!mProxyTracker.mDefaultProxyDisabled) {
|
||||
mProxyTracker.sendProxyBroadcast(proxy);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3508,8 +3418,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
ProxyInfo newProxyInfo = newLp == null ? null : newLp.getHttpProxy();
|
||||
ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy();
|
||||
|
||||
if (!proxyInfoEqual(newProxyInfo, oldProxyInfo)) {
|
||||
sendProxyBroadcast(getDefaultProxy());
|
||||
if (!ProxyTracker.proxyInfoEqual(newProxyInfo, oldProxyInfo)) {
|
||||
mProxyTracker.sendProxyBroadcast(mProxyTracker.getDefaultProxy());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3536,22 +3446,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
private void sendProxyBroadcast(ProxyInfo proxy) {
|
||||
if (proxy == null) proxy = new ProxyInfo("", 0, "");
|
||||
if (mPacManager.setCurrentProxyScriptUrl(proxy)) return;
|
||||
if (DBG) log("sending Proxy Broadcast for " + proxy);
|
||||
Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
|
||||
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
|
||||
Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
|
||||
intent.putExtra(Proxy.EXTRA_PROXY_INFO, proxy);
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
|
||||
private static class SettingsObserver extends ContentObserver {
|
||||
final private HashMap<Uri, Integer> mUriEventMap;
|
||||
final private Context mContext;
|
||||
@@ -5570,11 +5464,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
|
||||
if (networkAgent.isVPN()) {
|
||||
// Temporarily disable the default proxy (not global).
|
||||
synchronized (mProxyLock) {
|
||||
if (!mDefaultProxyDisabled) {
|
||||
mDefaultProxyDisabled = true;
|
||||
if (mGlobalProxy == null && mDefaultProxy != null) {
|
||||
sendProxyBroadcast(null);
|
||||
synchronized (mProxyTracker.mProxyLock) {
|
||||
if (!mProxyTracker.mDefaultProxyDisabled) {
|
||||
mProxyTracker.mDefaultProxyDisabled = true;
|
||||
if (mProxyTracker.mGlobalProxy == null
|
||||
&& mProxyTracker.mDefaultProxy != null) {
|
||||
mProxyTracker.sendProxyBroadcast(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5599,11 +5494,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
} else if (state == NetworkInfo.State.DISCONNECTED) {
|
||||
networkAgent.asyncChannel.disconnect();
|
||||
if (networkAgent.isVPN()) {
|
||||
synchronized (mProxyLock) {
|
||||
if (mDefaultProxyDisabled) {
|
||||
mDefaultProxyDisabled = false;
|
||||
if (mGlobalProxy == null && mDefaultProxy != null) {
|
||||
sendProxyBroadcast(mDefaultProxy);
|
||||
synchronized (mProxyTracker.mProxyLock) {
|
||||
if (mProxyTracker.mDefaultProxyDisabled) {
|
||||
mProxyTracker.mDefaultProxyDisabled = false;
|
||||
if (mProxyTracker.mGlobalProxy == null
|
||||
&& mProxyTracker.mDefaultProxy != null) {
|
||||
mProxyTracker.sendProxyBroadcast(mProxyTracker.mDefaultProxy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
/**
|
||||
* Copyright (c) 2018, 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 com.android.server.connectivity;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Proxy;
|
||||
import android.net.ProxyInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A class to handle proxy for ConnectivityService.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class ProxyTracker {
|
||||
private static final String TAG = ProxyTracker.class.getSimpleName();
|
||||
private static final boolean DBG = true;
|
||||
|
||||
@NonNull
|
||||
private final Context mContext;
|
||||
|
||||
// TODO : make this private and import as much managing logic from ConnectivityService as
|
||||
// possible
|
||||
@NonNull
|
||||
public final Object mProxyLock = new Object();
|
||||
@Nullable
|
||||
@GuardedBy("mProxyLock")
|
||||
public ProxyInfo mGlobalProxy = null;
|
||||
@Nullable
|
||||
@GuardedBy("mProxyLock")
|
||||
public volatile ProxyInfo mDefaultProxy = null;
|
||||
@GuardedBy("mProxyLock")
|
||||
public boolean mDefaultProxyDisabled = false;
|
||||
|
||||
@NonNull
|
||||
private final PacManager mPacManager;
|
||||
|
||||
public ProxyTracker(@NonNull final Context context,
|
||||
@NonNull final Handler connectivityServiceInternalHandler, final int pacChangedEvent) {
|
||||
mContext = context;
|
||||
mPacManager = new PacManager(context, connectivityServiceInternalHandler, pacChangedEvent);
|
||||
}
|
||||
|
||||
// Convert empty ProxyInfo's to null as null-checks are used to determine if proxies are present
|
||||
// (e.g. if mGlobalProxy==null fall back to network-specific proxy, if network-specific
|
||||
// proxy is null then there is no proxy in place).
|
||||
@Nullable
|
||||
private static ProxyInfo canonicalizeProxyInfo(@Nullable final ProxyInfo proxy) {
|
||||
if (proxy != null && TextUtils.isEmpty(proxy.getHost())
|
||||
&& (proxy.getPacFileUrl() == null || Uri.EMPTY.equals(proxy.getPacFileUrl()))) {
|
||||
return null;
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
|
||||
// ProxyInfo equality functions with a couple modifications over ProxyInfo.equals() to make it
|
||||
// better for determining if a new proxy broadcast is necessary:
|
||||
// 1. Canonicalize empty ProxyInfos to null so an empty proxy compares equal to null so as to
|
||||
// avoid unnecessary broadcasts.
|
||||
// 2. Make sure all parts of the ProxyInfo's compare true, including the host when a PAC URL
|
||||
// is in place. This is important so legacy PAC resolver (see com.android.proxyhandler)
|
||||
// changes aren't missed. The legacy PAC resolver pretends to be a simple HTTP proxy but
|
||||
// actually uses the PAC to resolve; this results in ProxyInfo's with PAC URL, host and port
|
||||
// all set.
|
||||
public static boolean proxyInfoEqual(@Nullable final ProxyInfo a, @Nullable final ProxyInfo b) {
|
||||
final ProxyInfo pa = canonicalizeProxyInfo(a);
|
||||
final ProxyInfo pb = canonicalizeProxyInfo(b);
|
||||
// ProxyInfo.equals() doesn't check hosts when PAC URLs are present, but we need to check
|
||||
// hosts even when PAC URLs are present to account for the legacy PAC resolver.
|
||||
return Objects.equals(pa, pb) && (pa == null || Objects.equals(pa.getHost(), pb.getHost()));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ProxyInfo getDefaultProxy() {
|
||||
// This information is already available as a world read/writable jvm property.
|
||||
synchronized (mProxyLock) {
|
||||
final ProxyInfo ret = mGlobalProxy;
|
||||
if ((ret == null) && !mDefaultProxyDisabled) return mDefaultProxy;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ProxyInfo getGlobalProxy() {
|
||||
// This information is already available as a world read/writable jvm property.
|
||||
synchronized (mProxyLock) {
|
||||
return mGlobalProxy;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean setCurrentProxyScriptUrl(@NonNull final ProxyInfo proxy) {
|
||||
return mPacManager.setCurrentProxyScriptUrl(proxy);
|
||||
}
|
||||
|
||||
// TODO : make the argument NonNull final
|
||||
public void sendProxyBroadcast(@Nullable ProxyInfo proxy) {
|
||||
if (proxy == null) proxy = new ProxyInfo("", 0, "");
|
||||
if (setCurrentProxyScriptUrl(proxy)) return;
|
||||
if (DBG) Slog.d(TAG, "sending Proxy Broadcast for " + proxy);
|
||||
Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
|
||||
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
|
||||
Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
|
||||
intent.putExtra(Proxy.EXTRA_PROXY_INFO, proxy);
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
|
||||
public void setGlobalProxy(@Nullable ProxyInfo proxyProperties) {
|
||||
synchronized (mProxyLock) {
|
||||
if (proxyProperties == mGlobalProxy) return;
|
||||
if (proxyProperties != null && proxyProperties.equals(mGlobalProxy)) return;
|
||||
if (mGlobalProxy != null && mGlobalProxy.equals(proxyProperties)) return;
|
||||
|
||||
String host = "";
|
||||
int port = 0;
|
||||
String exclList = "";
|
||||
String pacFileUrl = "";
|
||||
if (proxyProperties != null && (!TextUtils.isEmpty(proxyProperties.getHost()) ||
|
||||
!Uri.EMPTY.equals(proxyProperties.getPacFileUrl()))) {
|
||||
if (!proxyProperties.isValid()) {
|
||||
if (DBG) Slog.d(TAG, "Invalid proxy properties, ignoring: " + proxyProperties);
|
||||
return;
|
||||
}
|
||||
mGlobalProxy = new ProxyInfo(proxyProperties);
|
||||
host = mGlobalProxy.getHost();
|
||||
port = mGlobalProxy.getPort();
|
||||
exclList = mGlobalProxy.getExclusionListAsString();
|
||||
if (!Uri.EMPTY.equals(proxyProperties.getPacFileUrl())) {
|
||||
pacFileUrl = proxyProperties.getPacFileUrl().toString();
|
||||
}
|
||||
} else {
|
||||
mGlobalProxy = null;
|
||||
}
|
||||
final ContentResolver res = mContext.getContentResolver();
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST, host);
|
||||
Settings.Global.putInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, port);
|
||||
Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST,
|
||||
exclList);
|
||||
Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_PAC, pacFileUrl);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
|
||||
if (mGlobalProxy == null) {
|
||||
proxyProperties = mDefaultProxy;
|
||||
}
|
||||
sendProxyBroadcast(proxyProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user