Chromium Code Reviews| 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 |