WifiManager.java revision 59358536d2f14b27cdc7386daeabc2b6dca8e177
14aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy/* 24aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Copyright (C) 2008 The Android Open Source Project 34aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * 44aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 54aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * you may not use this file except in compliance with the License. 64aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * You may obtain a copy of the License at 74aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * 84aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * http://www.apache.org/licenses/LICENSE-2.0 94aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * 104aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Unless required by applicable law or agreed to in writing, software 114aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * distributed under the License is distributed on an "AS IS" BASIS, 124aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * See the License for the specific language governing permissions and 144aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * limitations under the License. 154aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 164aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 174aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guypackage android.net.wifi; 184aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 194aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyimport android.annotation.SdkConstant; 204aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyimport android.annotation.SdkConstant.SdkConstantType; 214aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyimport android.content.Context; 224aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyimport android.net.DhcpInfo; 234aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyimport android.os.Binder; 244aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyimport android.os.IBinder; 254aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyimport android.os.Handler; 264aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyimport android.os.HandlerThread; 274aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyimport android.os.Looper; 284aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyimport android.os.Message; 294aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyimport android.os.RemoteException; 304aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyimport android.os.WorkSource; 314aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyimport android.os.Messenger; 324aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyimport android.util.Log; 334aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyimport android.util.SparseArray; 344aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 354aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyimport java.util.concurrent.CountDownLatch; 364aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 374aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyimport com.android.internal.util.AsyncChannel; 384aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyimport com.android.internal.util.Protocol; 394aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 404aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guyimport java.util.List; 414aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 424aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy/** 434aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * This class provides the primary API for managing all aspects of Wi-Fi 444aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * connectivity. Get an instance of this class by calling 454aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * {@link android.content.Context#getSystemService(String) Context.getSystemService(Context.WIFI_SERVICE)}. 464aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 474aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * It deals with several categories of items: 487975fb6d12cb1eb96b75e3a563627cd4c4081bd6Romain Guy * <ul> 497975fb6d12cb1eb96b75e3a563627cd4c4081bd6Romain Guy * <li>The list of configured networks. The list can be viewed and updated, 507975fb6d12cb1eb96b75e3a563627cd4c4081bd6Romain Guy * and attributes of individual entries can be modified.</li> 514aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * <li>The currently active Wi-Fi network, if any. Connectivity can be 527975fb6d12cb1eb96b75e3a563627cd4c4081bd6Romain Guy * established or torn down, and dynamic information about the state of 534aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * the network can be queried.</li> 544aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * <li>Results of access point scans, containing enough information to 554aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * make decisions about what access point to connect to.</li> 56b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * <li>It defines the names of various Intent actions that are broadcast 574aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * upon any sort of change in Wi-Fi state. 584aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * </ul> 594aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * This is the API to use when performing Wi-Fi specific operations. To 607975fb6d12cb1eb96b75e3a563627cd4c4081bd6Romain Guy * perform operations that pertain to network connectivity at an abstract 614aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * level, use {@link android.net.ConnectivityManager}. 624aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 634aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guypublic class WifiManager { 644aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 654aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy private static final String TAG = "WifiManager"; 664aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy // Supplicant error codes: 674aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy /** 68b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * The error code if there was a problem authenticating. 694aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 704aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy public static final int ERROR_AUTHENTICATING = 1; 71b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy 72b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy /** 734aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Broadcast intent action indicating that Wi-Fi has been enabled, disabled, 74b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * enabling, disabling, or unknown. One extra provides this state as an int. 754aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Another extra provides the previous state, if available. 76b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * 774aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @see #EXTRA_WIFI_STATE 78b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #EXTRA_PREVIOUS_WIFI_STATE 79b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy */ 804aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 814aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy public static final String WIFI_STATE_CHANGED_ACTION = 824aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy "android.net.wifi.WIFI_STATE_CHANGED"; 834aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy /** 844aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * The lookup key for an int that indicates whether Wi-Fi is enabled, 854aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * disabled, enabling, disabling, or unknown. Retrieve it with 864aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * {@link android.content.Intent#getIntExtra(String,int)}. 874aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * 884aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @see #WIFI_STATE_DISABLED 894aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @see #WIFI_STATE_DISABLING 904aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @see #WIFI_STATE_ENABLED 914aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @see #WIFI_STATE_ENABLING 924aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @see #WIFI_STATE_UNKNOWN 934aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 944aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy public static final String EXTRA_WIFI_STATE = "wifi_state"; 954aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy /** 964aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * The previous Wi-Fi state. 974aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * 984aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @see #EXTRA_WIFI_STATE 994aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 1004aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy public static final String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state"; 1014aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 1024aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy /** 1034aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Wi-Fi is currently being disabled. The state will change to {@link #WIFI_STATE_DISABLED} if 1044aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * it finishes successfully. 1054aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * 1064aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @see #WIFI_STATE_CHANGED_ACTION 1074aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @see #getWifiState() 1084aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 1094aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy public static final int WIFI_STATE_DISABLING = 0; 1104aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy /** 111b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * Wi-Fi is disabled. 112b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * 113b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #WIFI_STATE_CHANGED_ACTION 114b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #getWifiState() 115b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy */ 116b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy public static final int WIFI_STATE_DISABLED = 1; 117b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy /** 118b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * Wi-Fi is currently being enabled. The state will change to {@link #WIFI_STATE_ENABLED} if 119b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * it finishes successfully. 120b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * 121b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #WIFI_STATE_CHANGED_ACTION 122b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #getWifiState() 123b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy */ 124b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy public static final int WIFI_STATE_ENABLING = 2; 125b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy /** 126b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * Wi-Fi is enabled. 127b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * 128b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #WIFI_STATE_CHANGED_ACTION 129b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #getWifiState() 130b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy */ 1315c13d89c1332fcc499379b9064b891187b75ca32Chet Haase public static final int WIFI_STATE_ENABLED = 3; 1325c13d89c1332fcc499379b9064b891187b75ca32Chet Haase /** 1335c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * Wi-Fi is in an unknown state. This state will occur when an error happens while enabling 1345c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * or disabling. 1355c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * 136b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #WIFI_STATE_CHANGED_ACTION 137b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #getWifiState() 138ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase */ 139ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase public static final int WIFI_STATE_UNKNOWN = 4; 140ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase 141ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase /** 142b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * Broadcast intent action indicating that Wi-Fi AP has been enabled, disabled, 143b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * enabling, disabling, or failed. 144b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * 145b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @hide 146b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy */ 147b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy public static final String WIFI_AP_STATE_CHANGED_ACTION = 148b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy "android.net.wifi.WIFI_AP_STATE_CHANGED"; 149b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy 150b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy /** 1515c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * The lookup key for an int that indicates whether Wi-Fi AP is enabled, 152b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * disabled, enabling, disabling, or failed. Retrieve it with 153b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * {@link android.content.Intent#getIntExtra(String,int)}. 154b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * 155b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #WIFI_AP_STATE_DISABLED 156b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #WIFI_AP_STATE_DISABLING 157b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #WIFI_AP_STATE_ENABLED 158b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #WIFI_AP_STATE_ENABLING 1595c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * @see #WIFI_AP_STATE_FAILED 160b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * 161b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @hide 162b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy */ 163b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy public static final String EXTRA_WIFI_AP_STATE = "wifi_state"; 164b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy /** 165b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * The previous Wi-Fi state. 166b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * 167b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #EXTRA_WIFI_AP_STATE 168b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * 169b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @hide 170b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy */ 1714bb942083a0d4db746adf95349108dd8ef842e32Romain Guy public static final String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state"; 1724bb942083a0d4db746adf95349108dd8ef842e32Romain Guy /** 1734bb942083a0d4db746adf95349108dd8ef842e32Romain Guy * Wi-Fi AP is currently being disabled. The state will change to 1744bb942083a0d4db746adf95349108dd8ef842e32Romain Guy * {@link #WIFI_AP_STATE_DISABLED} if it finishes successfully. 1754bb942083a0d4db746adf95349108dd8ef842e32Romain Guy * 176b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #WIFI_AP_STATE_CHANGED_ACTION 177b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #getWifiApState() 178b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * 179b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @hide 180b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy */ 181b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy public static final int WIFI_AP_STATE_DISABLING = 10; 182b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy /** 183b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * Wi-Fi AP is disabled. 184b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * 185b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #WIFI_AP_STATE_CHANGED_ACTION 186b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #getWifiState() 187b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * 1885c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * @hide 1895c13d89c1332fcc499379b9064b891187b75ca32Chet Haase */ 190ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase public static final int WIFI_AP_STATE_DISABLED = 11; 191b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy /** 192d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase * Wi-Fi AP is currently being enabled. The state will change to 193d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase * {@link #WIFI_AP_STATE_ENABLED} if it finishes successfully. 194d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase * 195b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #WIFI_AP_STATE_CHANGED_ACTION 196b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #getWifiApState() 197b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * 198b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @hide 199b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy */ 200b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy public static final int WIFI_AP_STATE_ENABLING = 12; 201b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy /** 202b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * Wi-Fi AP is enabled. 203b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * 204b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #WIFI_AP_STATE_CHANGED_ACTION 205b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #getWifiApState() 206b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * 207b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @hide 208b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy */ 209b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy public static final int WIFI_AP_STATE_ENABLED = 13; 210b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy /** 211b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * Wi-Fi AP is in a failed state. This state will occur when an error occurs during 212b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * enabling or disabling 213b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * 2146b7bd24659fb175fe1f0e97c86c18969918b496aRomain Guy * @see #WIFI_AP_STATE_CHANGED_ACTION 215b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * @see #getWifiApState() 2164aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * 2174aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @hide 2184aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 2194aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy public static final int WIFI_AP_STATE_FAILED = 14; 2204aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 2214aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy /** 2224aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Broadcast intent action indicating that a connection to the supplicant has 2234aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * been established (and it is now possible 2245c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * to perform Wi-Fi operations) or the connection to the supplicant has been 2254aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * lost. One extra provides the connection state as a boolean, where {@code true} 2264aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * means CONNECTED. 2274aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @see #EXTRA_SUPPLICANT_CONNECTED 2284aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 2294aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 2304aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION = 2314aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy "android.net.wifi.supplicant.CONNECTION_CHANGE"; 2324aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy /** 2334aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * The lookup key for a boolean that indicates whether a connection to 2344aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * the supplicant daemon has been gained or lost. {@code true} means 2355c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * a connection now exists. 2365c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}. 2374aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 2384aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy public static final String EXTRA_SUPPLICANT_CONNECTED = "connected"; 2395c13d89c1332fcc499379b9064b891187b75ca32Chet Haase /** 2404aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Broadcast intent action indicating that the state of Wi-Fi connectivity 2414bb942083a0d4db746adf95349108dd8ef842e32Romain Guy * has changed. One extra provides the new state 2425c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * in the form of a {@link android.net.NetworkInfo} object. If the new 2434aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * state is CONNECTED, additional extras may provide the BSSID and WifiInfo of 2445c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * the access point. 2454aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * as a {@code String}. 2465c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * @see #EXTRA_NETWORK_INFO 2474aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @see #EXTRA_BSSID 2484aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @see #EXTRA_WIFI_INFO 2494aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 2504aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 2514aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy public static final String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE"; 2524aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy /** 2534aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * The lookup key for a {@link android.net.NetworkInfo} object associated with the 2544aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Wi-Fi network. Retrieve with 2554aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * {@link android.content.Intent#getParcelableExtra(String)}. 2564aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 2574aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy public static final String EXTRA_NETWORK_INFO = "networkInfo"; 2584aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy /** 2594aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * The lookup key for a String giving the BSSID of the access point to which 260b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * we are connected. Only present when the new state is CONNECTED. 261b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * Retrieve with 262b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * {@link android.content.Intent#getStringExtra(String)}. 263b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy */ 264b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy public static final String EXTRA_BSSID = "bssid"; 265b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy /** 266b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * The lookup key for a {@link android.net.wifi.WifiInfo} object giving the 267b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * information about the access point to which we are connected. Only present 2685c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * when the new state is CONNECTED. Retrieve with 2695c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * {@link android.content.Intent#getParcelableExtra(String)}. 270b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy */ 271b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy public static final String EXTRA_WIFI_INFO = "wifiInfo"; 272d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase /** 273d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase * Broadcast intent action indicating that the state of establishing a connection to 274b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * an access point has changed.One extra provides the new 275b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * {@link SupplicantState}. Note that the supplicant state is Wi-Fi specific, and 276d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase * is not generally the most useful thing to look at if you are just interested in 277d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase * the overall state of connectivity. 2785c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * @see #EXTRA_NEW_STATE 2795c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * @see #EXTRA_SUPPLICANT_ERROR 280d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase */ 281d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 282b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy public static final String SUPPLICANT_STATE_CHANGED_ACTION = 283b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy "android.net.wifi.supplicant.STATE_CHANGE"; 284ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase /** 285ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase * The lookup key for a {@link SupplicantState} describing the new state 286ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase * Retrieve with 287ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase * {@link android.content.Intent#getParcelableExtra(String)}. 2884aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 289b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy public static final String EXTRA_NEW_STATE = "newState"; 2904aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 2914aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy /** 2924aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * The lookup key for a {@link SupplicantState} describing the supplicant 2934aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * error code if any 2944aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Retrieve with 2954aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * {@link android.content.Intent#getIntExtra(String, int)}. 2964aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @see #ERROR_AUTHENTICATING 2974aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 298b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy public static final String EXTRA_SUPPLICANT_ERROR = "supplicantError"; 2994aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 3004bb942083a0d4db746adf95349108dd8ef842e32Romain Guy /** 3014bb942083a0d4db746adf95349108dd8ef842e32Romain Guy * Broadcast intent action indicating that the configured networks changed. 3024bb942083a0d4db746adf95349108dd8ef842e32Romain Guy * This can be as a result of adding/updating/deleting a network. If 3034bb942083a0d4db746adf95349108dd8ef842e32Romain Guy * {@link #EXTRA_MULTIPLE_NETWORKS_CHANGED} is set to true the new configuration 3044bb942083a0d4db746adf95349108dd8ef842e32Romain Guy * can be retreived with the {@link #EXTRA_WIFI_CONFIGURATION} extra. If multiple 3054bb942083a0d4db746adf95349108dd8ef842e32Romain Guy * Wi-Fi configurations changed, {@link #EXTRA_WIFI_CONFIGURATION} will not be present. 3064bb942083a0d4db746adf95349108dd8ef842e32Romain Guy * @hide 3074aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 3084aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy public static final String CONFIGURED_NETWORKS_CHANGED_ACTION = 3094aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy "android.net.wifi.CONFIGURED_NETWORKS_CHANGE"; 3104aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy /** 3114aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * The lookup key for a (@link android.net.wifi.WifiConfiguration} object representing 3124aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * the changed Wi-Fi configuration when the {@link #CONFIGURED_NETWORKS_CHANGED_ACTION} 3134aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * broadcast is sent. 3144aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @hide 3154aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 316b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy public static final String EXTRA_WIFI_CONFIGURATION = "wifiConfiguration"; 3174aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy /** 3184aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Multiple network configurations have changed. 3194aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @see #CONFIGURED_NETWORKS_CHANGED_ACTION 3204aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * 3214aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @hide 3224aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 3234aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy public static final String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges"; 3244aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy /** 3254aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * The lookup key for an integer indicating the reason a Wi-Fi network configuration 3264aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * has changed. Only present if {@link #EXTRA_MULTIPLE_NETWORKS_CHANGED} is {@code false} 3274aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @see #CONFIGURED_NETWORKS_CHANGED_ACTION 3284aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @hide 3294aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 3304aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy public static final String EXTRA_CHANGE_REASON = "changeReason"; 3314aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy /** 3324aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * The configuration is new and was added. 3334aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @hide 3344aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 3354aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy public static final int CHANGE_REASON_ADDED = 0; 3364aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy /** 3374aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * The configuration was removed and is no longer present in the system's list of 3384aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * configured networks. 3394aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @hide 3404aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 3414aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy public static final int CHANGE_REASON_REMOVED = 1; 3424aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy /** 3434aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * The configuration has changed as a result of explicit action or because the system 3444aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * took an automated action such as disabling a malfunctioning configuration. 3454aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * @hide 3465c13d89c1332fcc499379b9064b891187b75ca32Chet Haase */ 347d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase public static final int CHANGE_REASON_CONFIG_CHANGE = 2; 348d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase /** 349d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase * An access point scan has completed, and results are available from the supplicant. 350d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase * Call {@link #getScanResults()} to obtain the results. 351d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase */ 352d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 353d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS"; 354d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase /** 355d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase * The RSSI (signal strength) has changed. 356d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase * @see #EXTRA_NEW_RSSI 357d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase */ 3584aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 3594aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED"; 3605c13d89c1332fcc499379b9064b891187b75ca32Chet Haase /** 361d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase * The lookup key for an {@code int} giving the new RSSI in dBm. 362d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase */ 363d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase public static final String EXTRA_NEW_RSSI = "newRssi"; 3644aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 3654aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy /** 3665c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * Broadcast intent action indicating that the link configuration 367d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase * changed on wifi. 368d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase * @hide 369d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase */ 370d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase public static final String LINK_CONFIGURATION_CHANGED_ACTION = 3715c13d89c1332fcc499379b9064b891187b75ca32Chet Haase "android.net.wifi.LINK_CONFIGURATION_CHANGED"; 3725c13d89c1332fcc499379b9064b891187b75ca32Chet Haase 3735c13d89c1332fcc499379b9064b891187b75ca32Chet Haase /** 3745c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * The lookup key for a {@link android.net.LinkProperties} object associated with the 3755c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * Wi-Fi network. Retrieve with 3764aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * {@link android.content.Intent#getParcelableExtra(String)}. 3775c13d89c1332fcc499379b9064b891187b75ca32Chet Haase * @hide 3785c13d89c1332fcc499379b9064b891187b75ca32Chet Haase */ 3795c13d89c1332fcc499379b9064b891187b75ca32Chet Haase public static final String EXTRA_LINK_PROPERTIES = "linkProperties"; 3805c13d89c1332fcc499379b9064b891187b75ca32Chet Haase 3815c13d89c1332fcc499379b9064b891187b75ca32Chet Haase /** 3824aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * The lookup key for a {@link android.net.LinkCapabilities} object associated with the 3834aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Wi-Fi network. Retrieve with 384ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase * {@link android.content.Intent#getParcelableExtra(String)}. 385ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase * @hide 386ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase */ 387ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase public static final String EXTRA_LINK_CAPABILITIES = "linkCapabilities"; 388ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase 389ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase /** 390ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase * The network IDs of the configured networks could have changed. 3914aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 3924aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 3935c13d89c1332fcc499379b9064b891187b75ca32Chet Haase public static final String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED"; 3945c13d89c1332fcc499379b9064b891187b75ca32Chet Haase 395ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase /** 3964aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * Activity Action: Pick a Wi-Fi network to connect to. 397d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase * <p>Input: Nothing. 398d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase * <p>Output: Nothing. 399d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase */ 400d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 4014aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK"; 4024aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy 4034aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy /** 4044aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * In this Wi-Fi lock mode, Wi-Fi will be kept active, 4054aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * and will behave normally, i.e., it will attempt to automatically 4064aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * establish a connection to a remembered access point that is 407b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * within range, and will do periodic scans if there are remembered 408b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * access points but none are in range. 4094aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy */ 4104aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy public static final int WIFI_MODE_FULL = 1; 4114aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy /** 4124aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * In this Wi-Fi lock mode, Wi-Fi will be kept active, 4134aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * but the only operation that will be supported is initiation of 4144aa90573bbf86db0d33a3a790c5dbd0d93b95cfeRomain Guy * scans, and the subsequent reporting of scan results. No attempts 415 * will be made to automatically connect to remembered access points, 416 * nor will periodic scans be automatically performed looking for 417 * remembered access points. Scans must be explicitly requested by 418 * an application in this mode. 419 */ 420 public static final int WIFI_MODE_SCAN_ONLY = 2; 421 /** 422 * In this Wi-Fi lock mode, Wi-Fi will be kept active as in mode 423 * {@link #WIFI_MODE_FULL} but it operates at high performance 424 * with minimum packet loss and low packet latency even when 425 * the device screen is off. This mode will consume more power 426 * and hence should be used only when there is a need for such 427 * an active connection. 428 * <p> 429 * An example use case is when a voice connection needs to be 430 * kept active even after the device screen goes off. Holding the 431 * regular {@link #WIFI_MODE_FULL} lock will keep the wifi 432 * connection active, but the connection can be lossy. 433 * Holding a {@link #WIFI_MODE_FULL_HIGH_PERF} lock for the 434 * duration of the voice call will improve the call quality. 435 * <p> 436 * When there is no support from the hardware, this lock mode 437 * will have the same behavior as {@link #WIFI_MODE_FULL} 438 */ 439 public static final int WIFI_MODE_FULL_HIGH_PERF = 3; 440 441 /** Anything worse than or equal to this will show 0 bars. */ 442 private static final int MIN_RSSI = -100; 443 444 /** Anything better than or equal to this will show the max bars. */ 445 private static final int MAX_RSSI = -55; 446 447 /** 448 * Number of RSSI levels used in the framework to initiate 449 * {@link #RSSI_CHANGED_ACTION} broadcast 450 * @hide 451 */ 452 public static final int RSSI_LEVELS = 5; 453 454 /** 455 * Auto settings in the driver. The driver could choose to operate on both 456 * 2.4 GHz and 5 GHz or make a dynamic decision on selecting the band. 457 * @hide 458 */ 459 public static final int WIFI_FREQUENCY_BAND_AUTO = 0; 460 461 /** 462 * Operation on 5 GHz alone 463 * @hide 464 */ 465 public static final int WIFI_FREQUENCY_BAND_5GHZ = 1; 466 467 /** 468 * Operation on 2.4 GHz alone 469 * @hide 470 */ 471 public static final int WIFI_FREQUENCY_BAND_2GHZ = 2; 472 473 /** List of asyncronous notifications 474 * @hide 475 */ 476 public static final int DATA_ACTIVITY_NOTIFICATION = 1; 477 478 //Lowest bit indicates data reception and the second lowest 479 //bit indicates data transmitted 480 /** @hide */ 481 public static final int DATA_ACTIVITY_NONE = 0x00; 482 /** @hide */ 483 public static final int DATA_ACTIVITY_IN = 0x01; 484 /** @hide */ 485 public static final int DATA_ACTIVITY_OUT = 0x02; 486 /** @hide */ 487 public static final int DATA_ACTIVITY_INOUT = 0x03; 488 489 /* Maximum number of active locks we allow. 490 * This limit was added to prevent apps from creating a ridiculous number 491 * of locks and crashing the system by overflowing the global ref table. 492 */ 493 private static final int MAX_ACTIVE_LOCKS = 50; 494 495 /* Number of currently active WifiLocks and MulticastLocks */ 496 private int mActiveLockCount; 497 498 private Context mContext; 499 IWifiManager mService; 500 501 private static final int INVALID_KEY = 0; 502 private int mListenerKey = 1; 503 private final SparseArray mListenerMap = new SparseArray(); 504 private final Object mListenerMapLock = new Object(); 505 506 private AsyncChannel mAsyncChannel = new AsyncChannel(); 507 private ServiceHandler mHandler; 508 private Messenger mWifiServiceMessenger; 509 private final CountDownLatch mConnected = new CountDownLatch(1); 510 511 /** 512 * Create a new WifiManager instance. 513 * Applications will almost always want to use 514 * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve 515 * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}. 516 * @param context the application context 517 * @param service the Binder interface 518 * @hide - hide this because it takes in a parameter of type IWifiManager, which 519 * is a system private class. 520 */ 521 public WifiManager(Context context, IWifiManager service) { 522 mContext = context; 523 mService = service; 524 init(); 525 } 526 527 /** 528 * Return a list of all the networks configured in the supplicant. 529 * Not all fields of WifiConfiguration are returned. Only the following 530 * fields are filled in: 531 * <ul> 532 * <li>networkId</li> 533 * <li>SSID</li> 534 * <li>BSSID</li> 535 * <li>priority</li> 536 * <li>allowedProtocols</li> 537 * <li>allowedKeyManagement</li> 538 * <li>allowedAuthAlgorithms</li> 539 * <li>allowedPairwiseCiphers</li> 540 * <li>allowedGroupCiphers</li> 541 * </ul> 542 * @return a list of network configurations in the form of a list 543 * of {@link WifiConfiguration} objects. Upon failure to fetch or 544 * when when Wi-Fi is turned off, it can be null. 545 */ 546 public List<WifiConfiguration> getConfiguredNetworks() { 547 try { 548 return mService.getConfiguredNetworks(); 549 } catch (RemoteException e) { 550 return null; 551 } 552 } 553 554 /** 555 * Add a new network description to the set of configured networks. 556 * The {@code networkId} field of the supplied configuration object 557 * is ignored. 558 * <p/> 559 * The new network will be marked DISABLED by default. To enable it, 560 * called {@link #enableNetwork}. 561 * 562 * @param config the set of variables that describe the configuration, 563 * contained in a {@link WifiConfiguration} object. 564 * @return the ID of the newly created network description. This is used in 565 * other operations to specified the network to be acted upon. 566 * Returns {@code -1} on failure. 567 */ 568 public int addNetwork(WifiConfiguration config) { 569 if (config == null) { 570 return -1; 571 } 572 config.networkId = -1; 573 return addOrUpdateNetwork(config); 574 } 575 576 /** 577 * Update the network description of an existing configured network. 578 * 579 * @param config the set of variables that describe the configuration, 580 * contained in a {@link WifiConfiguration} object. It may 581 * be sparse, so that only the items that are being changed 582 * are non-<code>null</code>. The {@code networkId} field 583 * must be set to the ID of the existing network being updated. 584 * @return Returns the {@code networkId} of the supplied 585 * {@code WifiConfiguration} on success. 586 * <br/> 587 * Returns {@code -1} on failure, including when the {@code networkId} 588 * field of the {@code WifiConfiguration} does not refer to an 589 * existing network. 590 */ 591 public int updateNetwork(WifiConfiguration config) { 592 if (config == null || config.networkId < 0) { 593 return -1; 594 } 595 return addOrUpdateNetwork(config); 596 } 597 598 /** 599 * Internal method for doing the RPC that creates a new network description 600 * or updates an existing one. 601 * 602 * @param config The possibly sparse object containing the variables that 603 * are to set or updated in the network description. 604 * @return the ID of the network on success, {@code -1} on failure. 605 */ 606 private int addOrUpdateNetwork(WifiConfiguration config) { 607 try { 608 return mService.addOrUpdateNetwork(config); 609 } catch (RemoteException e) { 610 return -1; 611 } 612 } 613 614 /** 615 * Remove the specified network from the list of configured networks. 616 * This may result in the asynchronous delivery of state change 617 * events. 618 * @param netId the integer that identifies the network configuration 619 * to the supplicant 620 * @return {@code true} if the operation succeeded 621 */ 622 public boolean removeNetwork(int netId) { 623 try { 624 return mService.removeNetwork(netId); 625 } catch (RemoteException e) { 626 return false; 627 } 628 } 629 630 /** 631 * Allow a previously configured network to be associated with. If 632 * <code>disableOthers</code> is true, then all other configured 633 * networks are disabled, and an attempt to connect to the selected 634 * network is initiated. This may result in the asynchronous delivery 635 * of state change events. 636 * @param netId the ID of the network in the list of configured networks 637 * @param disableOthers if true, disable all other networks. The way to 638 * select a particular network to connect to is specify {@code true} 639 * for this parameter. 640 * @return {@code true} if the operation succeeded 641 */ 642 public boolean enableNetwork(int netId, boolean disableOthers) { 643 try { 644 return mService.enableNetwork(netId, disableOthers); 645 } catch (RemoteException e) { 646 return false; 647 } 648 } 649 650 /** 651 * Disable a configured network. The specified network will not be 652 * a candidate for associating. This may result in the asynchronous 653 * delivery of state change events. 654 * @param netId the ID of the network as returned by {@link #addNetwork}. 655 * @return {@code true} if the operation succeeded 656 */ 657 public boolean disableNetwork(int netId) { 658 try { 659 return mService.disableNetwork(netId); 660 } catch (RemoteException e) { 661 return false; 662 } 663 } 664 665 /** 666 * Disassociate from the currently active access point. This may result 667 * in the asynchronous delivery of state change events. 668 * @return {@code true} if the operation succeeded 669 */ 670 public boolean disconnect() { 671 try { 672 mService.disconnect(); 673 return true; 674 } catch (RemoteException e) { 675 return false; 676 } 677 } 678 679 /** 680 * Reconnect to the currently active access point, if we are currently 681 * disconnected. This may result in the asynchronous delivery of state 682 * change events. 683 * @return {@code true} if the operation succeeded 684 */ 685 public boolean reconnect() { 686 try { 687 mService.reconnect(); 688 return true; 689 } catch (RemoteException e) { 690 return false; 691 } 692 } 693 694 /** 695 * Reconnect to the currently active access point, even if we are already 696 * connected. This may result in the asynchronous delivery of state 697 * change events. 698 * @return {@code true} if the operation succeeded 699 */ 700 public boolean reassociate() { 701 try { 702 mService.reassociate(); 703 return true; 704 } catch (RemoteException e) { 705 return false; 706 } 707 } 708 709 /** 710 * Check that the supplicant daemon is responding to requests. 711 * @return {@code true} if we were able to communicate with the supplicant and 712 * it returned the expected response to the PING message. 713 */ 714 public boolean pingSupplicant() { 715 if (mService == null) 716 return false; 717 try { 718 return mService.pingSupplicant(); 719 } catch (RemoteException e) { 720 return false; 721 } 722 } 723 724 /** 725 * Request a scan for access points. Returns immediately. The availability 726 * of the results is made known later by means of an asynchronous event sent 727 * on completion of the scan. 728 * @return {@code true} if the operation succeeded, i.e., the scan was initiated 729 */ 730 public boolean startScan() { 731 try { 732 mService.startScan(false); 733 return true; 734 } catch (RemoteException e) { 735 return false; 736 } 737 } 738 739 /** 740 * Request a scan for access points. Returns immediately. The availability 741 * of the results is made known later by means of an asynchronous event sent 742 * on completion of the scan. 743 * This is a variant of startScan that forces an active scan, even if passive 744 * scans are the current default 745 * @return {@code true} if the operation succeeded, i.e., the scan was initiated 746 * 747 * @hide 748 */ 749 public boolean startScanActive() { 750 try { 751 mService.startScan(true); 752 return true; 753 } catch (RemoteException e) { 754 return false; 755 } 756 } 757 758 /** 759 * Return dynamic information about the current Wi-Fi connection, if any is active. 760 * @return the Wi-Fi information, contained in {@link WifiInfo}. 761 */ 762 public WifiInfo getConnectionInfo() { 763 try { 764 return mService.getConnectionInfo(); 765 } catch (RemoteException e) { 766 return null; 767 } 768 } 769 770 /** 771 * Return the results of the latest access point scan. 772 * @return the list of access points found in the most recent scan. 773 */ 774 public List<ScanResult> getScanResults() { 775 try { 776 return mService.getScanResults(); 777 } catch (RemoteException e) { 778 return null; 779 } 780 } 781 782 /** 783 * Tell the supplicant to persist the current list of configured networks. 784 * <p> 785 * Note: It is possible for this method to change the network IDs of 786 * existing networks. You should assume the network IDs can be different 787 * after calling this method. 788 * 789 * @return {@code true} if the operation succeeded 790 */ 791 public boolean saveConfiguration() { 792 try { 793 return mService.saveConfiguration(); 794 } catch (RemoteException e) { 795 return false; 796 } 797 } 798 799 /** 800 * Set the country code. 801 * @param countryCode country code in ISO 3166 format. 802 * @param persist {@code true} if this needs to be remembered 803 * 804 * @hide 805 */ 806 public void setCountryCode(String country, boolean persist) { 807 try { 808 mService.setCountryCode(country, persist); 809 } catch (RemoteException e) { } 810 } 811 812 /** 813 * Set the operational frequency band. 814 * @param band One of 815 * {@link #WIFI_FREQUENCY_BAND_AUTO}, 816 * {@link #WIFI_FREQUENCY_BAND_5GHZ}, 817 * {@link #WIFI_FREQUENCY_BAND_2GHZ}, 818 * @param persist {@code true} if this needs to be remembered 819 * @hide 820 */ 821 public void setFrequencyBand(int band, boolean persist) { 822 try { 823 mService.setFrequencyBand(band, persist); 824 } catch (RemoteException e) { } 825 } 826 827 /** 828 * Get the operational frequency band. 829 * @return One of 830 * {@link #WIFI_FREQUENCY_BAND_AUTO}, 831 * {@link #WIFI_FREQUENCY_BAND_5GHZ}, 832 * {@link #WIFI_FREQUENCY_BAND_2GHZ} or 833 * {@code -1} on failure. 834 * @hide 835 */ 836 public int getFrequencyBand() { 837 try { 838 return mService.getFrequencyBand(); 839 } catch (RemoteException e) { 840 return -1; 841 } 842 } 843 844 /** 845 * Check if the chipset supports dual frequency band (2.4 GHz and 5 GHz) 846 * @return {@code true} if supported, {@code false} otherwise. 847 * @hide 848 */ 849 public boolean isDualBandSupported() { 850 try { 851 return mService.isDualBandSupported(); 852 } catch (RemoteException e) { 853 return false; 854 } 855 } 856 857 /** 858 * Return the DHCP-assigned addresses from the last successful DHCP request, 859 * if any. 860 * @return the DHCP information 861 */ 862 public DhcpInfo getDhcpInfo() { 863 try { 864 return mService.getDhcpInfo(); 865 } catch (RemoteException e) { 866 return null; 867 } 868 } 869 870 871 /** 872 * Enable or disable Wi-Fi. 873 * @param enabled {@code true} to enable, {@code false} to disable. 874 * @return {@code true} if the operation succeeds (or if the existing state 875 * is the same as the requested state). 876 */ 877 public boolean setWifiEnabled(boolean enabled) { 878 try { 879 return mService.setWifiEnabled(enabled); 880 } catch (RemoteException e) { 881 return false; 882 } 883 } 884 885 /** 886 * Gets the Wi-Fi enabled state. 887 * @return One of {@link #WIFI_STATE_DISABLED}, 888 * {@link #WIFI_STATE_DISABLING}, {@link #WIFI_STATE_ENABLED}, 889 * {@link #WIFI_STATE_ENABLING}, {@link #WIFI_STATE_UNKNOWN} 890 * @see #isWifiEnabled() 891 */ 892 public int getWifiState() { 893 try { 894 return mService.getWifiEnabledState(); 895 } catch (RemoteException e) { 896 return WIFI_STATE_UNKNOWN; 897 } 898 } 899 900 /** 901 * Return whether Wi-Fi is enabled or disabled. 902 * @return {@code true} if Wi-Fi is enabled 903 * @see #getWifiState() 904 */ 905 public boolean isWifiEnabled() { 906 return getWifiState() == WIFI_STATE_ENABLED; 907 } 908 909 /** 910 * Return TX packet counter, for CTS test of WiFi watchdog. 911 * @param listener is the interface to receive result 912 * 913 * @hide for CTS test only 914 */ 915 public void getTxPacketCount(TxPacketCountListener listener) { 916 validateChannel(); 917 mAsyncChannel.sendMessage(RSSI_PKTCNT_FETCH, 0, putListener(listener)); 918 } 919 920 /** 921 * Calculates the level of the signal. This should be used any time a signal 922 * is being shown. 923 * 924 * @param rssi The power of the signal measured in RSSI. 925 * @param numLevels The number of levels to consider in the calculated 926 * level. 927 * @return A level of the signal, given in the range of 0 to numLevels-1 928 * (both inclusive). 929 */ 930 public static int calculateSignalLevel(int rssi, int numLevels) { 931 if (rssi <= MIN_RSSI) { 932 return 0; 933 } else if (rssi >= MAX_RSSI) { 934 return numLevels - 1; 935 } else { 936 float inputRange = (MAX_RSSI - MIN_RSSI); 937 float outputRange = (numLevels - 1); 938 return (int)((float)(rssi - MIN_RSSI) * outputRange / inputRange); 939 } 940 } 941 942 /** 943 * Compares two signal strengths. 944 * 945 * @param rssiA The power of the first signal measured in RSSI. 946 * @param rssiB The power of the second signal measured in RSSI. 947 * @return Returns <0 if the first signal is weaker than the second signal, 948 * 0 if the two signals have the same strength, and >0 if the first 949 * signal is stronger than the second signal. 950 */ 951 public static int compareSignalLevel(int rssiA, int rssiB) { 952 return rssiA - rssiB; 953 } 954 955 /** 956 * Start AccessPoint mode with the specified 957 * configuration. If the radio is already running in 958 * AP mode, update the new configuration 959 * Note that starting in access point mode disables station 960 * mode operation 961 * @param wifiConfig SSID, security and channel details as 962 * part of WifiConfiguration 963 * @return {@code true} if the operation succeeds, {@code false} otherwise 964 * 965 * @hide Dont open up yet 966 */ 967 public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) { 968 try { 969 mService.setWifiApEnabled(wifiConfig, enabled); 970 return true; 971 } catch (RemoteException e) { 972 return false; 973 } 974 } 975 976 /** 977 * Gets the Wi-Fi enabled state. 978 * @return One of {@link #WIFI_AP_STATE_DISABLED}, 979 * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED}, 980 * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED} 981 * @see #isWifiApEnabled() 982 * 983 * @hide Dont open yet 984 */ 985 public int getWifiApState() { 986 try { 987 return mService.getWifiApEnabledState(); 988 } catch (RemoteException e) { 989 return WIFI_AP_STATE_FAILED; 990 } 991 } 992 993 /** 994 * Return whether Wi-Fi AP is enabled or disabled. 995 * @return {@code true} if Wi-Fi AP is enabled 996 * @see #getWifiApState() 997 * 998 * @hide Dont open yet 999 */ 1000 public boolean isWifiApEnabled() { 1001 return getWifiApState() == WIFI_AP_STATE_ENABLED; 1002 } 1003 1004 /** 1005 * Gets the Wi-Fi AP Configuration. 1006 * @return AP details in WifiConfiguration 1007 * 1008 * @hide Dont open yet 1009 */ 1010 public WifiConfiguration getWifiApConfiguration() { 1011 try { 1012 return mService.getWifiApConfiguration(); 1013 } catch (RemoteException e) { 1014 return null; 1015 } 1016 } 1017 1018 /** 1019 * Sets the Wi-Fi AP Configuration. 1020 * @return {@code true} if the operation succeeded, {@code false} otherwise 1021 * 1022 * @hide Dont open yet 1023 */ 1024 public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) { 1025 try { 1026 mService.setWifiApConfiguration(wifiConfig); 1027 return true; 1028 } catch (RemoteException e) { 1029 return false; 1030 } 1031 } 1032 1033 /** 1034 * Start the driver and connect to network. 1035 * 1036 * This function will over-ride WifiLock and device idle status. For example, 1037 * even if the device is idle or there is only a scan-only lock held, 1038 * a start wifi would mean that wifi connection is kept active until 1039 * a stopWifi() is sent. 1040 * 1041 * This API is used by WifiStateTracker 1042 * 1043 * @return {@code true} if the operation succeeds else {@code false} 1044 * @hide 1045 */ 1046 public boolean startWifi() { 1047 try { 1048 mService.startWifi(); 1049 return true; 1050 } catch (RemoteException e) { 1051 return false; 1052 } 1053 } 1054 1055 /** 1056 * Disconnect from a network (if any) and stop the driver. 1057 * 1058 * This function will over-ride WifiLock and device idle status. Wi-Fi 1059 * stays inactive until a startWifi() is issued. 1060 * 1061 * This API is used by WifiStateTracker 1062 * 1063 * @return {@code true} if the operation succeeds else {@code false} 1064 * @hide 1065 */ 1066 public boolean stopWifi() { 1067 try { 1068 mService.stopWifi(); 1069 return true; 1070 } catch (RemoteException e) { 1071 return false; 1072 } 1073 } 1074 1075 /** 1076 * Add a bssid to the supplicant blacklist 1077 * 1078 * This API is used by WifiWatchdogService 1079 * 1080 * @return {@code true} if the operation succeeds else {@code false} 1081 * @hide 1082 */ 1083 public boolean addToBlacklist(String bssid) { 1084 try { 1085 mService.addToBlacklist(bssid); 1086 return true; 1087 } catch (RemoteException e) { 1088 return false; 1089 } 1090 } 1091 1092 /** 1093 * Clear the supplicant blacklist 1094 * 1095 * This API is used by WifiWatchdogService 1096 * 1097 * @return {@code true} if the operation succeeds else {@code false} 1098 * @hide 1099 */ 1100 public boolean clearBlacklist() { 1101 try { 1102 mService.clearBlacklist(); 1103 return true; 1104 } catch (RemoteException e) { 1105 return false; 1106 } 1107 } 1108 1109 /* TODO: deprecate synchronous API and open up the following API */ 1110 1111 private static final int BASE = Protocol.BASE_WIFI_MANAGER; 1112 1113 /* Commands to WifiService */ 1114 /** @hide */ 1115 public static final int CONNECT_NETWORK = BASE + 1; 1116 /** @hide */ 1117 public static final int CONNECT_NETWORK_FAILED = BASE + 2; 1118 /** @hide */ 1119 public static final int CONNECT_NETWORK_SUCCEEDED = BASE + 3; 1120 1121 /** @hide */ 1122 public static final int FORGET_NETWORK = BASE + 4; 1123 /** @hide */ 1124 public static final int FORGET_NETWORK_FAILED = BASE + 5; 1125 /** @hide */ 1126 public static final int FORGET_NETWORK_SUCCEEDED = BASE + 6; 1127 1128 /** @hide */ 1129 public static final int SAVE_NETWORK = BASE + 7; 1130 /** @hide */ 1131 public static final int SAVE_NETWORK_FAILED = BASE + 8; 1132 /** @hide */ 1133 public static final int SAVE_NETWORK_SUCCEEDED = BASE + 9; 1134 1135 /** @hide */ 1136 public static final int START_WPS = BASE + 10; 1137 /** @hide */ 1138 public static final int START_WPS_SUCCEEDED = BASE + 11; 1139 /** @hide */ 1140 public static final int WPS_FAILED = BASE + 12; 1141 /** @hide */ 1142 public static final int WPS_COMPLETED = BASE + 13; 1143 1144 /** @hide */ 1145 public static final int CANCEL_WPS = BASE + 14; 1146 /** @hide */ 1147 public static final int CANCEL_WPS_FAILED = BASE + 15; 1148 /** @hide */ 1149 public static final int CANCEL_WPS_SUCCEDED = BASE + 16; 1150 1151 /** @hide */ 1152 public static final int DISABLE_NETWORK = BASE + 17; 1153 /** @hide */ 1154 public static final int DISABLE_NETWORK_FAILED = BASE + 18; 1155 /** @hide */ 1156 public static final int DISABLE_NETWORK_SUCCEEDED = BASE + 19; 1157 1158 /** @hide */ 1159 public static final int RSSI_PKTCNT_FETCH = BASE + 20; 1160 /** @hide */ 1161 public static final int RSSI_PKTCNT_FETCH_SUCCEEDED = BASE + 21; 1162 /** @hide */ 1163 public static final int RSSI_PKTCNT_FETCH_FAILED = BASE + 22; 1164 1165 /* For system use only */ 1166 /** @hide */ 1167 public static final int ENABLE_TRAFFIC_STATS_POLL = BASE + 31; 1168 /** @hide */ 1169 public static final int TRAFFIC_STATS_POLL = BASE + 32; 1170 1171 1172 /** 1173 * Passed with {@link ActionListener#onFailure}. 1174 * Indicates that the operation failed due to an internal error. 1175 * @hide 1176 */ 1177 public static final int ERROR = 0; 1178 1179 /** 1180 * Passed with {@link ActionListener#onFailure}. 1181 * Indicates that the operation is already in progress 1182 * @hide 1183 */ 1184 public static final int IN_PROGRESS = 1; 1185 1186 /** 1187 * Passed with {@link ActionListener#onFailure}. 1188 * Indicates that the operation failed because the framework is busy and 1189 * unable to service the request 1190 * @hide 1191 */ 1192 public static final int BUSY = 2; 1193 1194 /* WPS specific errors */ 1195 /** WPS overlap detected {@hide} */ 1196 public static final int WPS_OVERLAP_ERROR = 3; 1197 /** WEP on WPS is prohibited {@hide} */ 1198 public static final int WPS_WEP_PROHIBITED = 4; 1199 /** TKIP only prohibited {@hide} */ 1200 public static final int WPS_TKIP_ONLY_PROHIBITED = 5; 1201 /** Authentication failure on WPS {@hide} */ 1202 public static final int WPS_AUTH_FAILURE = 6; 1203 /** WPS timed out {@hide} */ 1204 public static final int WPS_TIMED_OUT = 7; 1205 1206 /** Interface for callback invocation on an application action {@hide} */ 1207 public interface ActionListener { 1208 /** The operation succeeded */ 1209 public void onSuccess(); 1210 /** 1211 * The operation failed 1212 * @param reason The reason for failure could be one of 1213 * {@link #ERROR}, {@link #IN_PROGRESS} or {@link #BUSY} 1214 */ 1215 public void onFailure(int reason); 1216 } 1217 1218 /** Interface for callback invocation on a start WPS action {@hide} */ 1219 public interface WpsListener { 1220 /** WPS start succeeded */ 1221 public void onStartSuccess(String pin); 1222 1223 /** WPS operation completed succesfully */ 1224 public void onCompletion(); 1225 1226 /** 1227 * WPS operation failed 1228 * @param reason The reason for failure could be one of 1229 * {@link #IN_PROGRESS}, {@link #WPS_OVERLAP_ERROR},{@link #ERROR} or {@link #BUSY} 1230 */ 1231 public void onFailure(int reason); 1232 } 1233 1234 /** Interface for callback invocation on a TX packet count poll action {@hide} */ 1235 public interface TxPacketCountListener { 1236 /** 1237 * The operation succeeded 1238 * @param count TX packet counter 1239 */ 1240 public void onSuccess(int count); 1241 /** 1242 * The operation failed 1243 * @param reason The reason for failure could be one of 1244 * {@link #ERROR}, {@link #IN_PROGRESS} or {@link #BUSY} 1245 */ 1246 public void onFailure(int reason); 1247 } 1248 1249 private class ServiceHandler extends Handler { 1250 ServiceHandler(Looper looper) { 1251 super(looper); 1252 } 1253 1254 @Override 1255 public void handleMessage(Message message) { 1256 Object listener = removeListener(message.arg2); 1257 switch (message.what) { 1258 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: 1259 if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 1260 mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); 1261 } else { 1262 Log.e(TAG, "Failed to set up channel connection"); 1263 // This will cause all further async API calls on the WifiManager 1264 // to fail and throw an exception 1265 mAsyncChannel = null; 1266 } 1267 mConnected.countDown(); 1268 break; 1269 case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED: 1270 // Ignore 1271 break; 1272 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: 1273 Log.e(TAG, "Channel connection lost"); 1274 // This will cause all further async API calls on the WifiManager 1275 // to fail and throw an exception 1276 mAsyncChannel = null; 1277 break; 1278 /* ActionListeners grouped together */ 1279 case WifiManager.CONNECT_NETWORK_FAILED: 1280 case WifiManager.FORGET_NETWORK_FAILED: 1281 case WifiManager.SAVE_NETWORK_FAILED: 1282 case WifiManager.CANCEL_WPS_FAILED: 1283 case WifiManager.DISABLE_NETWORK_FAILED: 1284 if (listener != null) { 1285 ((ActionListener) listener).onFailure(message.arg1); 1286 } 1287 break; 1288 /* ActionListeners grouped together */ 1289 case WifiManager.CONNECT_NETWORK_SUCCEEDED: 1290 case WifiManager.FORGET_NETWORK_SUCCEEDED: 1291 case WifiManager.SAVE_NETWORK_SUCCEEDED: 1292 case WifiManager.CANCEL_WPS_SUCCEDED: 1293 case WifiManager.DISABLE_NETWORK_SUCCEEDED: 1294 if (listener != null) { 1295 ((ActionListener) listener).onSuccess(); 1296 } 1297 break; 1298 case WifiManager.START_WPS_SUCCEEDED: 1299 if (listener != null) { 1300 WpsResult result = (WpsResult) message.obj; 1301 ((WpsListener) listener).onStartSuccess(result.pin); 1302 //Listener needs to stay until completion or failure 1303 synchronized(mListenerMapLock) { 1304 mListenerMap.put(message.arg2, listener); 1305 } 1306 } 1307 break; 1308 case WifiManager.WPS_COMPLETED: 1309 if (listener != null) { 1310 ((WpsListener) listener).onCompletion(); 1311 } 1312 break; 1313 case WifiManager.WPS_FAILED: 1314 if (listener != null) { 1315 ((WpsListener) listener).onFailure(message.arg1); 1316 } 1317 break; 1318 case WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED: 1319 if (listener != null) { 1320 RssiPacketCountInfo info = (RssiPacketCountInfo) message.obj; 1321 if (info != null) 1322 ((TxPacketCountListener) listener).onSuccess(info.txgood + info.txbad); 1323 else 1324 ((TxPacketCountListener) listener).onFailure(ERROR); 1325 } 1326 break; 1327 case WifiManager.RSSI_PKTCNT_FETCH_FAILED: 1328 if (listener != null) { 1329 ((TxPacketCountListener) listener).onFailure(message.arg1); 1330 } 1331 break; 1332 default: 1333 //ignore 1334 break; 1335 } 1336 } 1337 } 1338 1339 private int putListener(Object listener) { 1340 if (listener == null) return INVALID_KEY; 1341 int key; 1342 synchronized (mListenerMapLock) { 1343 do { 1344 key = mListenerKey++; 1345 } while (key == INVALID_KEY); 1346 mListenerMap.put(key, listener); 1347 } 1348 return key; 1349 } 1350 1351 private Object removeListener(int key) { 1352 if (key == INVALID_KEY) return null; 1353 synchronized (mListenerMapLock) { 1354 Object listener = mListenerMap.get(key); 1355 mListenerMap.remove(key); 1356 return listener; 1357 } 1358 } 1359 1360 private void init() { 1361 mWifiServiceMessenger = getWifiServiceMessenger(); 1362 if (mWifiServiceMessenger == null) { 1363 mAsyncChannel = null; 1364 return; 1365 } 1366 1367 HandlerThread t = new HandlerThread("WifiManager"); 1368 t.start(); 1369 mHandler = new ServiceHandler(t.getLooper()); 1370 mAsyncChannel.connect(mContext, mHandler, mWifiServiceMessenger); 1371 try { 1372 mConnected.await(); 1373 } catch (InterruptedException e) { 1374 Log.e(TAG, "interrupted wait at init"); 1375 } 1376 } 1377 1378 private void validateChannel() { 1379 if (mAsyncChannel == null) throw new IllegalStateException( 1380 "No permission to access and change wifi or a bad initialization"); 1381 } 1382 1383 /** 1384 * Connect to a network with the given configuration. The network also 1385 * gets added to the supplicant configuration. 1386 * 1387 * For a new network, this function is used instead of a 1388 * sequence of addNetwork(), enableNetwork(), saveConfiguration() and 1389 * reconnect() 1390 * 1391 * @param config the set of variables that describe the configuration, 1392 * contained in a {@link WifiConfiguration} object. 1393 * @param listener for callbacks on success or failure. Can be null. 1394 * @throws IllegalStateException if the WifiManager instance needs to be 1395 * initialized again 1396 * 1397 * @hide 1398 */ 1399 public void connect(WifiConfiguration config, ActionListener listener) { 1400 if (config == null) throw new IllegalArgumentException("config cannot be null"); 1401 validateChannel(); 1402 // Use INVALID_NETWORK_ID for arg1 when passing a config object 1403 // arg1 is used to pass network id when the network already exists 1404 mAsyncChannel.sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID, 1405 putListener(listener), config); 1406 } 1407 1408 /** 1409 * Connect to a network with the given networkId. 1410 * 1411 * This function is used instead of a enableNetwork(), saveConfiguration() and 1412 * reconnect() 1413 * 1414 * @param networkId the network id identifiying the network in the 1415 * supplicant configuration list 1416 * @param listener for callbacks on success or failure. Can be null. 1417 * @throws IllegalStateException if the WifiManager instance needs to be 1418 * initialized again 1419 * @hide 1420 */ 1421 public void connect(int networkId, ActionListener listener) { 1422 if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative"); 1423 validateChannel(); 1424 mAsyncChannel.sendMessage(CONNECT_NETWORK, networkId, putListener(listener)); 1425 } 1426 1427 /** 1428 * Save the given network in the supplicant config. If the network already 1429 * exists, the configuration is updated. A new network is enabled 1430 * by default. 1431 * 1432 * For a new network, this function is used instead of a 1433 * sequence of addNetwork(), enableNetwork() and saveConfiguration(). 1434 * 1435 * For an existing network, it accomplishes the task of updateNetwork() 1436 * and saveConfiguration() 1437 * 1438 * @param config the set of variables that describe the configuration, 1439 * contained in a {@link WifiConfiguration} object. 1440 * @param listener for callbacks on success or failure. Can be null. 1441 * @throws IllegalStateException if the WifiManager instance needs to be 1442 * initialized again 1443 * @hide 1444 */ 1445 public void save(WifiConfiguration config, ActionListener listener) { 1446 if (config == null) throw new IllegalArgumentException("config cannot be null"); 1447 validateChannel(); 1448 mAsyncChannel.sendMessage(SAVE_NETWORK, 0, putListener(listener), config); 1449 } 1450 1451 /** 1452 * Delete the network in the supplicant config. 1453 * 1454 * This function is used instead of a sequence of removeNetwork() 1455 * and saveConfiguration(). 1456 * 1457 * @param config the set of variables that describe the configuration, 1458 * contained in a {@link WifiConfiguration} object. 1459 * @param listener for callbacks on success or failure. Can be null. 1460 * @throws IllegalStateException if the WifiManager instance needs to be 1461 * initialized again 1462 * @hide 1463 */ 1464 public void forget(int netId, ActionListener listener) { 1465 if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative"); 1466 validateChannel(); 1467 mAsyncChannel.sendMessage(FORGET_NETWORK, netId, putListener(listener)); 1468 } 1469 1470 /** 1471 * Disable network 1472 * 1473 * @param netId is the network Id 1474 * @param listener for callbacks on success or failure. Can be null. 1475 * @throws IllegalStateException if the WifiManager instance needs to be 1476 * initialized again 1477 * @hide 1478 */ 1479 public void disable(int netId, ActionListener listener) { 1480 if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative"); 1481 validateChannel(); 1482 mAsyncChannel.sendMessage(DISABLE_NETWORK, netId, putListener(listener)); 1483 } 1484 1485 /** 1486 * Start Wi-fi Protected Setup 1487 * 1488 * @param config WPS configuration 1489 * @param listener for callbacks on success or failure. Can be null. 1490 * @throws IllegalStateException if the WifiManager instance needs to be 1491 * initialized again 1492 * @hide 1493 */ 1494 public void startWps(WpsInfo config, WpsListener listener) { 1495 if (config == null) throw new IllegalArgumentException("config cannot be null"); 1496 validateChannel(); 1497 mAsyncChannel.sendMessage(START_WPS, 0, putListener(listener), config); 1498 } 1499 1500 /** 1501 * Cancel any ongoing Wi-fi Protected Setup 1502 * 1503 * @param listener for callbacks on success or failure. Can be null. 1504 * @throws IllegalStateException if the WifiManager instance needs to be 1505 * initialized again 1506 * @hide 1507 */ 1508 public void cancelWps(ActionListener listener) { 1509 validateChannel(); 1510 mAsyncChannel.sendMessage(CANCEL_WPS, 0, putListener(listener)); 1511 } 1512 1513 /** 1514 * Get a reference to WifiService handler. This is used by a client to establish 1515 * an AsyncChannel communication with WifiService 1516 * 1517 * @return Messenger pointing to the WifiService handler 1518 * @hide 1519 */ 1520 public Messenger getWifiServiceMessenger() { 1521 try { 1522 return mService.getWifiServiceMessenger(); 1523 } catch (RemoteException e) { 1524 return null; 1525 } catch (SecurityException e) { 1526 return null; 1527 } 1528 } 1529 1530 /** 1531 * Get a reference to WifiStateMachine handler. 1532 * @return Messenger pointing to the WifiService handler 1533 * @hide 1534 */ 1535 public Messenger getWifiStateMachineMessenger() { 1536 try { 1537 return mService.getWifiStateMachineMessenger(); 1538 } catch (RemoteException e) { 1539 return null; 1540 } 1541 } 1542 1543 /** 1544 * Returns the file in which IP and proxy configuration data is stored 1545 * @hide 1546 */ 1547 public String getConfigFile() { 1548 try { 1549 return mService.getConfigFile(); 1550 } catch (RemoteException e) { 1551 return null; 1552 } 1553 } 1554 1555 /** 1556 * Allows an application to keep the Wi-Fi radio awake. 1557 * Normally the Wi-Fi radio may turn off when the user has not used the device in a while. 1558 * Acquiring a WifiLock will keep the radio on until the lock is released. Multiple 1559 * applications may hold WifiLocks, and the radio will only be allowed to turn off when no 1560 * WifiLocks are held in any application. 1561 * <p> 1562 * Before using a WifiLock, consider carefully if your application requires Wi-Fi access, or 1563 * could function over a mobile network, if available. A program that needs to download large 1564 * files should hold a WifiLock to ensure that the download will complete, but a program whose 1565 * network usage is occasional or low-bandwidth should not hold a WifiLock to avoid adversely 1566 * affecting battery life. 1567 * <p> 1568 * Note that WifiLocks cannot override the user-level "Wi-Fi Enabled" setting, nor Airplane 1569 * Mode. They simply keep the radio from turning off when Wi-Fi is already on but the device 1570 * is idle. 1571 * <p> 1572 * Any application using a WifiLock must request the {@code android.permission.WAKE_LOCK} 1573 * permission in an {@code <uses-permission>} element of the application's manifest. 1574 */ 1575 public class WifiLock { 1576 private String mTag; 1577 private final IBinder mBinder; 1578 private int mRefCount; 1579 int mLockType; 1580 private boolean mRefCounted; 1581 private boolean mHeld; 1582 private WorkSource mWorkSource; 1583 1584 private WifiLock(int lockType, String tag) { 1585 mTag = tag; 1586 mLockType = lockType; 1587 mBinder = new Binder(); 1588 mRefCount = 0; 1589 mRefCounted = true; 1590 mHeld = false; 1591 } 1592 1593 /** 1594 * Locks the Wi-Fi radio on until {@link #release} is called. 1595 * 1596 * If this WifiLock is reference-counted, each call to {@code acquire} will increment the 1597 * reference count, and the radio will remain locked as long as the reference count is 1598 * above zero. 1599 * 1600 * If this WifiLock is not reference-counted, the first call to {@code acquire} will lock 1601 * the radio, but subsequent calls will be ignored. Only one call to {@link #release} 1602 * will be required, regardless of the number of times that {@code acquire} is called. 1603 */ 1604 public void acquire() { 1605 synchronized (mBinder) { 1606 if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) { 1607 try { 1608 mService.acquireWifiLock(mBinder, mLockType, mTag, mWorkSource); 1609 synchronized (WifiManager.this) { 1610 if (mActiveLockCount >= MAX_ACTIVE_LOCKS) { 1611 mService.releaseWifiLock(mBinder); 1612 throw new UnsupportedOperationException( 1613 "Exceeded maximum number of wifi locks"); 1614 } 1615 mActiveLockCount++; 1616 } 1617 } catch (RemoteException ignore) { 1618 } 1619 mHeld = true; 1620 } 1621 } 1622 } 1623 1624 /** 1625 * Unlocks the Wi-Fi radio, allowing it to turn off when the device is idle. 1626 * 1627 * If this WifiLock is reference-counted, each call to {@code release} will decrement the 1628 * reference count, and the radio will be unlocked only when the reference count reaches 1629 * zero. If the reference count goes below zero (that is, if {@code release} is called 1630 * a greater number of times than {@link #acquire}), an exception is thrown. 1631 * 1632 * If this WifiLock is not reference-counted, the first call to {@code release} (after 1633 * the radio was locked using {@link #acquire}) will unlock the radio, and subsequent 1634 * calls will be ignored. 1635 */ 1636 public void release() { 1637 synchronized (mBinder) { 1638 if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { 1639 try { 1640 mService.releaseWifiLock(mBinder); 1641 synchronized (WifiManager.this) { 1642 mActiveLockCount--; 1643 } 1644 } catch (RemoteException ignore) { 1645 } 1646 mHeld = false; 1647 } 1648 if (mRefCount < 0) { 1649 throw new RuntimeException("WifiLock under-locked " + mTag); 1650 } 1651 } 1652 } 1653 1654 /** 1655 * Controls whether this is a reference-counted or non-reference-counted WifiLock. 1656 * 1657 * Reference-counted WifiLocks keep track of the number of calls to {@link #acquire} and 1658 * {@link #release}, and only allow the radio to sleep when every call to {@link #acquire} 1659 * has been balanced with a call to {@link #release}. Non-reference-counted WifiLocks 1660 * lock the radio whenever {@link #acquire} is called and it is unlocked, and unlock the 1661 * radio whenever {@link #release} is called and it is locked. 1662 * 1663 * @param refCounted true if this WifiLock should keep a reference count 1664 */ 1665 public void setReferenceCounted(boolean refCounted) { 1666 mRefCounted = refCounted; 1667 } 1668 1669 /** 1670 * Checks whether this WifiLock is currently held. 1671 * 1672 * @return true if this WifiLock is held, false otherwise 1673 */ 1674 public boolean isHeld() { 1675 synchronized (mBinder) { 1676 return mHeld; 1677 } 1678 } 1679 1680 public void setWorkSource(WorkSource ws) { 1681 synchronized (mBinder) { 1682 if (ws != null && ws.size() == 0) { 1683 ws = null; 1684 } 1685 boolean changed = true; 1686 if (ws == null) { 1687 mWorkSource = null; 1688 } else if (mWorkSource == null) { 1689 changed = mWorkSource != null; 1690 mWorkSource = new WorkSource(ws); 1691 } else { 1692 changed = mWorkSource.diff(ws); 1693 if (changed) { 1694 mWorkSource.set(ws); 1695 } 1696 } 1697 if (changed && mHeld) { 1698 try { 1699 mService.updateWifiLockWorkSource(mBinder, mWorkSource); 1700 } catch (RemoteException e) { 1701 } 1702 } 1703 } 1704 } 1705 1706 public String toString() { 1707 String s1, s2, s3; 1708 synchronized (mBinder) { 1709 s1 = Integer.toHexString(System.identityHashCode(this)); 1710 s2 = mHeld ? "held; " : ""; 1711 if (mRefCounted) { 1712 s3 = "refcounted: refcount = " + mRefCount; 1713 } else { 1714 s3 = "not refcounted"; 1715 } 1716 return "WifiLock{ " + s1 + "; " + s2 + s3 + " }"; 1717 } 1718 } 1719 1720 @Override 1721 protected void finalize() throws Throwable { 1722 super.finalize(); 1723 synchronized (mBinder) { 1724 if (mHeld) { 1725 try { 1726 mService.releaseWifiLock(mBinder); 1727 synchronized (WifiManager.this) { 1728 mActiveLockCount--; 1729 } 1730 } catch (RemoteException ignore) { 1731 } 1732 } 1733 } 1734 } 1735 } 1736 1737 /** 1738 * Creates a new WifiLock. 1739 * 1740 * @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL}, 1741 * {@link #WIFI_MODE_FULL_HIGH_PERF} and {@link #WIFI_MODE_SCAN_ONLY} for 1742 * descriptions of the types of Wi-Fi locks. 1743 * @param tag a tag for the WifiLock to identify it in debugging messages. This string is 1744 * never shown to the user under normal conditions, but should be descriptive 1745 * enough to identify your application and the specific WifiLock within it, if it 1746 * holds multiple WifiLocks. 1747 * 1748 * @return a new, unacquired WifiLock with the given tag. 1749 * 1750 * @see WifiLock 1751 */ 1752 public WifiLock createWifiLock(int lockType, String tag) { 1753 return new WifiLock(lockType, tag); 1754 } 1755 1756 /** 1757 * Creates a new WifiLock. 1758 * 1759 * @param tag a tag for the WifiLock to identify it in debugging messages. This string is 1760 * never shown to the user under normal conditions, but should be descriptive 1761 * enough to identify your application and the specific WifiLock within it, if it 1762 * holds multiple WifiLocks. 1763 * 1764 * @return a new, unacquired WifiLock with the given tag. 1765 * 1766 * @see WifiLock 1767 */ 1768 public WifiLock createWifiLock(String tag) { 1769 return new WifiLock(WIFI_MODE_FULL, tag); 1770 } 1771 1772 1773 /** 1774 * Create a new MulticastLock 1775 * 1776 * @param tag a tag for the MulticastLock to identify it in debugging 1777 * messages. This string is never shown to the user under 1778 * normal conditions, but should be descriptive enough to 1779 * identify your application and the specific MulticastLock 1780 * within it, if it holds multiple MulticastLocks. 1781 * 1782 * @return a new, unacquired MulticastLock with the given tag. 1783 * 1784 * @see MulticastLock 1785 */ 1786 public MulticastLock createMulticastLock(String tag) { 1787 return new MulticastLock(tag); 1788 } 1789 1790 /** 1791 * Allows an application to receive Wifi Multicast packets. 1792 * Normally the Wifi stack filters out packets not explicitly 1793 * addressed to this device. Acquring a MulticastLock will 1794 * cause the stack to receive packets addressed to multicast 1795 * addresses. Processing these extra packets can cause a noticable 1796 * battery drain and should be disabled when not needed. 1797 */ 1798 public class MulticastLock { 1799 private String mTag; 1800 private final IBinder mBinder; 1801 private int mRefCount; 1802 private boolean mRefCounted; 1803 private boolean mHeld; 1804 1805 private MulticastLock(String tag) { 1806 mTag = tag; 1807 mBinder = new Binder(); 1808 mRefCount = 0; 1809 mRefCounted = true; 1810 mHeld = false; 1811 } 1812 1813 /** 1814 * Locks Wifi Multicast on until {@link #release} is called. 1815 * 1816 * If this MulticastLock is reference-counted each call to 1817 * {@code acquire} will increment the reference count, and the 1818 * wifi interface will receive multicast packets as long as the 1819 * reference count is above zero. 1820 * 1821 * If this MulticastLock is not reference-counted, the first call to 1822 * {@code acquire} will turn on the multicast packets, but subsequent 1823 * calls will be ignored. Only one call to {@link #release} will 1824 * be required, regardless of the number of times that {@code acquire} 1825 * is called. 1826 * 1827 * Note that other applications may also lock Wifi Multicast on. 1828 * Only they can relinquish their lock. 1829 * 1830 * Also note that applications cannot leave Multicast locked on. 1831 * When an app exits or crashes, any Multicast locks will be released. 1832 */ 1833 public void acquire() { 1834 synchronized (mBinder) { 1835 if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) { 1836 try { 1837 mService.acquireMulticastLock(mBinder, mTag); 1838 synchronized (WifiManager.this) { 1839 if (mActiveLockCount >= MAX_ACTIVE_LOCKS) { 1840 mService.releaseMulticastLock(); 1841 throw new UnsupportedOperationException( 1842 "Exceeded maximum number of wifi locks"); 1843 } 1844 mActiveLockCount++; 1845 } 1846 } catch (RemoteException ignore) { 1847 } 1848 mHeld = true; 1849 } 1850 } 1851 } 1852 1853 /** 1854 * Unlocks Wifi Multicast, restoring the filter of packets 1855 * not addressed specifically to this device and saving power. 1856 * 1857 * If this MulticastLock is reference-counted, each call to 1858 * {@code release} will decrement the reference count, and the 1859 * multicast packets will only stop being received when the reference 1860 * count reaches zero. If the reference count goes below zero (that 1861 * is, if {@code release} is called a greater number of times than 1862 * {@link #acquire}), an exception is thrown. 1863 * 1864 * If this MulticastLock is not reference-counted, the first call to 1865 * {@code release} (after the radio was multicast locked using 1866 * {@link #acquire}) will unlock the multicast, and subsequent calls 1867 * will be ignored. 1868 * 1869 * Note that if any other Wifi Multicast Locks are still outstanding 1870 * this {@code release} call will not have an immediate effect. Only 1871 * when all applications have released all their Multicast Locks will 1872 * the Multicast filter be turned back on. 1873 * 1874 * Also note that when an app exits or crashes all of its Multicast 1875 * Locks will be automatically released. 1876 */ 1877 public void release() { 1878 synchronized (mBinder) { 1879 if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { 1880 try { 1881 mService.releaseMulticastLock(); 1882 synchronized (WifiManager.this) { 1883 mActiveLockCount--; 1884 } 1885 } catch (RemoteException ignore) { 1886 } 1887 mHeld = false; 1888 } 1889 if (mRefCount < 0) { 1890 throw new RuntimeException("MulticastLock under-locked " 1891 + mTag); 1892 } 1893 } 1894 } 1895 1896 /** 1897 * Controls whether this is a reference-counted or non-reference- 1898 * counted MulticastLock. 1899 * 1900 * Reference-counted MulticastLocks keep track of the number of calls 1901 * to {@link #acquire} and {@link #release}, and only stop the 1902 * reception of multicast packets when every call to {@link #acquire} 1903 * has been balanced with a call to {@link #release}. Non-reference- 1904 * counted MulticastLocks allow the reception of multicast packets 1905 * whenever {@link #acquire} is called and stop accepting multicast 1906 * packets whenever {@link #release} is called. 1907 * 1908 * @param refCounted true if this MulticastLock should keep a reference 1909 * count 1910 */ 1911 public void setReferenceCounted(boolean refCounted) { 1912 mRefCounted = refCounted; 1913 } 1914 1915 /** 1916 * Checks whether this MulticastLock is currently held. 1917 * 1918 * @return true if this MulticastLock is held, false otherwise 1919 */ 1920 public boolean isHeld() { 1921 synchronized (mBinder) { 1922 return mHeld; 1923 } 1924 } 1925 1926 public String toString() { 1927 String s1, s2, s3; 1928 synchronized (mBinder) { 1929 s1 = Integer.toHexString(System.identityHashCode(this)); 1930 s2 = mHeld ? "held; " : ""; 1931 if (mRefCounted) { 1932 s3 = "refcounted: refcount = " + mRefCount; 1933 } else { 1934 s3 = "not refcounted"; 1935 } 1936 return "MulticastLock{ " + s1 + "; " + s2 + s3 + " }"; 1937 } 1938 } 1939 1940 @Override 1941 protected void finalize() throws Throwable { 1942 super.finalize(); 1943 setReferenceCounted(false); 1944 release(); 1945 } 1946 } 1947 1948 /** 1949 * Check multicast filter status. 1950 * 1951 * @return true if multicast packets are allowed. 1952 * 1953 * @hide pending API council approval 1954 */ 1955 public boolean isMulticastEnabled() { 1956 try { 1957 return mService.isMulticastEnabled(); 1958 } catch (RemoteException e) { 1959 return false; 1960 } 1961 } 1962 1963 /** 1964 * Initialize the multicast filtering to 'on' 1965 * @hide no intent to publish 1966 */ 1967 public boolean initializeMulticastFiltering() { 1968 try { 1969 mService.initializeMulticastFiltering(); 1970 return true; 1971 } catch (RemoteException e) { 1972 return false; 1973 } 1974 } 1975 1976 /** @hide */ 1977 public void captivePortalCheckComplete() { 1978 try { 1979 mService.captivePortalCheckComplete(); 1980 } catch (RemoteException e) {} 1981 } 1982} 1983