Index: net/android/java/src/org/chromium/net/ProxyChangeListener.java |
diff --git a/net/android/java/src/org/chromium/net/ProxyChangeListener.java b/net/android/java/src/org/chromium/net/ProxyChangeListener.java |
index 9c59bcccf6df36c4ed2032a3d9b517656a89fb3d..ce9aabb5637a7e788833cd12367eb479d95f1763 100644 |
--- a/net/android/java/src/org/chromium/net/ProxyChangeListener.java |
+++ b/net/android/java/src/org/chromium/net/ProxyChangeListener.java |
@@ -10,6 +10,9 @@ import android.content.Intent; |
import android.content.IntentFilter; |
import android.net.Proxy; |
+import java.lang.reflect.InvocationTargetException; |
+import java.lang.reflect.Method; |
+ |
import org.chromium.base.CalledByNative; |
import org.chromium.base.JNINamespace; |
import org.chromium.base.NativeClassQualifiedName; |
@@ -26,6 +29,15 @@ public class ProxyChangeListener { |
private ProxyReceiver mProxyReceiver; |
private Delegate mDelegate; |
+ private static class ProxyConfig { |
+ public ProxyConfig(String host, int port) { |
+ mHost = host; |
+ mPort = port; |
+ } |
+ public final String mHost; |
+ public final int mPort; |
+ }; |
+ |
public interface Delegate { |
public void proxySettingsChanged(); |
} |
@@ -69,12 +81,49 @@ public class ProxyChangeListener { |
@Override |
public void onReceive(Context context, Intent intent) { |
if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) { |
- proxySettingsChanged(); |
+ proxySettingsChanged(extractNewProxy(intent)); |
+ } |
+ } |
+ |
+ // Extract a ProxyConfig object from the supplied Intent's extra data |
+ // bundle. The android.net.ProxyProperties class is not exported from |
+ // tne 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 |
+ // 'direct'). |
+ // TODO(ellyjones): once android.net.ProxyProperties is exported, |
+ // rewrite this. |
+ private ProxyConfig extractNewProxy(Intent intent) { |
+ try { |
+ final String CLASS_NAME = "android.net.ProxyProperties"; |
+ final String GET_HOST_NAME = "getHost"; |
+ final String GET_PORT_NAME = "getPort"; |
+ Object props = intent.getExtras().get("proxy"); |
+ if (props == null) { |
+ return null; |
+ } |
+ Class cls = Class.forName(CLASS_NAME); |
+ Method getHostMethod = cls.getDeclaredMethod(GET_HOST_NAME); |
+ Method getPortMethod = cls.getDeclaredMethod(GET_PORT_NAME); |
+ |
+ String host = (String)getHostMethod.invoke(props); |
+ int port = (Integer)getPortMethod.invoke(props); |
+ |
+ return new ProxyConfig(host, port); |
+ } catch (ClassNotFoundException ex) { |
+ return null; |
+ } catch (NoSuchMethodException ex) { |
+ return null; |
+ } catch (IllegalAccessException ex) { |
+ return null; |
+ } catch (InvocationTargetException ex) { |
+ return null; |
+ } catch (NullPointerException ex) { |
+ return null; |
} |
} |
} |
- private void proxySettingsChanged() { |
+ private void proxySettingsChanged(ProxyConfig cfg) { |
if (!sEnabled) { |
return; |
} |
@@ -86,7 +135,11 @@ public class ProxyChangeListener { |
} |
// Note that this code currently runs on a MESSAGE_LOOP_UI thread, but |
// the C++ code must run the callbacks on the network thread. |
- nativeProxySettingsChanged(mNativePtr); |
+ if (cfg != null) { |
+ nativeProxySettingsChangedTo(mNativePtr, cfg.mHost, cfg.mPort); |
+ } else { |
+ nativeProxySettingsChanged(mNativePtr); |
+ } |
} |
private void registerReceiver() { |
@@ -111,5 +164,9 @@ public class ProxyChangeListener { |
* See net/proxy/proxy_config_service_android.cc |
*/ |
@NativeClassQualifiedName("ProxyConfigServiceAndroid::JNIDelegate") |
+ private native void nativeProxySettingsChangedTo(int nativePtr, |
+ String host, |
+ int port); |
+ @NativeClassQualifiedName("ProxyConfigServiceAndroid::JNIDelegate") |
private native void nativeProxySettingsChanged(int nativePtr); |
} |