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.InvocationTargetException; |
| 14 import java.lang.reflect.Method; |
| 15 |
13 import org.chromium.base.CalledByNative; | 16 import org.chromium.base.CalledByNative; |
14 import org.chromium.base.JNINamespace; | 17 import org.chromium.base.JNINamespace; |
15 import org.chromium.base.NativeClassQualifiedName; | 18 import org.chromium.base.NativeClassQualifiedName; |
16 | 19 |
17 // This class partners with native ProxyConfigServiceAndroid to listen for | 20 // This class partners with native ProxyConfigServiceAndroid to listen for |
18 // proxy change notifications from Android. | 21 // proxy change notifications from Android. |
19 @JNINamespace("net") | 22 @JNINamespace("net") |
20 public class ProxyChangeListener { | 23 public class ProxyChangeListener { |
21 private static final String TAG = "ProxyChangeListener"; | 24 private static final String TAG = "ProxyChangeListener"; |
22 private static boolean sEnabled = true; | 25 private static boolean sEnabled = true; |
23 | 26 |
24 private int mNativePtr; | 27 private int mNativePtr; |
25 private Context mContext; | 28 private Context mContext; |
26 private ProxyReceiver mProxyReceiver; | 29 private ProxyReceiver mProxyReceiver; |
27 private Delegate mDelegate; | 30 private Delegate mDelegate; |
28 | 31 |
| 32 private static class ProxyConfig { |
| 33 public ProxyConfig(String host, int port) { |
| 34 mHost = host; |
| 35 mPort = port; |
| 36 } |
| 37 public final String mHost; |
| 38 public final int mPort; |
| 39 }; |
| 40 |
29 public interface Delegate { | 41 public interface Delegate { |
30 public void proxySettingsChanged(); | 42 public void proxySettingsChanged(); |
31 } | 43 } |
32 | 44 |
33 private ProxyChangeListener(Context context) { | 45 private ProxyChangeListener(Context context) { |
34 mContext = context; | 46 mContext = context; |
35 } | 47 } |
36 | 48 |
37 public static void setEnabled(boolean enabled) { | 49 public static void setEnabled(boolean enabled) { |
38 sEnabled = enabled; | 50 sEnabled = enabled; |
(...skipping 23 matching lines...) Expand all Loading... |
62 @CalledByNative | 74 @CalledByNative |
63 public void stop() { | 75 public void stop() { |
64 mNativePtr = 0; | 76 mNativePtr = 0; |
65 unregisterReceiver(); | 77 unregisterReceiver(); |
66 } | 78 } |
67 | 79 |
68 private class ProxyReceiver extends BroadcastReceiver { | 80 private class ProxyReceiver extends BroadcastReceiver { |
69 @Override | 81 @Override |
70 public void onReceive(Context context, Intent intent) { | 82 public void onReceive(Context context, Intent intent) { |
71 if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) { | 83 if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) { |
72 proxySettingsChanged(); | 84 proxySettingsChanged(extractNewProxy(intent)); |
| 85 } |
| 86 } |
| 87 |
| 88 // Extract a ProxyConfig object from the supplied Intent's extra data |
| 89 // bundle. The android.net.ProxyProperties class is not exported from |
| 90 // tne Android SDK, so we have to use reflection to get at it and invoke |
| 91 // methods on it. If we fail, return an empty proxy config (meaning |
| 92 // 'direct'). |
| 93 // TODO(ellyjones): once android.net.ProxyProperties is exported, |
| 94 // rewrite this. |
| 95 private ProxyConfig extractNewProxy(Intent intent) { |
| 96 try { |
| 97 final String CLASS_NAME = "android.net.ProxyProperties"; |
| 98 final String GET_HOST_NAME = "getHost"; |
| 99 final String GET_PORT_NAME = "getPort"; |
| 100 Object props = intent.getExtras().get("proxy"); |
| 101 if (props == null) { |
| 102 return null; |
| 103 } |
| 104 Class cls = Class.forName(CLASS_NAME); |
| 105 Method getHostMethod = cls.getDeclaredMethod(GET_HOST_NAME); |
| 106 Method getPortMethod = cls.getDeclaredMethod(GET_PORT_NAME); |
| 107 |
| 108 String host = (String)getHostMethod.invoke(props); |
| 109 int port = (Integer)getPortMethod.invoke(props); |
| 110 |
| 111 return new ProxyConfig(host, port); |
| 112 } catch (ClassNotFoundException ex) { |
| 113 return null; |
| 114 } catch (NoSuchMethodException ex) { |
| 115 return null; |
| 116 } catch (IllegalAccessException ex) { |
| 117 return null; |
| 118 } catch (InvocationTargetException ex) { |
| 119 return null; |
| 120 } catch (NullPointerException ex) { |
| 121 return null; |
73 } | 122 } |
74 } | 123 } |
75 } | 124 } |
76 | 125 |
77 private void proxySettingsChanged() { | 126 private void proxySettingsChanged(ProxyConfig cfg) { |
78 if (!sEnabled) { | 127 if (!sEnabled) { |
79 return; | 128 return; |
80 } | 129 } |
81 if (mDelegate != null) { | 130 if (mDelegate != null) { |
82 mDelegate.proxySettingsChanged(); | 131 mDelegate.proxySettingsChanged(); |
83 } | 132 } |
84 if (mNativePtr == 0) { | 133 if (mNativePtr == 0) { |
85 return; | 134 return; |
86 } | 135 } |
87 // Note that this code currently runs on a MESSAGE_LOOP_UI thread, but | 136 // 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. | 137 // the C++ code must run the callbacks on the network thread. |
89 nativeProxySettingsChanged(mNativePtr); | 138 if (cfg != null) { |
| 139 nativeProxySettingsChangedTo(mNativePtr, cfg.mHost, cfg.mPort); |
| 140 } else { |
| 141 nativeProxySettingsChanged(mNativePtr); |
| 142 } |
90 } | 143 } |
91 | 144 |
92 private void registerReceiver() { | 145 private void registerReceiver() { |
93 if (mProxyReceiver != null) { | 146 if (mProxyReceiver != null) { |
94 return; | 147 return; |
95 } | 148 } |
96 IntentFilter filter = new IntentFilter(); | 149 IntentFilter filter = new IntentFilter(); |
97 filter.addAction(Proxy.PROXY_CHANGE_ACTION); | 150 filter.addAction(Proxy.PROXY_CHANGE_ACTION); |
98 mProxyReceiver = new ProxyReceiver(); | 151 mProxyReceiver = new ProxyReceiver(); |
99 mContext.getApplicationContext().registerReceiver(mProxyReceiver, filter
); | 152 mContext.getApplicationContext().registerReceiver(mProxyReceiver, filter
); |
100 } | 153 } |
101 | 154 |
102 private void unregisterReceiver() { | 155 private void unregisterReceiver() { |
103 if (mProxyReceiver == null) { | 156 if (mProxyReceiver == null) { |
104 return; | 157 return; |
105 } | 158 } |
106 mContext.unregisterReceiver(mProxyReceiver); | 159 mContext.unregisterReceiver(mProxyReceiver); |
107 mProxyReceiver = null; | 160 mProxyReceiver = null; |
108 } | 161 } |
109 | 162 |
110 /** | 163 /** |
111 * See net/proxy/proxy_config_service_android.cc | 164 * See net/proxy/proxy_config_service_android.cc |
112 */ | 165 */ |
113 @NativeClassQualifiedName("ProxyConfigServiceAndroid::JNIDelegate") | 166 @NativeClassQualifiedName("ProxyConfigServiceAndroid::JNIDelegate") |
| 167 private native void nativeProxySettingsChangedTo(int nativePtr, |
| 168 String host, |
| 169 int port); |
| 170 @NativeClassQualifiedName("ProxyConfigServiceAndroid::JNIDelegate") |
114 private native void nativeProxySettingsChanged(int nativePtr); | 171 private native void nativeProxySettingsChanged(int nativePtr); |
115 } | 172 } |
OLD | NEW |