Query HTTP proxy for network via a new API to avoid permissions exceptions
Add @hidden ConnectivityManager.getProxyForNetwork() API. Bug:20470604 Change-Id: I6a9bc4afc8273bc43b14cdeccfedbbf3ff66be40
This commit is contained in:
@@ -1904,9 +1904,6 @@ public class ConnectivityManager {
|
|||||||
*
|
*
|
||||||
* @return {@link ProxyInfo} for the current global HTTP proxy or {@code null}
|
* @return {@link ProxyInfo} for the current global HTTP proxy or {@code null}
|
||||||
* if no global HTTP proxy is set.
|
* 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
|
* @hide
|
||||||
*/
|
*/
|
||||||
public ProxyInfo getGlobalProxy() {
|
public ProxyInfo getGlobalProxy() {
|
||||||
@@ -1917,6 +1914,28 @@ public class ConnectivityManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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,
|
* 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
|
* otherwise if this process is bound to a {@link Network} using
|
||||||
@@ -1927,19 +1946,7 @@ public class ConnectivityManager {
|
|||||||
* HTTP proxy is active.
|
* HTTP proxy is active.
|
||||||
*/
|
*/
|
||||||
public ProxyInfo getDefaultProxy() {
|
public ProxyInfo getDefaultProxy() {
|
||||||
final Network network = getBoundNetworkForProcess();
|
return getProxyForNetwork(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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ interface IConnectivityManager
|
|||||||
|
|
||||||
void setGlobalProxy(in ProxyInfo p);
|
void setGlobalProxy(in ProxyInfo p);
|
||||||
|
|
||||||
ProxyInfo getDefaultProxy();
|
ProxyInfo getProxyForNetwork(in Network nework);
|
||||||
|
|
||||||
boolean prepareVpn(String oldPackage, String newPackage);
|
boolean prepareVpn(String oldPackage, String newPackage);
|
||||||
|
|
||||||
|
|||||||
@@ -247,12 +247,7 @@ public class Network implements Parcelable {
|
|||||||
throw new IOException("No ConnectivityManager yet constructed, please construct one");
|
throw new IOException("No ConnectivityManager yet constructed, please construct one");
|
||||||
}
|
}
|
||||||
// TODO: Should this be optimized to avoid fetching the global proxy for every request?
|
// TODO: Should this be optimized to avoid fetching the global proxy for every request?
|
||||||
ProxyInfo proxyInfo = cm.getGlobalProxy();
|
final ProxyInfo proxyInfo = cm.getProxyForNetwork(this);
|
||||||
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();
|
|
||||||
}
|
|
||||||
java.net.Proxy proxy = null;
|
java.net.Proxy proxy = null;
|
||||||
if (proxyInfo != null) {
|
if (proxyInfo != null) {
|
||||||
proxy = proxyInfo.makeProxy();
|
proxy = proxyInfo.makeProxy();
|
||||||
|
|||||||
@@ -193,6 +193,12 @@ public class NetworkUtils {
|
|||||||
*/
|
*/
|
||||||
public native static boolean protectFromVpn(int socketfd);
|
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.
|
* Convert a IPv4 address from an integer to an InetAddress.
|
||||||
* @param hostAddress an int corresponding to the IPv4 address in network byte order
|
* @param hostAddress an int corresponding to the IPv4 address in network byte order
|
||||||
|
|||||||
@@ -291,6 +291,11 @@ static jboolean android_net_utils_protectFromVpn(JNIEnv *env, jobject thiz, jint
|
|||||||
return (jboolean) !protectFromVpn(socket);
|
return (jboolean) !protectFromVpn(socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static jboolean android_net_utils_queryUserAccess(JNIEnv *env, jobject thiz, jint uid, jint netId)
|
||||||
|
{
|
||||||
|
return (jboolean) !queryUserAccess(uid, netId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -311,6 +316,7 @@ static JNINativeMethod gNetworkUtilMethods[] = {
|
|||||||
{ "bindProcessToNetworkForHostResolution", "(I)Z", (void*) android_net_utils_bindProcessToNetworkForHostResolution },
|
{ "bindProcessToNetworkForHostResolution", "(I)Z", (void*) android_net_utils_bindProcessToNetworkForHostResolution },
|
||||||
{ "bindSocketToNetwork", "(II)I", (void*) android_net_utils_bindSocketToNetwork },
|
{ "bindSocketToNetwork", "(II)I", (void*) android_net_utils_bindSocketToNetwork },
|
||||||
{ "protectFromVpn", "(I)Z", (void*)android_net_utils_protectFromVpn },
|
{ "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 },
|
{ "attachDhcpFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_attachDhcpFilter },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2626,7 +2626,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
actionToken);
|
actionToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProxyInfo getDefaultProxy() {
|
private ProxyInfo getDefaultProxy() {
|
||||||
// this information is already available as a world read/writable jvm property
|
// 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
|
// so this API change wouldn't have a benifit. It also breaks the passing
|
||||||
// of proxy info to all the JVMs.
|
// of proxy info to all the JVMs.
|
||||||
@@ -2638,6 +2638,22 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// 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
|
// (e.g. if mGlobalProxy==null fall back to network-specific proxy, if network-specific
|
||||||
// proxy is null then there is no proxy in place).
|
// proxy is null then there is no proxy in place).
|
||||||
|
|||||||
Reference in New Issue
Block a user