OLD | NEW |
---|---|
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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 import android.net.Uri; | 12 import android.net.Uri; |
13 import android.os.Build; | 13 import android.os.Build; |
14 import android.os.Handler; | |
15 import android.os.Looper; | |
14 import android.text.TextUtils; | 16 import android.text.TextUtils; |
15 import android.util.Log; | 17 import android.util.Log; |
16 | 18 |
19 import org.chromium.base.BuildConfig; | |
17 import org.chromium.base.annotations.CalledByNative; | 20 import org.chromium.base.annotations.CalledByNative; |
18 import org.chromium.base.annotations.JNINamespace; | 21 import org.chromium.base.annotations.JNINamespace; |
19 import org.chromium.base.annotations.NativeClassQualifiedName; | 22 import org.chromium.base.annotations.NativeClassQualifiedName; |
20 | 23 |
21 import java.lang.reflect.InvocationTargetException; | 24 import java.lang.reflect.InvocationTargetException; |
22 import java.lang.reflect.Method; | 25 import java.lang.reflect.Method; |
23 | 26 |
24 /** | 27 /** |
25 * This class partners with native ProxyConfigServiceAndroid to listen for | 28 * This class partners with native ProxyConfigServiceAndroid to listen for |
26 * proxy change notifications from Android. | 29 * proxy change notifications from Android. |
27 */ | 30 */ |
28 @JNINamespace("net") | 31 @JNINamespace("net") |
29 public class ProxyChangeListener { | 32 public class ProxyChangeListener { |
30 private static final String TAG = "ProxyChangeListener"; | 33 private static final String TAG = "ProxyChangeListener"; |
31 private static boolean sEnabled = true; | 34 private static boolean sEnabled = true; |
32 | 35 |
36 private final Context mContext; | |
37 private final Looper mLooper; | |
38 private final Handler mHandler; | |
39 | |
33 private long mNativePtr; | 40 private long mNativePtr; |
34 private Context mContext; | |
35 private ProxyReceiver mProxyReceiver; | 41 private ProxyReceiver mProxyReceiver; |
36 private Delegate mDelegate; | 42 private Delegate mDelegate; |
37 | 43 |
38 private static class ProxyConfig { | 44 private static class ProxyConfig { |
39 public ProxyConfig(String host, int port, String pacUrl, String[] exclus ionList) { | 45 public ProxyConfig(String host, int port, String pacUrl, String[] exclus ionList) { |
40 mHost = host; | 46 mHost = host; |
41 mPort = port; | 47 mPort = port; |
42 mPacUrl = pacUrl; | 48 mPacUrl = pacUrl; |
43 mExclusionList = exclusionList; | 49 mExclusionList = exclusionList; |
44 } | 50 } |
45 public final String mHost; | 51 public final String mHost; |
46 public final int mPort; | 52 public final int mPort; |
47 public final String mPacUrl; | 53 public final String mPacUrl; |
48 public final String[] mExclusionList; | 54 public final String[] mExclusionList; |
49 } | 55 } |
50 | 56 |
51 /** | 57 /** |
52 * The delegate for ProxyChangeListener. Use for testing. | 58 * The delegate for ProxyChangeListener. Use for testing. |
53 */ | 59 */ |
54 public interface Delegate { | 60 public interface Delegate { |
55 public void proxySettingsChanged(); | 61 public void proxySettingsChanged(); |
56 } | 62 } |
57 | 63 |
58 private ProxyChangeListener(Context context) { | 64 private ProxyChangeListener(Context context) { |
59 mContext = context; | 65 mContext = context; |
66 mLooper = Looper.myLooper(); | |
67 mHandler = new Handler(mLooper); | |
60 } | 68 } |
61 | 69 |
62 public static void setEnabled(boolean enabled) { | 70 public static void setEnabled(boolean enabled) { |
63 sEnabled = enabled; | 71 sEnabled = enabled; |
64 } | 72 } |
65 | 73 |
66 public void setDelegateForTesting(Delegate delegate) { | 74 public void setDelegateForTesting(Delegate delegate) { |
67 mDelegate = delegate; | 75 mDelegate = delegate; |
68 } | 76 } |
69 | 77 |
70 @CalledByNative | 78 @CalledByNative |
71 public static ProxyChangeListener create(Context context) { | 79 public static ProxyChangeListener create(Context context) { |
72 return new ProxyChangeListener(context); | 80 return new ProxyChangeListener(context); |
73 } | 81 } |
74 | 82 |
75 @CalledByNative | 83 @CalledByNative |
76 public static String getProperty(String property) { | 84 public static String getProperty(String property) { |
77 return System.getProperty(property); | 85 return System.getProperty(property); |
78 } | 86 } |
79 | 87 |
80 @CalledByNative | 88 @CalledByNative |
81 public void start(long nativePtr) { | 89 public void start(long nativePtr) { |
90 assertOnThread(); | |
82 assert mNativePtr == 0; | 91 assert mNativePtr == 0; |
83 mNativePtr = nativePtr; | 92 mNativePtr = nativePtr; |
84 registerReceiver(); | 93 registerReceiver(); |
85 } | 94 } |
86 | 95 |
87 @CalledByNative | 96 @CalledByNative |
88 public void stop() { | 97 public void stop() { |
98 assertOnThread(); | |
89 mNativePtr = 0; | 99 mNativePtr = 0; |
90 unregisterReceiver(); | 100 unregisterReceiver(); |
91 } | 101 } |
92 | 102 |
93 private class ProxyReceiver extends BroadcastReceiver { | 103 private class ProxyReceiver extends BroadcastReceiver { |
94 @Override | 104 @Override |
95 public void onReceive(Context context, Intent intent) { | 105 public void onReceive(Context context, final Intent intent) { |
96 if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) { | 106 if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) { |
97 proxySettingsChanged(extractNewProxy(intent)); | 107 runOnThread(new Runnable() { |
108 @Override | |
109 public void run() { | |
110 proxySettingsChanged(ProxyReceiver.this, extractNewProxy (intent)); | |
111 } | |
112 }); | |
98 } | 113 } |
99 } | 114 } |
100 | 115 |
101 // Extract a ProxyConfig object from the supplied Intent's extra data | 116 // Extract a ProxyConfig object from the supplied Intent's extra data |
102 // bundle. The android.net.ProxyProperties class is not exported from | 117 // bundle. The android.net.ProxyProperties class is not exported from |
103 // the Android SDK, so we have to use reflection to get at it and invoke | 118 // the Android SDK, so we have to use reflection to get at it and invoke |
104 // methods on it. If we fail, return an empty proxy config (meaning | 119 // methods on it. If we fail, return an empty proxy config (meaning |
105 // 'direct'). | 120 // 'direct'). |
106 // TODO(sgurun): once android.net.ProxyInfo is public, rewrite this. | 121 // TODO(sgurun): once android.net.ProxyInfo is public, rewrite this. |
107 private ProxyConfig extractNewProxy(Intent intent) { | 122 private ProxyConfig extractNewProxy(Intent intent) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
168 } catch (InvocationTargetException ex) { | 183 } catch (InvocationTargetException ex) { |
169 Log.e(TAG, "Using no proxy configuration due to exception:" + ex ); | 184 Log.e(TAG, "Using no proxy configuration due to exception:" + ex ); |
170 return null; | 185 return null; |
171 } catch (NullPointerException ex) { | 186 } catch (NullPointerException ex) { |
172 Log.e(TAG, "Using no proxy configuration due to exception:" + ex ); | 187 Log.e(TAG, "Using no proxy configuration due to exception:" + ex ); |
173 return null; | 188 return null; |
174 } | 189 } |
175 } | 190 } |
176 } | 191 } |
177 | 192 |
178 private void proxySettingsChanged(ProxyConfig cfg) { | 193 private void proxySettingsChanged(ProxyReceiver proxyReceiver, ProxyConfig c fg) { |
179 if (!sEnabled) { | 194 if (!sEnabled || proxyReceiver != mProxyReceiver) { |
xunjieli
2017/04/13 18:44:54
Same here. Maybe add a comment on we need this ext
pauljensen
2017/05/01 15:35:53
Done.
| |
180 return; | 195 return; |
181 } | 196 } |
182 if (mDelegate != null) { | 197 if (mDelegate != null) { |
183 mDelegate.proxySettingsChanged(); | 198 mDelegate.proxySettingsChanged(); |
184 } | 199 } |
185 if (mNativePtr == 0) { | 200 if (mNativePtr == 0) { |
186 return; | 201 return; |
187 } | 202 } |
188 // Note that this code currently runs on a MESSAGE_LOOP_UI thread, but | 203 // Note that this code currently runs on a MESSAGE_LOOP_UI thread, but |
189 // the C++ code must run the callbacks on the network thread. | 204 // the C++ code must run the callbacks on the network thread. |
(...skipping 16 matching lines...) Expand all Loading... | |
206 } | 221 } |
207 | 222 |
208 private void unregisterReceiver() { | 223 private void unregisterReceiver() { |
209 if (mProxyReceiver == null) { | 224 if (mProxyReceiver == null) { |
210 return; | 225 return; |
211 } | 226 } |
212 mContext.unregisterReceiver(mProxyReceiver); | 227 mContext.unregisterReceiver(mProxyReceiver); |
213 mProxyReceiver = null; | 228 mProxyReceiver = null; |
214 } | 229 } |
215 | 230 |
231 private boolean onThread() { | |
232 return mLooper == Looper.myLooper(); | |
233 } | |
234 | |
235 private void assertOnThread() { | |
236 if (BuildConfig.DCHECK_IS_ON && !onThread()) { | |
237 throw new IllegalStateException( | |
238 "Must be called on NetworkChangeNotifierAutoDetect thread.") ; | |
xunjieli
2017/04/13 18:44:54
nit: s/NetworkChangeNotifierAutoDetect/ProxyChange
pauljensen
2017/05/01 15:35:53
Done.
| |
239 } | |
240 } | |
241 | |
242 private void runOnThread(Runnable r) { | |
243 if (onThread()) { | |
244 r.run(); | |
245 } else { | |
246 mHandler.post(r); | |
247 } | |
248 } | |
249 | |
216 /** | 250 /** |
217 * See net/proxy/proxy_config_service_android.cc | 251 * See net/proxy/proxy_config_service_android.cc |
218 */ | 252 */ |
219 @NativeClassQualifiedName("ProxyConfigServiceAndroid::JNIDelegate") | 253 @NativeClassQualifiedName("ProxyConfigServiceAndroid::JNIDelegate") |
220 private native void nativeProxySettingsChangedTo(long nativePtr, | 254 private native void nativeProxySettingsChangedTo(long nativePtr, |
221 String host, | 255 String host, |
222 int port, | 256 int port, |
223 String pacUrl, | 257 String pacUrl, |
224 String[] exclusionList); | 258 String[] exclusionList); |
225 @NativeClassQualifiedName("ProxyConfigServiceAndroid::JNIDelegate") | 259 @NativeClassQualifiedName("ProxyConfigServiceAndroid::JNIDelegate") |
226 private native void nativeProxySettingsChanged(long nativePtr); | 260 private native void nativeProxySettingsChanged(long nativePtr); |
227 } | 261 } |
OLD | NEW |