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 |
3 | // found in the LICENSE file. |
4 | |
5 | package org.chromium.net; |
6 | |
7 | import android.content.BroadcastReceiver; |
8 | import android.content.Context; |
9 | import android.content.Intent; |
10 | import android.content.IntentFilter; |
11 | import android.net.Proxy; |
12 | |
13 | import org.chromium.base.CalledByNative; |
14 | import org.chromium.base.JNINamespace; |
15 | import org.chromium.base.NativeClassQualifiedName; |
16 | |
17 | // This class partners with native ProxyConfigServiceAndroid to listen for |
18 | // proxy change notifications from Android. |
19 | @JNINamespace("net") |
20 | public class ProxyChangeListener { |
21 | private static final String TAG = "ProxyChangeListener"; |
22 | private static boolean sEnabled = true; |
23 | |
24 | private int mNativePtr; |
25 | private Context mContext; |
26 | private ProxyReceiver mProxyReceiver; |
27 | private Delegate mDelegate; |
28 | |
29 | public interface Delegate { |
30 | public void proxySettingsChanged(); |
31 | } |
32 | |
33 | private ProxyChangeListener(Context context) { |
34 | mContext = context; |
35 | } |
36 | |
37 | public static void setEnabled(boolean enabled) { |
38 | sEnabled = enabled; |
39 | } |
40 | |
41 | public void setDelegateForTesting(Delegate delegate) { |
42 | mDelegate = delegate; |
43 | } |
44 | |
45 | @CalledByNative |
46 | static public ProxyChangeListener create(Context context) { |
47 | return new ProxyChangeListener(context); |
48 | } |
49 | |
50 | @CalledByNative |
51 | static public String getProperty(String property) { |
52 | return System.getProperty(property); |
53 | } |
54 | |
55 | @CalledByNative |
56 | public void start(int nativePtr) { |
57 | assert mNativePtr == 0; |
58 | mNativePtr = nativePtr; |
59 | registerReceiver(); |
60 | } |
61 | |
62 | @CalledByNative |
63 | public void stop() { |
64 | mNativePtr = 0; |
65 | unregisterReceiver(); |
66 | } |
67 | |
68 | private class ProxyReceiver extends BroadcastReceiver { |
69 | @Override |
70 | public void onReceive(Context context, Intent intent) { |
71 | if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) { |
72 | proxySettingsChanged(); |
73 | } |
74 | } |
75 | } |
76 | |
77 | private void proxySettingsChanged() { |
78 | if (!sEnabled) { |
79 | return; |
80 | } |
81 | if (mDelegate != null) { |
82 | mDelegate.proxySettingsChanged(); |
83 | } |
84 | if (mNativePtr == 0) { |
85 | return; |
86 | } |
87 | // 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. |
89 | nativeProxySettingsChanged(mNativePtr); |
90 | } |
91 | |
92 | private void registerReceiver() { |
93 | if (mProxyReceiver != null) { |
94 | return; |
95 | } |
96 | IntentFilter filter = new IntentFilter(); |
97 | filter.addAction(Proxy.PROXY_CHANGE_ACTION); |
98 | mProxyReceiver = new ProxyReceiver(); |
99 | mContext.getApplicationContext().registerReceiver(mProxyReceiver, filter); |
100 | } |
101 | |
102 | private void unregisterReceiver() { |
103 | if (mProxyReceiver == null) { |
104 | return; |
105 | } |
106 | mContext.unregisterReceiver(mProxyReceiver); |
107 | mProxyReceiver = null; |
108 | } |
109 | |
110 | /** |
111 | * See net/proxy/proxy_config_service_android.cc |
112 | */ |
113 | @NativeClassQualifiedName("ProxyConfigServiceAndroid::JNIDelegate") |
114 | private native void nativeProxySettingsChanged(int nativePtr); |
115 | } |