Commit 7b607a0d authored by Laís Minchillo's avatar Laís Minchillo Committed by Commit Bot

[aw] Get ProxyConfig from Intent if getDefaultProxy() ProxyInfo is invalid

If ConnectivityManager.getDefaultProxy() returns a ProxyInfo with host
"localhost" and port -1 (which is invalid), extract ProxyConfig from the
original Intent in the PROXY_CHANGE_ACTION broadcast.

Bug: 993538
Change-Id: Ic61b5f5527a921596b71e7b0582436827b1739e6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1765848
Commit-Queue: Laís Minchillo <laisminchillo@chromium.org>
Reviewed-by: default avatarPaul Jensen <pauljensen@chromium.org>
Reviewed-by: default avatarRichard Coles <torne@chromium.org>
Auto-Submit: Laís Minchillo <laisminchillo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#702853}
parent b6fd4c53
......@@ -19,7 +19,7 @@ final class ProxyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, final Intent intent) {
if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) {
mListener.updateProxyConfigFromConnectivityManager();
mListener.updateProxyConfigFromConnectivityManager(intent);
}
}
}
......@@ -144,59 +144,59 @@ public class ProxyChangeListener {
runOnThread(() -> proxySettingsChanged(extractNewProxy(intent)));
}
}
}
// Extract a ProxyConfig object from the supplied Intent's extra data
// bundle. The android.net.ProxyProperties class is not exported from
// the Android SDK, so we have to use reflection to get at it and invoke
// methods on it. If we fail, return an empty proxy config (meaning
// use system properties).
private ProxyConfig extractNewProxy(Intent intent) {
Bundle extras = intent.getExtras();
if (extras == null) {
return null;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return ProxyConfig.fromProxyInfo(
(ProxyInfo) extras.get("android.intent.extra.PROXY_INFO"));
}
// Extract a ProxyConfig object from the supplied Intent's extra data
// bundle. The android.net.ProxyProperties class is not exported from
// the Android SDK, so we have to use reflection to get at it and invoke
// methods on it. If we fail, return an empty proxy config (meaning
// use system properties).
private static ProxyConfig extractNewProxy(Intent intent) {
Bundle extras = intent.getExtras();
if (extras == null) {
return null;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return ProxyConfig.fromProxyInfo(
(ProxyInfo) extras.get("android.intent.extra.PROXY_INFO"));
}
try {
final String getHostName = "getHost";
final String getPortName = "getPort";
final String getPacFileUrl = "getPacFileUrl";
final String getExclusionList = "getExclusionList";
final String className = "android.net.ProxyProperties";
try {
final String getHostName = "getHost";
final String getPortName = "getPort";
final String getPacFileUrl = "getPacFileUrl";
final String getExclusionList = "getExclusionList";
final String className = "android.net.ProxyProperties";
Object props = extras.get("proxy");
if (props == null) {
return null;
}
Object props = extras.get("proxy");
if (props == null) {
return null;
}
Class<?> cls = Class.forName(className);
Method getHostMethod = cls.getDeclaredMethod(getHostName);
Method getPortMethod = cls.getDeclaredMethod(getPortName);
Method getExclusionListMethod = cls.getDeclaredMethod(getExclusionList);
Class<?> cls = Class.forName(className);
Method getHostMethod = cls.getDeclaredMethod(getHostName);
Method getPortMethod = cls.getDeclaredMethod(getPortName);
Method getExclusionListMethod = cls.getDeclaredMethod(getExclusionList);
String host = (String) getHostMethod.invoke(props);
int port = (Integer) getPortMethod.invoke(props);
String host = (String) getHostMethod.invoke(props);
int port = (Integer) getPortMethod.invoke(props);
String[] exclusionList;
String s = (String) getExclusionListMethod.invoke(props);
exclusionList = s.split(",");
String[] exclusionList;
String s = (String) getExclusionListMethod.invoke(props);
exclusionList = s.split(",");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Method getPacFileUrlMethod = cls.getDeclaredMethod(getPacFileUrl);
String pacFileUrl = (String) getPacFileUrlMethod.invoke(props);
if (!TextUtils.isEmpty(pacFileUrl)) {
return new ProxyConfig(host, port, pacFileUrl, exclusionList);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Method getPacFileUrlMethod = cls.getDeclaredMethod(getPacFileUrl);
String pacFileUrl = (String) getPacFileUrlMethod.invoke(props);
if (!TextUtils.isEmpty(pacFileUrl)) {
return new ProxyConfig(host, port, pacFileUrl, exclusionList);
}
return new ProxyConfig(host, port, null, exclusionList);
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException
| InvocationTargetException | NullPointerException ex) {
Log.e(TAG, "Using no proxy configuration due to exception:" + ex);
return null;
}
return new ProxyConfig(host, port, null, exclusionList);
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException
| InvocationTargetException | NullPointerException ex) {
Log.e(TAG, "Using no proxy configuration due to exception:" + ex);
return null;
}
}
......@@ -224,16 +224,29 @@ public class ProxyChangeListener {
}
@TargetApi(Build.VERSION_CODES.M)
private ProxyConfig getProxyConfig() {
private ProxyConfig getProxyConfig(Intent intent) {
ConnectivityManager connectivityManager =
(ConnectivityManager) ContextUtils.getApplicationContext().getSystemService(
Context.CONNECTIVITY_SERVICE);
ProxyInfo proxyInfo = connectivityManager.getDefaultProxy();
return proxyInfo == null ? ProxyConfig.DIRECT : ProxyConfig.fromProxyInfo(proxyInfo);
if (proxyInfo == null) {
return ProxyConfig.DIRECT;
}
// TODO(laisminchillo): replace '29' with 'Build.VERSION_CODES.Q'
// when Android Q is finalized for release
if (Build.VERSION.SDK_INT == 29 && proxyInfo.getHost().equals("localhost")
&& proxyInfo.getPort() == -1) {
// There's a bug in Android Q's PAC support. If ConnectivityManager
// returns localhost:-1 then use the intent from the PROXY_CHANGE_ACTION
// broadcast to extract the ProxyConfig. See http://crbug.com/993538.
return extractNewProxy(intent);
}
return ProxyConfig.fromProxyInfo(proxyInfo);
}
/* package */ void updateProxyConfigFromConnectivityManager() {
runOnThread(() -> proxySettingsChanged(getProxyConfig()));
/* package */ void updateProxyConfigFromConnectivityManager(Intent intent) {
runOnThread(() -> proxySettingsChanged(getProxyConfig(intent)));
}
private void registerReceiver() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment