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