OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.net; | 5 package org.chromium.net; |
6 | 6 |
7 import android.content.BroadcastReceiver; | 7 import android.content.BroadcastReceiver; |
8 import android.content.Context; | 8 import android.content.Context; |
9 import android.content.Intent; | 9 import android.content.Intent; |
10 import android.content.IntentFilter; | 10 import android.content.IntentFilter; |
11 import android.net.Proxy; | 11 import android.net.Proxy; |
12 | 12 |
13 import java.lang.reflect.Method; | |
14 | |
13 import org.chromium.base.CalledByNative; | 15 import org.chromium.base.CalledByNative; |
14 import org.chromium.base.JNINamespace; | 16 import org.chromium.base.JNINamespace; |
15 import org.chromium.base.NativeClassQualifiedName; | 17 import org.chromium.base.NativeClassQualifiedName; |
16 | 18 |
17 // This class partners with native ProxyConfigServiceAndroid to listen for | 19 // This class partners with native ProxyConfigServiceAndroid to listen for |
18 // proxy change notifications from Android. | 20 // proxy change notifications from Android. |
19 @JNINamespace("net") | 21 @JNINamespace("net") |
20 public class ProxyChangeListener { | 22 public class ProxyChangeListener { |
21 private static final String TAG = "ProxyChangeListener"; | 23 private static final String TAG = "ProxyChangeListener"; |
22 private static boolean sEnabled = true; | 24 private static boolean sEnabled = true; |
23 | 25 |
24 private int mNativePtr; | 26 private int mNativePtr; |
25 private Context mContext; | 27 private Context mContext; |
26 private ProxyReceiver mProxyReceiver; | 28 private ProxyReceiver mProxyReceiver; |
27 private Delegate mDelegate; | 29 private Delegate mDelegate; |
28 | 30 |
31 private static class ProxyConfig { | |
32 public ProxyConfig(String host, int port) { | |
33 mHost = host; | |
34 mPort = port; | |
35 } | |
36 public final String mHost; | |
37 public final int mPort; | |
38 }; | |
39 | |
29 public interface Delegate { | 40 public interface Delegate { |
30 public void proxySettingsChanged(); | 41 public void proxySettingsChanged(); |
31 } | 42 } |
32 | 43 |
33 private ProxyChangeListener(Context context) { | 44 private ProxyChangeListener(Context context) { |
34 mContext = context; | 45 mContext = context; |
35 } | 46 } |
36 | 47 |
37 public static void setEnabled(boolean enabled) { | 48 public static void setEnabled(boolean enabled) { |
38 sEnabled = enabled; | 49 sEnabled = enabled; |
(...skipping 23 matching lines...) Expand all Loading... | |
62 @CalledByNative | 73 @CalledByNative |
63 public void stop() { | 74 public void stop() { |
64 mNativePtr = 0; | 75 mNativePtr = 0; |
65 unregisterReceiver(); | 76 unregisterReceiver(); |
66 } | 77 } |
67 | 78 |
68 private class ProxyReceiver extends BroadcastReceiver { | 79 private class ProxyReceiver extends BroadcastReceiver { |
69 @Override | 80 @Override |
70 public void onReceive(Context context, Intent intent) { | 81 public void onReceive(Context context, Intent intent) { |
71 if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) { | 82 if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) { |
72 proxySettingsChanged(); | 83 ProxyConfig cfg = extractNewProxy(intent); |
cbentzel
2013/10/15 18:59:42
Do older versions of Android set a "proxy" object
Elly Fong-Jones
2013/10/15 19:50:42
All versions ICS and later do.
| |
84 if (cfg != null) { | |
85 proxySettingsChanged(cfg); | |
86 } | |
87 } | |
88 } | |
89 | |
90 // Extract a ProxyConfig object from the supplied Intent's extra data | |
91 // bundle. The android.net.ProxyProperties class is not exported from | |
92 // tne Android SDK, so we have to use reflection to get at it and invoke | |
93 // methods on it. | |
94 // TODO(ellyjones): once android.net.ProxyProperties is exported, | |
95 // rewrite this. | |
96 private ProxyConfig extractNewProxy(Intent intent) { | |
cbentzel
2013/10/15 18:59:42
How hard would it be to test this?
Elly Fong-Jones
2013/10/15 19:50:42
Not difficult per se, just ugly. It would basicall
| |
97 try { | |
98 final String CLASS_NAME = "android.net.ProxyProperties"; | |
99 final String GET_HOST_NAME = "getHost"; | |
100 final String GET_PORT_NAME = "getPort"; | |
101 Object props = intent.getExtras().get("proxy"); | |
102 if (props == null) { | |
103 return null; | |
104 } | |
105 Class cls = Class.forName(CLASS_NAME); | |
106 Method getHostMethod = cls.getDeclaredMethod(GET_HOST_NAME); | |
107 Method getPortMethod = cls.getDeclaredMethod(GET_PORT_NAME); | |
108 | |
109 String host = (String)getHostMethod.invoke(props); | |
cbentzel
2013/10/15 18:59:42
Stupid java question: what happens if the getHost
Elly Fong-Jones
2013/10/15 19:50:42
I don't know. pliard?
Philippe
2013/10/15 20:23:37
This would indeed throw an InvalidCastException (t
| |
110 int port = (Integer)getPortMethod.invoke(props); | |
111 | |
112 return new ProxyConfig(host, port); | |
113 } catch (Exception ex) { | |
114 return null; | |
73 } | 115 } |
74 } | 116 } |
75 } | 117 } |
76 | 118 |
77 private void proxySettingsChanged() { | 119 private void proxySettingsChanged(ProxyConfig cfg) { |
78 if (!sEnabled) { | 120 if (!sEnabled) { |
79 return; | 121 return; |
80 } | 122 } |
81 if (mDelegate != null) { | 123 if (mDelegate != null) { |
82 mDelegate.proxySettingsChanged(); | 124 mDelegate.proxySettingsChanged(); |
83 } | 125 } |
84 if (mNativePtr == 0) { | 126 if (mNativePtr == 0) { |
85 return; | 127 return; |
86 } | 128 } |
87 // Note that this code currently runs on a MESSAGE_LOOP_UI thread, but | 129 // Note that this code currently runs on a MESSAGE_LOOP_UI thread, but |
88 // the C++ code must run the callbacks on the network thread. | 130 // the C++ code must run the callbacks on the network thread. |
89 nativeProxySettingsChanged(mNativePtr); | 131 nativeProxySettingsChanged(mNativePtr, cfg.mHost, cfg.mPort); |
90 } | 132 } |
91 | 133 |
92 private void registerReceiver() { | 134 private void registerReceiver() { |
93 if (mProxyReceiver != null) { | 135 if (mProxyReceiver != null) { |
94 return; | 136 return; |
95 } | 137 } |
96 IntentFilter filter = new IntentFilter(); | 138 IntentFilter filter = new IntentFilter(); |
97 filter.addAction(Proxy.PROXY_CHANGE_ACTION); | 139 filter.addAction(Proxy.PROXY_CHANGE_ACTION); |
98 mProxyReceiver = new ProxyReceiver(); | 140 mProxyReceiver = new ProxyReceiver(); |
99 mContext.getApplicationContext().registerReceiver(mProxyReceiver, filter ); | 141 mContext.getApplicationContext().registerReceiver(mProxyReceiver, filter ); |
100 } | 142 } |
101 | 143 |
102 private void unregisterReceiver() { | 144 private void unregisterReceiver() { |
103 if (mProxyReceiver == null) { | 145 if (mProxyReceiver == null) { |
104 return; | 146 return; |
105 } | 147 } |
106 mContext.unregisterReceiver(mProxyReceiver); | 148 mContext.unregisterReceiver(mProxyReceiver); |
107 mProxyReceiver = null; | 149 mProxyReceiver = null; |
108 } | 150 } |
109 | 151 |
110 /** | 152 /** |
111 * See net/proxy/proxy_config_service_android.cc | 153 * See net/proxy/proxy_config_service_android.cc |
112 */ | 154 */ |
113 @NativeClassQualifiedName("ProxyConfigServiceAndroid::JNIDelegate") | 155 @NativeClassQualifiedName("ProxyConfigServiceAndroid::JNIDelegate") |
114 private native void nativeProxySettingsChanged(int nativePtr); | 156 private native void nativeProxySettingsChanged(int nativePtr, |
157 String host, | |
158 int port); | |
115 } | 159 } |
OLD | NEW |