OSDN Git Service

If in a mobile captive portal is detected enable fail fast.
[android-x86/frameworks-base.git] / wifi / java / android / net / wifi / WifiStateTracker.java
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package android.net.wifi;
18
19 import android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.net.LinkCapabilities;
24 import android.net.LinkProperties;
25 import android.net.NetworkInfo;
26 import android.net.NetworkInfo.DetailedState;
27 import android.net.NetworkStateTracker;
28 import android.os.Handler;
29 import android.os.Message;
30 import android.os.Messenger;
31 import android.util.Slog;
32
33 import java.util.concurrent.atomic.AtomicBoolean;
34
35 /**
36  * Track the state of wifi for connectivity service.
37  *
38  * @hide
39  */
40 public class WifiStateTracker implements NetworkStateTracker {
41
42     private static final String NETWORKTYPE = "WIFI";
43     private static final String TAG = "WifiStateTracker";
44
45     private static final boolean LOGV = true;
46
47     private AtomicBoolean mTeardownRequested = new AtomicBoolean(false);
48     private AtomicBoolean mPrivateDnsRouteSet = new AtomicBoolean(false);
49     private AtomicBoolean mDefaultRouteSet = new AtomicBoolean(false);
50
51     private LinkProperties mLinkProperties;
52     private LinkCapabilities mLinkCapabilities;
53     private NetworkInfo mNetworkInfo;
54     private NetworkInfo.State mLastState = NetworkInfo.State.UNKNOWN;
55
56     /* For sending events to connectivity service handler */
57     private Handler mCsHandler;
58     private Context mContext;
59     private BroadcastReceiver mWifiStateReceiver;
60     private WifiManager mWifiManager;
61
62     public WifiStateTracker(int netType, String networkName) {
63         mNetworkInfo = new NetworkInfo(netType, 0, networkName, "");
64         mLinkProperties = new LinkProperties();
65         mLinkCapabilities = new LinkCapabilities();
66
67         mNetworkInfo.setIsAvailable(false);
68         setTeardownRequested(false);
69     }
70
71
72     public void setTeardownRequested(boolean isRequested) {
73         mTeardownRequested.set(isRequested);
74     }
75
76     public boolean isTeardownRequested() {
77         return mTeardownRequested.get();
78     }
79
80     /**
81      * Begin monitoring wifi connectivity
82      */
83     public void startMonitoring(Context context, Handler target) {
84         mCsHandler = target;
85         mContext = context;
86
87         mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
88         IntentFilter filter = new IntentFilter();
89         filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
90         filter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
91
92         mWifiStateReceiver = new WifiStateReceiver();
93         mContext.registerReceiver(mWifiStateReceiver, filter);
94     }
95
96     /**
97      * Disable connectivity to a network
98      * TODO: do away with return value after making MobileDataStateTracker async
99      */
100     public boolean teardown() {
101         mTeardownRequested.set(true);
102         mWifiManager.stopWifi();
103         return true;
104     }
105
106     /**
107      * Re-enable connectivity to a network after a {@link #teardown()}.
108      */
109     public boolean reconnect() {
110         mTeardownRequested.set(false);
111         mWifiManager.startWifi();
112         return true;
113     }
114
115     /**
116      * Captive check is complete, switch to network
117      */
118     @Override
119     public void captivePortalCheckComplete() {
120         mWifiManager.captivePortalCheckComplete();
121     }
122
123     @Override
124     public void captivePortalCheckCompleted(boolean isCaptivePortal) {
125         // not implemented
126     }
127
128     /**
129      * Turn the wireless radio off for a network.
130      * @param turnOn {@code true} to turn the radio on, {@code false}
131      */
132     public boolean setRadio(boolean turnOn) {
133         mWifiManager.setWifiEnabled(turnOn);
134         return true;
135     }
136
137     /**
138      * Wi-Fi is considered available as long as we have a connection to the
139      * supplicant daemon and there is at least one enabled network. If a teardown
140      * was explicitly requested, then Wi-Fi can be restarted with a reconnect
141      * request, so it is considered available. If the driver has been stopped
142      * for any reason other than a teardown request, Wi-Fi is considered
143      * unavailable.
144      * @return {@code true} if Wi-Fi connections are possible
145      */
146     public boolean isAvailable() {
147         return mNetworkInfo.isAvailable();
148     }
149
150     @Override
151     public void setUserDataEnable(boolean enabled) {
152         Slog.w(TAG, "ignoring setUserDataEnable(" + enabled + ")");
153     }
154
155     @Override
156     public void setPolicyDataEnable(boolean enabled) {
157         // ignored
158     }
159
160     /**
161      * Check if private DNS route is set for the network
162      */
163     public boolean isPrivateDnsRouteSet() {
164         return mPrivateDnsRouteSet.get();
165     }
166
167     /**
168      * Set a flag indicating private DNS route is set
169      */
170     public void privateDnsRouteSet(boolean enabled) {
171         mPrivateDnsRouteSet.set(enabled);
172     }
173
174     /**
175      * Fetch NetworkInfo for the network
176      */
177     public NetworkInfo getNetworkInfo() {
178         return new NetworkInfo(mNetworkInfo);
179     }
180
181     /**
182      * Fetch LinkProperties for the network
183      */
184     public LinkProperties getLinkProperties() {
185         return new LinkProperties(mLinkProperties);
186     }
187
188     /**
189      * A capability is an Integer/String pair, the capabilities
190      * are defined in the class LinkSocket#Key.
191      *
192      * @return a copy of this connections capabilities, may be empty but never null.
193      */
194     public LinkCapabilities getLinkCapabilities() {
195         return new LinkCapabilities(mLinkCapabilities);
196     }
197
198     /**
199      * Check if default route is set
200      */
201     public boolean isDefaultRouteSet() {
202         return mDefaultRouteSet.get();
203     }
204
205     /**
206      * Set a flag indicating default route is set for the network
207      */
208     public void defaultRouteSet(boolean enabled) {
209         mDefaultRouteSet.set(enabled);
210     }
211
212     /**
213      * Return the system properties name associated with the tcp buffer sizes
214      * for this network.
215      */
216     public String getTcpBufferSizesPropName() {
217         return "net.tcp.buffersize.wifi";
218     }
219
220     private class WifiStateReceiver extends BroadcastReceiver {
221         @Override
222         public void onReceive(Context context, Intent intent) {
223
224             if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
225                 mNetworkInfo = (NetworkInfo) intent.getParcelableExtra(
226                         WifiManager.EXTRA_NETWORK_INFO);
227                 mLinkProperties = intent.getParcelableExtra(
228                         WifiManager.EXTRA_LINK_PROPERTIES);
229                 if (mLinkProperties == null) {
230                     mLinkProperties = new LinkProperties();
231                 }
232                 mLinkCapabilities = intent.getParcelableExtra(
233                         WifiManager.EXTRA_LINK_CAPABILITIES);
234                 if (mLinkCapabilities == null) {
235                     mLinkCapabilities = new LinkCapabilities();
236                 }
237                 // don't want to send redundent state messages
238                 // but send portal check detailed state notice
239                 NetworkInfo.State state = mNetworkInfo.getState();
240                 if (mLastState == state &&
241                         mNetworkInfo.getDetailedState() != DetailedState.CAPTIVE_PORTAL_CHECK) {
242                     return;
243                 } else {
244                     mLastState = state;
245                 }
246                 Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED,
247                         new NetworkInfo(mNetworkInfo));
248                 msg.sendToTarget();
249             } else if (intent.getAction().equals(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION)) {
250                 mLinkProperties = (LinkProperties) intent.getParcelableExtra(
251                         WifiManager.EXTRA_LINK_PROPERTIES);
252                 Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
253                 msg.sendToTarget();
254             }
255         }
256     }
257
258     public void setDependencyMet(boolean met) {
259         // not supported on this network
260     }
261
262     @Override
263     public void addStackedLink(LinkProperties link) {
264         mLinkProperties.addStackedLink(link);
265     }
266
267     @Override
268     public void removeStackedLink(LinkProperties link) {
269         mLinkProperties.removeStackedLink(link);
270     }
271
272     @Override
273     public void supplyMessenger(Messenger messenger) {
274         // not supported on this network
275     }
276 }