2 * Copyright (C) 2010 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package android.net.wifi;
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;
33 import java.util.concurrent.atomic.AtomicBoolean;
36 * Track the state of wifi for connectivity service.
40 public class WifiStateTracker implements NetworkStateTracker {
42 private static final String NETWORKTYPE = "WIFI";
43 private static final String TAG = "WifiStateTracker";
45 private static final boolean LOGV = true;
47 private AtomicBoolean mTeardownRequested = new AtomicBoolean(false);
48 private AtomicBoolean mPrivateDnsRouteSet = new AtomicBoolean(false);
49 private AtomicBoolean mDefaultRouteSet = new AtomicBoolean(false);
51 private LinkProperties mLinkProperties;
52 private LinkCapabilities mLinkCapabilities;
53 private NetworkInfo mNetworkInfo;
54 private NetworkInfo.State mLastState = NetworkInfo.State.UNKNOWN;
56 /* For sending events to connectivity service handler */
57 private Handler mCsHandler;
58 private Context mContext;
59 private BroadcastReceiver mWifiStateReceiver;
60 private WifiManager mWifiManager;
62 public WifiStateTracker(int netType, String networkName) {
63 mNetworkInfo = new NetworkInfo(netType, 0, networkName, "");
64 mLinkProperties = new LinkProperties();
65 mLinkCapabilities = new LinkCapabilities();
67 mNetworkInfo.setIsAvailable(false);
68 setTeardownRequested(false);
72 public void setTeardownRequested(boolean isRequested) {
73 mTeardownRequested.set(isRequested);
76 public boolean isTeardownRequested() {
77 return mTeardownRequested.get();
81 * Begin monitoring wifi connectivity
83 public void startMonitoring(Context context, Handler target) {
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);
92 mWifiStateReceiver = new WifiStateReceiver();
93 mContext.registerReceiver(mWifiStateReceiver, filter);
97 * Disable connectivity to a network
98 * TODO: do away with return value after making MobileDataStateTracker async
100 public boolean teardown() {
101 mTeardownRequested.set(true);
102 mWifiManager.stopWifi();
107 * Re-enable connectivity to a network after a {@link #teardown()}.
109 public boolean reconnect() {
110 mTeardownRequested.set(false);
111 mWifiManager.startWifi();
116 * Captive check is complete, switch to network
119 public void captivePortalCheckComplete() {
120 mWifiManager.captivePortalCheckComplete();
124 public void captivePortalCheckCompleted(boolean isCaptivePortal) {
129 * Turn the wireless radio off for a network.
130 * @param turnOn {@code true} to turn the radio on, {@code false}
132 public boolean setRadio(boolean turnOn) {
133 mWifiManager.setWifiEnabled(turnOn);
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
144 * @return {@code true} if Wi-Fi connections are possible
146 public boolean isAvailable() {
147 return mNetworkInfo.isAvailable();
151 public void setUserDataEnable(boolean enabled) {
152 Slog.w(TAG, "ignoring setUserDataEnable(" + enabled + ")");
156 public void setPolicyDataEnable(boolean enabled) {
161 * Check if private DNS route is set for the network
163 public boolean isPrivateDnsRouteSet() {
164 return mPrivateDnsRouteSet.get();
168 * Set a flag indicating private DNS route is set
170 public void privateDnsRouteSet(boolean enabled) {
171 mPrivateDnsRouteSet.set(enabled);
175 * Fetch NetworkInfo for the network
177 public NetworkInfo getNetworkInfo() {
178 return new NetworkInfo(mNetworkInfo);
182 * Fetch LinkProperties for the network
184 public LinkProperties getLinkProperties() {
185 return new LinkProperties(mLinkProperties);
189 * A capability is an Integer/String pair, the capabilities
190 * are defined in the class LinkSocket#Key.
192 * @return a copy of this connections capabilities, may be empty but never null.
194 public LinkCapabilities getLinkCapabilities() {
195 return new LinkCapabilities(mLinkCapabilities);
199 * Check if default route is set
201 public boolean isDefaultRouteSet() {
202 return mDefaultRouteSet.get();
206 * Set a flag indicating default route is set for the network
208 public void defaultRouteSet(boolean enabled) {
209 mDefaultRouteSet.set(enabled);
213 * Return the system properties name associated with the tcp buffer sizes
216 public String getTcpBufferSizesPropName() {
217 return "net.tcp.buffersize.wifi";
220 private class WifiStateReceiver extends BroadcastReceiver {
222 public void onReceive(Context context, Intent intent) {
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();
232 mLinkCapabilities = intent.getParcelableExtra(
233 WifiManager.EXTRA_LINK_CAPABILITIES);
234 if (mLinkCapabilities == null) {
235 mLinkCapabilities = new LinkCapabilities();
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) {
246 Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED,
247 new NetworkInfo(mNetworkInfo));
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);
258 public void setDependencyMet(boolean met) {
259 // not supported on this network
263 public void addStackedLink(LinkProperties link) {
264 mLinkProperties.addStackedLink(link);
268 public void removeStackedLink(LinkProperties link) {
269 mLinkProperties.removeStackedLink(link);
273 public void supplyMessenger(Messenger messenger) {
274 // not supported on this network