From 434203a277cd2f237a71508a3d5a7d1602126cd5 Mon Sep 17 00:00:00 2001
From: Robert Greenwalt
This is a protected intent that can only be sent by the system
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String PROXY_CHANGE_ACTION = "android.intent.action.PROXY_CHANGE";
+ /** {@hide} **/
+ public static final String EXTRA_PROXY_INFO = "proxy";
private static ConnectivityManager sConnectivityManager = null;
@@ -88,62 +96,6 @@ public final class Proxy {
EXCLLIST_PATTERN = Pattern.compile(EXCLLIST_REGEXP);
}
- // useful because it holds the processed exclusion list - don't want to reparse it each time
- private static class ProxySpec {
- String[] exclusionList;
- InetSocketAddress address = null;
- public ProxySpec() {
- exclusionList = new String[0];
- };
- }
-
- private static boolean isURLInExclusionList(String url, String[] exclusionList) {
- if (url == null) {
- return false;
- }
- Uri u = Uri.parse(url);
- String urlDomain = u.getHost();
- // If the domain is defined as ".android.com" or "android.com", we wish to match
- // http://android.com as well as http://xxx.android.com , but not
- // http://myandroid.com . This code works out the logic.
- for (String excludedDomain : exclusionList) {
- String dotDomain = "." + excludedDomain;
- if (urlDomain.equals(excludedDomain)) {
- return true;
- }
- if (urlDomain.endsWith(dotDomain)) {
- return true;
- }
- }
- // No match
- return false;
- }
-
- private static String parseHost(String proxySpec) {
- int i = proxySpec.indexOf(':');
- if (i == -1) {
- if (DEBUG) {
- Assert.assertTrue(proxySpec.length() == 0);
- }
- return null;
- }
- return proxySpec.substring(0, i);
- }
-
- private static int parsePort(String proxySpec) {
- int i = proxySpec.indexOf(':');
- if (i == -1) {
- if (DEBUG) {
- Assert.assertTrue(proxySpec.length() == 0);
- }
- return -1;
- }
- if (DEBUG) {
- Assert.assertTrue(i < proxySpec.length());
- }
- return Integer.parseInt(proxySpec.substring(i+1));
- }
-
/**
* Return the proxy object to be used for the URL given as parameter.
* @param ctx A Context used to get the settings for the proxy host.
@@ -154,34 +106,31 @@ public final class Proxy {
* {@hide}
*/
public static final java.net.Proxy getProxy(Context ctx, String url) {
- sProxyInfoLock.readLock().lock();
- java.net.Proxy retval;
- try {
- if (sGlobalProxyChangedObserver == null) {
- registerContentObserversReadLocked(ctx);
- parseGlobalProxyInfoReadLocked(ctx);
+ String host = "";
+ if (url != null) {
+ URI uri = URI.create(url);
+ host = uri.getHost();
+ }
+
+ if (!isLocalHost(host)) {
+ if (sConnectivityManager == null) {
+ sConnectivityManager = (ConnectivityManager)ctx.getSystemService(
+ Context.CONNECTIVITY_SERVICE);
}
- if (sGlobalProxySpec != null) {
- // Proxy defined - Apply exclusion rules
- if (isURLInExclusionList(url, sGlobalProxySpec.exclusionList)) {
- // Return no proxy
- retval = java.net.Proxy.NO_PROXY;
- } else {
- retval =
- new java.net.Proxy(java.net.Proxy.Type.HTTP, sGlobalProxySpec.address);
+ if (sConnectivityManager == null) return java.net.Proxy.NO_PROXY;
+
+ ProxyProperties proxyProperties = sConnectivityManager.getProxy();
+
+ if (proxyProperties != null) {
+ if (!proxyProperties.isExcluded(host)) {
+ return proxyProperties.makeProxy();
}
- } else {
- retval = getDefaultProxy(ctx, url);
}
- } finally {
- sProxyInfoLock.readLock().unlock();
- }
- if ((retval != java.net.Proxy.NO_PROXY) && (isLocalHost(url))) {
- retval = java.net.Proxy.NO_PROXY;
}
- return retval;
+ return java.net.Proxy.NO_PROXY;
}
+
// TODO: deprecate this function
/**
* Return the proxy host set by the user.
@@ -236,35 +185,6 @@ public final class Proxy {
return -1;
}
- // TODO - cache the details for each network so we don't have to fetch and parse
- // on each request
- private static final java.net.Proxy getDefaultProxy(Context context, String url) {
- if (sConnectivityManager == null) {
- sConnectivityManager = (ConnectivityManager)context.getSystemService(
- Context.CONNECTIVITY_SERVICE);
- }
- if (sConnectivityManager == null) return java.net.Proxy.NO_PROXY;
-
- LinkProperties linkProperties = sConnectivityManager.getActiveLinkProperties();
-
- if (linkProperties != null) {
- ProxyProperties proxyProperties = linkProperties.getHttpProxy();
-
- if (proxyProperties != null) {
- String exclusionList = proxyProperties.getExclusionList();
- SocketAddress socketAddr = proxyProperties.getSocketAddress();
- if (socketAddr != null) {
- String[] parsedExclusionArray =
- parsedExclusionArray = parseExclusionList(exclusionList);
- if (!isURLInExclusionList(url, parsedExclusionArray)) {
- return new java.net.Proxy(java.net.Proxy.Type.HTTP, socketAddr);
- }
- }
- }
- }
- return java.net.Proxy.NO_PROXY;
- }
-
// TODO: remove this function / deprecate
/**
* Returns the preferred proxy to be used by clients. This is a wrapper
@@ -291,13 +211,11 @@ public final class Proxy {
}
}
- private static final boolean isLocalHost(String url) {
- if (url == null) {
+ private static final boolean isLocalHost(String host) {
+ if (host == null) {
return false;
}
try {
- final URI uri = URI.create(url);
- final String host = uri.getHost();
if (host != null) {
if (host.equalsIgnoreCase("localhost")) {
return true;
@@ -317,92 +235,6 @@ public final class Proxy {
return false;
}
- private static class SettingsObserver extends ContentObserver {
-
- private Context mContext;
-
- SettingsObserver(Context ctx) {
- super(new Handler(ctx.getMainLooper()));
- mContext = ctx;
- }
-
- @Override
- public void onChange(boolean selfChange) {
- sProxyInfoLock.readLock().lock();
- parseGlobalProxyInfoReadLocked(mContext);
- sProxyInfoLock.readLock().unlock();
- }
- }
-
- private static final void registerContentObserversReadLocked(Context ctx) {
- Uri uriGlobalProxy = Settings.Secure.getUriFor(Settings.Secure.HTTP_PROXY);
- Uri uriGlobalExclList =
- Settings.Secure.getUriFor(Settings.Secure.HTTP_PROXY_EXCLUSION_LIST);
-
- // No lock upgrading (from read to write) allowed
- sProxyInfoLock.readLock().unlock();
- sProxyInfoLock.writeLock().lock();
- try {
- sGlobalProxyChangedObserver = new SettingsObserver(ctx);
- } finally {
- // Downgrading locks (from write to read) is allowed
- sProxyInfoLock.readLock().lock();
- sProxyInfoLock.writeLock().unlock();
- }
- ctx.getContentResolver().registerContentObserver(uriGlobalProxy, false,
- sGlobalProxyChangedObserver);
- ctx.getContentResolver().registerContentObserver(uriGlobalExclList, false,
- sGlobalProxyChangedObserver);
- }
-
- private static final void parseGlobalProxyInfoReadLocked(Context ctx) {
- ContentResolver contentResolver = ctx.getContentResolver();
- String proxyHost = Settings.Secure.getString(
- contentResolver,
- Settings.Secure.HTTP_PROXY);
- if (TextUtils.isEmpty(proxyHost)) {
- // Clear signal
- sProxyInfoLock.readLock().unlock();
- sProxyInfoLock.writeLock().lock();
- sGlobalProxySpec = null;
- sProxyInfoLock.readLock().lock();
- sProxyInfoLock.writeLock().unlock();
- return;
- }
- String exclusionListSpec = Settings.Secure.getString(
- contentResolver,
- Settings.Secure.HTTP_PROXY_EXCLUSION_LIST);
- String host = parseHost(proxyHost);
- int port = parsePort(proxyHost);
- ProxySpec tmpProxySpec = null;
- if (proxyHost != null) {
- tmpProxySpec = new ProxySpec();
- tmpProxySpec.address = new InetSocketAddress(host, port);
- tmpProxySpec.exclusionList = parseExclusionList(exclusionListSpec);
- }
- sProxyInfoLock.readLock().unlock();
- sProxyInfoLock.writeLock().lock();
- sGlobalProxySpec = tmpProxySpec;
- sProxyInfoLock.readLock().lock();
- sProxyInfoLock.writeLock().unlock();
- }
-
- private static String[] parseExclusionList(String exclusionList) {
- String[] processedArray = new String[0];
- if (!TextUtils.isEmpty(exclusionList)) {
- String[] exclusionListArray = exclusionList.toLowerCase().split(",");
- processedArray = new String[exclusionListArray.length];
- for (int i = 0; i < exclusionListArray.length; i++) {
- String entry = exclusionListArray[i].trim();
- if (entry.startsWith(".")) {
- entry = entry.substring(1);
- }
- processedArray[i] = entry;
- }
- }
- return processedArray;
- }
-
/**
* Validate syntax of hostname, port and exclusion list entries
* {@hide}
@@ -480,4 +312,44 @@ public final class Proxy {
new SchemeRegistry(), ProxySelector.getDefault(), context);
return ret;
}
+
+ /** @hide */
+ public static final void setHttpProxySystemProperty(ProxyProperties p) {
+ String host = null;
+ String port = null;
+ String exclList = null;
+ if (p != null) {
+ host = p.getHost();
+ port = Integer.toString(p.getPort());
+ exclList = p.getExclusionList();
+ }
+ setHttpProxySystemProperty(host, port, exclList);
+ }
+
+ /** @hide */
+ public static final void setHttpProxySystemProperty(String host, String port, String exclList) {
+ if (exclList != null) exclList = exclList.replace(",", "|");
+ if (false) Log.d(TAG, "setHttpProxySystemProperty :"+host+":"+port+" - "+exclList);
+ if (host != null) {
+ System.setProperty("http.proxyHost", host);
+ System.setProperty("https.proxyHost", host);
+ } else {
+ System.clearProperty("http.proxyHost");
+ System.clearProperty("https.proxyHost");
+ }
+ if (port != null) {
+ System.setProperty("http.proxyPort", port);
+ System.setProperty("https.proxyPort", port);
+ } else {
+ System.clearProperty("http.proxyPort");
+ System.clearProperty("https.proxyPort");
+ }
+ if (exclList != null) {
+ System.setProperty("http.nonProxyHosts", exclList);
+ System.setProperty("https.nonProxyHosts", exclList);
+ } else {
+ System.clearProperty("http.nonProxyHosts");
+ System.clearProperty("https.nonProxyHosts");
+ }
+ }
}
diff --git a/core/java/android/net/ProxyProperties.aidl b/core/java/android/net/ProxyProperties.aidl
new file mode 100644
index 0000000..02ea15d
--- /dev/null
+++ b/core/java/android/net/ProxyProperties.aidl
@@ -0,0 +1,21 @@
+/*
+**
+** Copyright (C) 2010 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;
+
+parcelable ProxyProperties;
+
diff --git a/core/java/android/net/ProxyProperties.java b/core/java/android/net/ProxyProperties.java
index 5fd0d89..cbe4445 100644
--- a/core/java/android/net/ProxyProperties.java
+++ b/core/java/android/net/ProxyProperties.java
@@ -19,6 +19,8 @@ package android.net;
import android.os.Parcel;
import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.Log;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@@ -30,44 +32,108 @@ import java.net.UnknownHostException;
*/
public class ProxyProperties implements Parcelable {
- private InetSocketAddress mProxy;
+ private String mHost;
+ private int mPort;
private String mExclusionList;
+ private String[] mParsedExclusionList;
- public ProxyProperties() {
+ public ProxyProperties(String host, int port, String exclList) {
+ mHost = host;
+ mPort = port;
+ setExclusionList(exclList);
+ }
+
+ private ProxyProperties(String host, int port, String exclList, String[] parsedExclList) {
+ mHost = host;
+ mPort = port;
+ mExclusionList = exclList;
+ mParsedExclusionList = parsedExclList;
}
// copy constructor instead of clone
public ProxyProperties(ProxyProperties source) {
if (source != null) {
- mProxy = source.getSocketAddress();
- String exclusionList = source.getExclusionList();
- if (exclusionList != null) {
- mExclusionList = new String(exclusionList);
- }
+ mHost = source.getHost();
+ mPort = source.getPort();
+ mExclusionList = source.getExclusionList();
+ mParsedExclusionList = source.mParsedExclusionList;
}
}
public InetSocketAddress getSocketAddress() {
- return mProxy;
+ InetSocketAddress inetSocketAddress = null;
+ try {
+ inetSocketAddress = new InetSocketAddress(mHost, mPort);
+ } catch (IllegalArgumentException e) { }
+ return inetSocketAddress;
}
- public void setSocketAddress(InetSocketAddress proxy) {
- mProxy = proxy;
+ public String getHost() {
+ return mHost;
}
+ public int getPort() {
+ return mPort;
+ }
+
+ // comma separated
public String getExclusionList() {
return mExclusionList;
}
- public void setExclusionList(String exclusionList) {
+ // comma separated
+ private void setExclusionList(String exclusionList) {
mExclusionList = exclusionList;
+ if (mExclusionList == null) {
+ mParsedExclusionList = new String[0];
+ } else {
+ String splitExclusionList[] = exclusionList.toLowerCase().split(",");
+ mParsedExclusionList = new String[splitExclusionList.length * 2];
+ for (int i = 0; i < splitExclusionList.length; i++) {
+ String s = splitExclusionList[i].trim();
+ if (s.startsWith(".")) s = s.substring(1);
+ mParsedExclusionList[i*2] = s;
+ mParsedExclusionList[(i*2)+1] = "." + s;
+ }
+ }
+ }
+
+ public boolean isExcluded(String url) {
+ if (TextUtils.isEmpty(url) || mParsedExclusionList == null ||
+ mParsedExclusionList.length == 0) return false;
+
+ Uri u = Uri.parse(url);
+ String urlDomain = u.getHost();
+ if (urlDomain == null) return false;
+ for (int i = 0; i< mParsedExclusionList.length; i+=2) {
+ if (urlDomain.equals(mParsedExclusionList[i]) ||
+ urlDomain.endsWith(mParsedExclusionList[i+1])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public java.net.Proxy makeProxy() {
+ java.net.Proxy proxy = java.net.Proxy.NO_PROXY;
+ if (mHost != null) {
+ try {
+ InetSocketAddress inetSocketAddress = new InetSocketAddress(mHost, mPort);
+ proxy = new java.net.Proxy(java.net.Proxy.Type.HTTP, inetSocketAddress);
+ } catch (IllegalArgumentException e) {
+ }
+ }
+ return proxy;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
- if (mProxy != null) {
- sb.append(mProxy.toString());
+ if (mHost != null) {
+ sb.append("[");
+ sb.append(mHost);
+ sb.append("] ");
+ sb.append(Integer.toString(mPort));
if (mExclusionList != null) {
sb.append(" xl=").append(mExclusionList);
}
@@ -75,6 +141,20 @@ public class ProxyProperties implements Parcelable {
return sb.toString();
}
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof ProxyProperties)) return false;
+ ProxyProperties p = (ProxyProperties)o;
+ if (mExclusionList != null && !mExclusionList.equals(p.getExclusionList())) return false;
+ if (mHost != null && p.getHost() != null && mHost.equals(p.getHost()) == false) {
+ return false;
+ }
+ if (mHost != null && p.mHost == null) return false;
+ if (mHost == null && p.mHost != null) return false;
+ if (mPort != p.mPort) return false;
+ return true;
+ }
+
/**
* Implement the Parcelable interface
* @hide
@@ -88,27 +168,15 @@ public class ProxyProperties implements Parcelable {
* @hide
*/
public void writeToParcel(Parcel dest, int flags) {
- String host = null;
- if (mProxy != null) {
- try {
- InetAddress addr = mProxy.getAddress();
- if (addr != null) {
- host = addr.getHostAddress();
- } else {
- /* Does not resolve when addr is null */
- host = mProxy.getHostName();
- }
- } catch (Exception e) { }
- }
-
- if (host != null) {
+ if (mHost != null) {
dest.writeByte((byte)1);
- dest.writeString(host);
- dest.writeInt(mProxy.getPort());
+ dest.writeString(mHost);
+ dest.writeInt(mPort);
} else {
dest.writeByte((byte)0);
}
dest.writeString(mExclusionList);
+ dest.writeStringArray(mParsedExclusionList);
}
/**
@@ -118,16 +186,16 @@ public class ProxyProperties implements Parcelable {
public static final Creator