// crash if we can't get it.
IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
try {
- final ProxyInfo proxyInfo = service.getDefaultProxy();
+ final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
Proxy.setHttpProxySystemProperty(proxyInfo);
} catch (RemoteException e) {}
}
*
* @return {@link ProxyInfo} for the current global HTTP proxy or {@code null}
* if no global HTTP proxy is set.
- *
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* @hide
*/
public ProxyInfo getGlobalProxy() {
}
/**
+ * Retrieve the global HTTP proxy, or if no global HTTP proxy is set, a
+ * network-specific HTTP proxy. If {@code network} is null, the
+ * network-specific proxy returned is the proxy of the default active
+ * network.
+ *
+ * @return {@link ProxyInfo} for the current global HTTP proxy, or if no
+ * global HTTP proxy is set, {@code ProxyInfo} for {@code network},
+ * or when {@code network} is {@code null},
+ * the {@code ProxyInfo} for the default active network. Returns
+ * {@code null} when no proxy applies or the caller doesn't have
+ * permission to use {@code network}.
+ * @hide
+ */
+ public ProxyInfo getProxyForNetwork(Network network) {
+ try {
+ return mService.getProxyForNetwork(network);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
* Get the current default HTTP proxy settings. If a global proxy is set it will be returned,
* otherwise if this process is bound to a {@link Network} using
* {@link #bindProcessToNetwork} then that {@code Network}'s proxy is returned, otherwise
* HTTP proxy is active.
*/
public ProxyInfo getDefaultProxy() {
- final Network network = getBoundNetworkForProcess();
- if (network != null) {
- final ProxyInfo globalProxy = getGlobalProxy();
- if (globalProxy != null) return globalProxy;
- final LinkProperties lp = getLinkProperties(network);
- if (lp != null) return lp.getHttpProxy();
- return null;
- }
- try {
- return mService.getDefaultProxy();
- } catch (RemoteException e) {
- return null;
- }
+ return getProxyForNetwork(getBoundNetworkForProcess());
}
/**
void setGlobalProxy(in ProxyInfo p);
- ProxyInfo getDefaultProxy();
+ ProxyInfo getProxyForNetwork(in Network nework);
boolean prepareVpn(String oldPackage, String newPackage);
throw new IOException("No ConnectivityManager yet constructed, please construct one");
}
// TODO: Should this be optimized to avoid fetching the global proxy for every request?
- ProxyInfo proxyInfo = cm.getGlobalProxy();
- if (proxyInfo == null) {
- // TODO: Should this be optimized to avoid fetching LinkProperties for every request?
- final LinkProperties lp = cm.getLinkProperties(this);
- if (lp != null) proxyInfo = lp.getHttpProxy();
- }
+ final ProxyInfo proxyInfo = cm.getProxyForNetwork(this);
java.net.Proxy proxy = null;
if (proxyInfo != null) {
proxy = proxyInfo.makeProxy();
public native static boolean protectFromVpn(int socketfd);
/**
+ * Determine if {@code uid} can access network designated by {@code netId}.
+ * @return {@code true} if {@code uid} can access network, {@code false} otherwise.
+ */
+ public native static boolean queryUserAccess(int uid, int netId);
+
+ /**
* Convert a IPv4 address from an integer to an InetAddress.
* @param hostAddress an int corresponding to the IPv4 address in network byte order
*/
return (jboolean) !protectFromVpn(socket);
}
+static jboolean android_net_utils_queryUserAccess(JNIEnv *env, jobject thiz, jint uid, jint netId)
+{
+ return (jboolean) !queryUserAccess(uid, netId);
+}
+
// ----------------------------------------------------------------------------
{ "bindProcessToNetworkForHostResolution", "(I)Z", (void*) android_net_utils_bindProcessToNetworkForHostResolution },
{ "bindSocketToNetwork", "(II)I", (void*) android_net_utils_bindSocketToNetwork },
{ "protectFromVpn", "(I)Z", (void*)android_net_utils_protectFromVpn },
+ { "queryUserAccess", "(II)Z", (void*)android_net_utils_queryUserAccess },
{ "attachDhcpFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_attachDhcpFilter },
};
actionToken);
}
- public ProxyInfo getDefaultProxy() {
+ private ProxyInfo getDefaultProxy() {
// this information is already available as a world read/writable jvm property
// so this API change wouldn't have a benifit. It also breaks the passing
// of proxy info to all the JVMs.
}
}
+ public ProxyInfo getProxyForNetwork(Network network) {
+ if (network == null) return getDefaultProxy();
+ final ProxyInfo globalProxy = 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
+ // caller may not have.
+ final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
+ if (nai == null) return null;
+ synchronized (nai) {
+ final ProxyInfo proxyInfo = nai.linkProperties.getHttpProxy();
+ if (proxyInfo == null) return null;
+ return new ProxyInfo(proxyInfo);
+ }
+ }
+
// 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).