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 { ...@@ -19,7 +19,7 @@ final class ProxyBroadcastReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, final Intent intent) { public void onReceive(Context context, final Intent intent) {
if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) { if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) {
mListener.updateProxyConfigFromConnectivityManager(); mListener.updateProxyConfigFromConnectivityManager(intent);
} }
} }
} }
...@@ -144,59 +144,59 @@ public class ProxyChangeListener { ...@@ -144,59 +144,59 @@ public class ProxyChangeListener {
runOnThread(() -> proxySettingsChanged(extractNewProxy(intent))); runOnThread(() -> proxySettingsChanged(extractNewProxy(intent)));
} }
} }
}
// Extract a ProxyConfig object from the supplied Intent's extra data // Extract a ProxyConfig object from the supplied Intent's extra data
// bundle. The android.net.ProxyProperties class is not exported from // 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 // 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 // methods on it. If we fail, return an empty proxy config (meaning
// use system properties). // use system properties).
private ProxyConfig extractNewProxy(Intent intent) { private static ProxyConfig extractNewProxy(Intent intent) {
Bundle extras = intent.getExtras(); Bundle extras = intent.getExtras();
if (extras == null) { if (extras == null) {
return null; return null;
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return ProxyConfig.fromProxyInfo( return ProxyConfig.fromProxyInfo(
(ProxyInfo) extras.get("android.intent.extra.PROXY_INFO")); (ProxyInfo) extras.get("android.intent.extra.PROXY_INFO"));
} }
try { try {
final String getHostName = "getHost"; final String getHostName = "getHost";
final String getPortName = "getPort"; final String getPortName = "getPort";
final String getPacFileUrl = "getPacFileUrl"; final String getPacFileUrl = "getPacFileUrl";
final String getExclusionList = "getExclusionList"; final String getExclusionList = "getExclusionList";
final String className = "android.net.ProxyProperties"; final String className = "android.net.ProxyProperties";
Object props = extras.get("proxy"); Object props = extras.get("proxy");
if (props == null) { if (props == null) {
return null; return null;
} }
Class<?> cls = Class.forName(className); Class<?> cls = Class.forName(className);
Method getHostMethod = cls.getDeclaredMethod(getHostName); Method getHostMethod = cls.getDeclaredMethod(getHostName);
Method getPortMethod = cls.getDeclaredMethod(getPortName); Method getPortMethod = cls.getDeclaredMethod(getPortName);
Method getExclusionListMethod = cls.getDeclaredMethod(getExclusionList); Method getExclusionListMethod = cls.getDeclaredMethod(getExclusionList);
String host = (String) getHostMethod.invoke(props); String host = (String) getHostMethod.invoke(props);
int port = (Integer) getPortMethod.invoke(props); int port = (Integer) getPortMethod.invoke(props);
String[] exclusionList; String[] exclusionList;
String s = (String) getExclusionListMethod.invoke(props); String s = (String) getExclusionListMethod.invoke(props);
exclusionList = s.split(","); exclusionList = s.split(",");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Method getPacFileUrlMethod = cls.getDeclaredMethod(getPacFileUrl); Method getPacFileUrlMethod = cls.getDeclaredMethod(getPacFileUrl);
String pacFileUrl = (String) getPacFileUrlMethod.invoke(props); String pacFileUrl = (String) getPacFileUrlMethod.invoke(props);
if (!TextUtils.isEmpty(pacFileUrl)) { if (!TextUtils.isEmpty(pacFileUrl)) {
return new ProxyConfig(host, port, pacFileUrl, exclusionList); 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 { ...@@ -224,16 +224,29 @@ public class ProxyChangeListener {
} }
@TargetApi(Build.VERSION_CODES.M) @TargetApi(Build.VERSION_CODES.M)
private ProxyConfig getProxyConfig() { private ProxyConfig getProxyConfig(Intent intent) {
ConnectivityManager connectivityManager = ConnectivityManager connectivityManager =
(ConnectivityManager) ContextUtils.getApplicationContext().getSystemService( (ConnectivityManager) ContextUtils.getApplicationContext().getSystemService(
Context.CONNECTIVITY_SERVICE); Context.CONNECTIVITY_SERVICE);
ProxyInfo proxyInfo = connectivityManager.getDefaultProxy(); 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() { /* package */ void updateProxyConfigFromConnectivityManager(Intent intent) {
runOnThread(() -> proxySettingsChanged(getProxyConfig())); runOnThread(() -> proxySettingsChanged(getProxyConfig(intent)));
} }
private void registerReceiver() { 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