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 17package android.net.wifi; 18 19import android.content.BroadcastReceiver; 20import android.content.Context; 21import android.content.Intent; 22import android.content.IntentFilter; 23import android.net.LinkCapabilities; 24import android.net.LinkProperties; 25import android.net.NetworkInfo; 26import android.net.NetworkStateTracker; 27import android.net.wifi.p2p.WifiP2pManager; 28import android.os.Handler; 29import android.os.Message; 30import android.util.Slog; 31 32import java.util.concurrent.atomic.AtomicBoolean; 33 34/** 35 * Track the state of wifi for connectivity service. 36 * 37 * @hide 38 */ 39public class WifiStateTracker implements NetworkStateTracker { 40 41 private static final String NETWORKTYPE = "WIFI"; 42 private static final String TAG = "WifiStateTracker"; 43 44 private static final boolean LOGV = true; 45 46 private AtomicBoolean mTeardownRequested = new AtomicBoolean(false); 47 private AtomicBoolean mPrivateDnsRouteSet = new AtomicBoolean(false); 48 private AtomicBoolean mDefaultRouteSet = new AtomicBoolean(false); 49 50 private LinkProperties mLinkProperties; 51 private LinkCapabilities mLinkCapabilities; 52 private NetworkInfo mNetworkInfo; 53 private NetworkInfo.State mLastState = NetworkInfo.State.UNKNOWN; 54 55 /* For sending events to connectivity service handler */ 56 private Handler mCsHandler; 57 private Context mContext; 58 private BroadcastReceiver mWifiStateReceiver; 59 private WifiManager mWifiManager; 60 61 public WifiStateTracker(int netType, String networkName) { 62 mNetworkInfo = new NetworkInfo(netType, 0, networkName, ""); 63 mLinkProperties = new LinkProperties(); 64 mLinkCapabilities = new LinkCapabilities(); 65 66 mNetworkInfo.setIsAvailable(false); 67 setTeardownRequested(false); 68 } 69 70 71 public void setTeardownRequested(boolean isRequested) { 72 mTeardownRequested.set(isRequested); 73 } 74 75 public boolean isTeardownRequested() { 76 return mTeardownRequested.get(); 77 } 78 79 /** 80 * Begin monitoring wifi connectivity 81 */ 82 public void startMonitoring(Context context, Handler target) { 83 mCsHandler = target; 84 mContext = context; 85 86 mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 87 IntentFilter filter = new IntentFilter(); 88 filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 89 filter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION); 90 filter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_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 * Turn the wireless radio off for a network. 117 * @param turnOn {@code true} to turn the radio on, {@code false} 118 */ 119 public boolean setRadio(boolean turnOn) { 120 mWifiManager.setWifiEnabled(turnOn); 121 return true; 122 } 123 124 /** 125 * Wi-Fi is considered available as long as we have a connection to the 126 * supplicant daemon and there is at least one enabled network. If a teardown 127 * was explicitly requested, then Wi-Fi can be restarted with a reconnect 128 * request, so it is considered available. If the driver has been stopped 129 * for any reason other than a teardown request, Wi-Fi is considered 130 * unavailable. 131 * @return {@code true} if Wi-Fi connections are possible 132 */ 133 public boolean isAvailable() { 134 return mNetworkInfo.isAvailable(); 135 } 136 137 @Override 138 public void setUserDataEnable(boolean enabled) { 139 Slog.w(TAG, "ignoring setUserDataEnable(" + enabled + ")"); 140 } 141 142 @Override 143 public void setPolicyDataEnable(boolean enabled) { 144 // ignored 145 } 146 147 /** 148 * Check if private DNS route is set for the network 149 */ 150 public boolean isPrivateDnsRouteSet() { 151 return mPrivateDnsRouteSet.get(); 152 } 153 154 /** 155 * Set a flag indicating private DNS route is set 156 */ 157 public void privateDnsRouteSet(boolean enabled) { 158 mPrivateDnsRouteSet.set(enabled); 159 } 160 161 /** 162 * Fetch NetworkInfo for the network 163 */ 164 public NetworkInfo getNetworkInfo() { 165 return new NetworkInfo(mNetworkInfo); 166 } 167 168 /** 169 * Fetch LinkProperties for the network 170 */ 171 public LinkProperties getLinkProperties() { 172 return new LinkProperties(mLinkProperties); 173 } 174 175 /** 176 * A capability is an Integer/String pair, the capabilities 177 * are defined in the class LinkSocket#Key. 178 * 179 * @return a copy of this connections capabilities, may be empty but never null. 180 */ 181 public LinkCapabilities getLinkCapabilities() { 182 return new LinkCapabilities(mLinkCapabilities); 183 } 184 185 /** 186 * Check if default route is set 187 */ 188 public boolean isDefaultRouteSet() { 189 return mDefaultRouteSet.get(); 190 } 191 192 /** 193 * Set a flag indicating default route is set for the network 194 */ 195 public void defaultRouteSet(boolean enabled) { 196 mDefaultRouteSet.set(enabled); 197 } 198 199 /** 200 * Return the system properties name associated with the tcp buffer sizes 201 * for this network. 202 */ 203 public String getTcpBufferSizesPropName() { 204 return "net.tcp.buffersize.wifi"; 205 } 206 207 private class WifiStateReceiver extends BroadcastReceiver { 208 @Override 209 public void onReceive(Context context, Intent intent) { 210 211 if (intent.getAction().equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) { 212 mNetworkInfo = (NetworkInfo) intent.getParcelableExtra( 213 WifiP2pManager.EXTRA_NETWORK_INFO); 214 mLinkProperties = intent.getParcelableExtra( 215 WifiP2pManager.EXTRA_LINK_PROPERTIES); 216 if (mLinkProperties == null) { 217 mLinkProperties = new LinkProperties(); 218 } 219 mLinkCapabilities = intent.getParcelableExtra( 220 WifiP2pManager.EXTRA_LINK_CAPABILITIES); 221 if (mLinkCapabilities == null) { 222 mLinkCapabilities = new LinkCapabilities(); 223 } 224 } else 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 // TODO can this be fixed in WifiStateMachine? 239 NetworkInfo.State state = mNetworkInfo.getState(); 240 if (mLastState == state) { 241 return; 242 } else { 243 mLastState = state; 244 } 245 Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, 246 new NetworkInfo(mNetworkInfo)); 247 msg.sendToTarget(); 248 } else if (intent.getAction().equals(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION)) { 249 mLinkProperties = (LinkProperties) intent.getParcelableExtra( 250 WifiManager.EXTRA_LINK_PROPERTIES); 251 Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo); 252 msg.sendToTarget(); 253 } 254 } 255 } 256 257 public void setDependencyMet(boolean met) { 258 // not supported on this network 259 } 260} 261