WifiManager.java revision 4c0d81b8add0372cc7194b17cc6d2bfc58baacd1
1/* 2 * Copyright (C) 2008 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.annotation.SdkConstant; 20import android.annotation.SdkConstant.SdkConstantType; 21import android.net.DhcpInfo; 22import android.os.Binder; 23import android.os.IBinder; 24import android.os.Handler; 25import android.os.RemoteException; 26 27import java.util.List; 28 29/** 30 * This class provides the primary API for managing all aspects of Wi-Fi 31 * connectivity. Get an instance of this class by calling 32 * {@link android.content.Context#getSystemService(String) Context.getSystemService(Context.WIFI_SERVICE)}. 33 34 * It deals with several categories of items: 35 * <ul> 36 * <li>The list of configured networks. The list can be viewed and updated, 37 * and attributes of individual entries can be modified.</li> 38 * <li>The currently active Wi-Fi network, if any. Connectivity can be 39 * established or torn down, and dynamic information about the state of 40 * the network can be queried.</li> 41 * <li>Results of access point scans, containing enough information to 42 * make decisions about what access point to connect to.</li> 43 * <li>It defines the names of various Intent actions that are broadcast 44 * upon any sort of change in Wi-Fi state. 45 * </ul> 46 * This is the API to use when performing Wi-Fi specific operations. To 47 * perform operations that pertain to network connectivity at an abstract 48 * level, use {@link android.net.ConnectivityManager}. 49 */ 50public class WifiManager { 51 52 // Supplicant error codes: 53 /** 54 * The error code if there was a problem authenticating. 55 */ 56 public static final int ERROR_AUTHENTICATING = 1; 57 58 /** 59 * Broadcast intent action indicating that Wi-Fi has been enabled, disabled, 60 * enabling, disabling, or unknown. One extra provides this state as an int. 61 * Another extra provides the previous state, if available. 62 * 63 * @see #EXTRA_WIFI_STATE 64 * @see #EXTRA_PREVIOUS_WIFI_STATE 65 */ 66 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 67 public static final String WIFI_STATE_CHANGED_ACTION = 68 "android.net.wifi.WIFI_STATE_CHANGED"; 69 /** 70 * The lookup key for an int that indicates whether Wi-Fi is enabled, 71 * disabled, enabling, disabling, or unknown. Retrieve it with 72 * {@link android.content.Intent#getIntExtra(String,int)}. 73 * 74 * @see #WIFI_STATE_DISABLED 75 * @see #WIFI_STATE_DISABLING 76 * @see #WIFI_STATE_ENABLED 77 * @see #WIFI_STATE_ENABLING 78 * @see #WIFI_STATE_UNKNOWN 79 */ 80 public static final String EXTRA_WIFI_STATE = "wifi_state"; 81 /** 82 * The previous Wi-Fi state. 83 * 84 * @see #EXTRA_WIFI_STATE 85 */ 86 public static final String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state"; 87 88 /** 89 * Wi-Fi is currently being disabled. The state will change to {@link #WIFI_STATE_DISABLED} if 90 * it finishes successfully. 91 * 92 * @see #WIFI_STATE_CHANGED_ACTION 93 * @see #getWifiState() 94 */ 95 public static final int WIFI_STATE_DISABLING = 0; 96 /** 97 * Wi-Fi is disabled. 98 * 99 * @see #WIFI_STATE_CHANGED_ACTION 100 * @see #getWifiState() 101 */ 102 public static final int WIFI_STATE_DISABLED = 1; 103 /** 104 * Wi-Fi is currently being enabled. The state will change to {@link #WIFI_STATE_ENABLED} if 105 * it finishes successfully. 106 * 107 * @see #WIFI_STATE_CHANGED_ACTION 108 * @see #getWifiState() 109 */ 110 public static final int WIFI_STATE_ENABLING = 2; 111 /** 112 * Wi-Fi is enabled. 113 * 114 * @see #WIFI_STATE_CHANGED_ACTION 115 * @see #getWifiState() 116 */ 117 public static final int WIFI_STATE_ENABLED = 3; 118 /** 119 * Wi-Fi is in an unknown state. This state will occur when an error happens while enabling 120 * or disabling. 121 * 122 * @see #WIFI_STATE_CHANGED_ACTION 123 * @see #getWifiState() 124 */ 125 public static final int WIFI_STATE_UNKNOWN = 4; 126 127 /** 128 * Broadcast intent action indicating that Wi-Fi AP has been enabled, disabled, 129 * enabling, disabling, or failed. 130 * 131 * @hide 132 */ 133 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 134 public static final String WIFI_AP_STATE_CHANGED_ACTION = 135 "android.net.wifi.WIFI_AP_STATE_CHANGED"; 136 137 /** 138 * The lookup key for an int that indicates whether Wi-Fi AP is enabled, 139 * disabled, enabling, disabling, or failed. Retrieve it with 140 * {@link android.content.Intent#getIntExtra(String,int)}. 141 * 142 * @see #WIFI_AP_STATE_DISABLED 143 * @see #WIFI_AP_STATE_DISABLING 144 * @see #WIFI_AP_STATE_ENABLED 145 * @see #WIFI_AP_STATE_ENABLING 146 * @see #WIFI_AP_STATE_FAILED 147 * 148 * @hide 149 */ 150 public static final String EXTRA_WIFI_AP_STATE = "wifi_state"; 151 /** 152 * The previous Wi-Fi state. 153 * 154 * @see #EXTRA_WIFI_AP_STATE 155 * 156 * @hide 157 */ 158 public static final String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state"; 159 /** 160 * Wi-Fi AP is currently being disabled. The state will change to 161 * {@link #WIFI_AP_STATE_DISABLED} if it finishes successfully. 162 * 163 * @see #WIFI_AP_STATE_CHANGED_ACTION 164 * @see #getWifiApState() 165 * 166 * @hide 167 */ 168 public static final int WIFI_AP_STATE_DISABLING = 10; 169 /** 170 * Wi-Fi AP is disabled. 171 * 172 * @see #WIFI_AP_STATE_CHANGED_ACTION 173 * @see #getWifiState() 174 * 175 * @hide 176 */ 177 public static final int WIFI_AP_STATE_DISABLED = 11; 178 /** 179 * Wi-Fi AP is currently being enabled. The state will change to 180 * {@link #WIFI_AP_STATE_ENABLED} if it finishes successfully. 181 * 182 * @see #WIFI_AP_STATE_CHANGED_ACTION 183 * @see #getWifiApState() 184 * 185 * @hide 186 */ 187 public static final int WIFI_AP_STATE_ENABLING = 12; 188 /** 189 * Wi-Fi AP is enabled. 190 * 191 * @see #WIFI_AP_STATE_CHANGED_ACTION 192 * @see #getWifiApState() 193 * 194 * @hide 195 */ 196 public static final int WIFI_AP_STATE_ENABLED = 13; 197 /** 198 * Wi-Fi AP is in a failed state. This state will occur when an error occurs during 199 * enabling or disabling 200 * 201 * @see #WIFI_AP_STATE_CHANGED_ACTION 202 * @see #getWifiApState() 203 * 204 * @hide 205 */ 206 public static final int WIFI_AP_STATE_FAILED = 14; 207 208 /** 209 * Broadcast intent action indicating that a connection to the supplicant has 210 * been established (and it is now possible 211 * to perform Wi-Fi operations) or the connection to the supplicant has been 212 * lost. One extra provides the connection state as a boolean, where {@code true} 213 * means CONNECTED. 214 * @see #EXTRA_SUPPLICANT_CONNECTED 215 */ 216 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 217 public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION = 218 "android.net.wifi.supplicant.CONNECTION_CHANGE"; 219 /** 220 * The lookup key for a boolean that indicates whether a connection to 221 * the supplicant daemon has been gained or lost. {@code true} means 222 * a connection now exists. 223 * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}. 224 */ 225 public static final String EXTRA_SUPPLICANT_CONNECTED = "connected"; 226 /** 227 * Broadcast intent action indicating that the state of Wi-Fi connectivity 228 * has changed. One extra provides the new state 229 * in the form of a {@link android.net.NetworkInfo} object. If the new state is 230 * CONNECTED, a second extra may provide the BSSID of the access point, 231 * as a {@code String}. 232 * @see #EXTRA_NETWORK_INFO 233 * @see #EXTRA_BSSID 234 */ 235 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 236 public static final String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE"; 237 /** 238 * The lookup key for a {@link android.net.NetworkInfo} object associated with the 239 * Wi-Fi network. Retrieve with 240 * {@link android.content.Intent#getParcelableExtra(String)}. 241 */ 242 public static final String EXTRA_NETWORK_INFO = "networkInfo"; 243 /** 244 * The lookup key for a String giving the BSSID of the access point to which 245 * we are connected. Only present when the new state is CONNECTED. 246 * Retrieve with 247 * {@link android.content.Intent#getStringExtra(String)}. 248 */ 249 public static final String EXTRA_BSSID = "bssid"; 250 /** 251 * Broadcast intent action indicating that the state of establishing a connection to 252 * an access point has changed.One extra provides the new 253 * {@link SupplicantState}. Note that the supplicant state is Wi-Fi specific, and 254 * is not generally the most useful thing to look at if you are just interested in 255 * the overall state of connectivity. 256 * @see #EXTRA_NEW_STATE 257 * @see #EXTRA_SUPPLICANT_ERROR 258 */ 259 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 260 public static final String SUPPLICANT_STATE_CHANGED_ACTION = 261 "android.net.wifi.supplicant.STATE_CHANGE"; 262 /** 263 * The lookup key for a {@link SupplicantState} describing the new state 264 * Retrieve with 265 * {@link android.content.Intent#getParcelableExtra(String)}. 266 */ 267 public static final String EXTRA_NEW_STATE = "newState"; 268 269 /** 270 * The lookup key for a {@link SupplicantState} describing the supplicant 271 * error code if any 272 * Retrieve with 273 * {@link android.content.Intent#getIntExtra(String, int)}. 274 * @see #ERROR_AUTHENTICATING 275 */ 276 public static final String EXTRA_SUPPLICANT_ERROR = "supplicantError"; 277 /** 278 * Broadcast intent action indicating that the supplicant configuration changed. 279 * This can be as a result of adding/updating/deleting a network 280 * @hide 281 */ 282 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 283 public static final String SUPPLICANT_CONFIG_CHANGED_ACTION = 284 "android.net.wifi.supplicant.CONFIG_CHANGE"; 285 /** 286 * An access point scan has completed, and results are available from the supplicant. 287 * Call {@link #getScanResults()} to obtain the results. 288 */ 289 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 290 public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS"; 291 /** 292 * The RSSI (signal strength) has changed. 293 * @see #EXTRA_NEW_RSSI 294 */ 295 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 296 public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED"; 297 /** 298 * The lookup key for an {@code int} giving the new RSSI in dBm. 299 */ 300 public static final String EXTRA_NEW_RSSI = "newRssi"; 301 302 /** 303 * Broadcast intent action indicating that the IP configuration 304 * changed on wifi. 305 * @hide 306 */ 307 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 308 public static final String CONFIG_CHANGED_ACTION = "android.net.wifi.CONFIG_CHANGED"; 309 /** 310 * The lookup key for a {@link android.net.NetworkProperties} object associated with the 311 * Wi-Fi network. Retrieve with 312 * {@link android.content.Intent#getParcelableExtra(String)}. 313 * @hide 314 */ 315 public static final String EXTRA_NETWORK_PROPERTIES = "networkProperties"; 316 317 /** 318 * The network IDs of the configured networks could have changed. 319 */ 320 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 321 public static final String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED"; 322 323 /** 324 * Activity Action: Pick a Wi-Fi network to connect to. 325 * <p>Input: Nothing. 326 * <p>Output: Nothing. 327 */ 328 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 329 public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK"; 330 331 /** 332 * In this Wi-Fi lock mode, Wi-Fi will be kept active, 333 * and will behave normally, i.e., it will attempt to automatically 334 * establish a connection to a remembered access point that is 335 * within range, and will do periodic scans if there are remembered 336 * access points but none are in range. 337 */ 338 public static final int WIFI_MODE_FULL = 1; 339 /** 340 * In this Wi-Fi lock mode, Wi-Fi will be kept active, 341 * but the only operation that will be supported is initiation of 342 * scans, and the subsequent reporting of scan results. No attempts 343 * will be made to automatically connect to remembered access points, 344 * nor will periodic scans be automatically performed looking for 345 * remembered access points. Scans must be explicitly requested by 346 * an application in this mode. 347 */ 348 public static final int WIFI_MODE_SCAN_ONLY = 2; 349 350 /** Anything worse than or equal to this will show 0 bars. */ 351 private static final int MIN_RSSI = -100; 352 353 /** Anything better than or equal to this will show the max bars. */ 354 private static final int MAX_RSSI = -55; 355 356 IWifiManager mService; 357 Handler mHandler; 358 359 /* Maximum number of active locks we allow. 360 * This limit was added to prevent apps from creating a ridiculous number 361 * of locks and crashing the system by overflowing the global ref table. 362 */ 363 private static final int MAX_ACTIVE_LOCKS = 50; 364 365 /* Number of currently active WifiLocks and MulticastLocks */ 366 private int mActiveLockCount; 367 368 /** 369 * Create a new WifiManager instance. 370 * Applications will almost always want to use 371 * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve 372 * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}. 373 * @param service the Binder interface 374 * @param handler target for messages 375 * @hide - hide this because it takes in a parameter of type IWifiManager, which 376 * is a system private class. 377 */ 378 public WifiManager(IWifiManager service, Handler handler) { 379 mService = service; 380 mHandler = handler; 381 } 382 383 /** 384 * Return a list of all the networks configured in the supplicant. 385 * Not all fields of WifiConfiguration are returned. Only the following 386 * fields are filled in: 387 * <ul> 388 * <li>networkId</li> 389 * <li>SSID</li> 390 * <li>BSSID</li> 391 * <li>priority</li> 392 * <li>allowedProtocols</li> 393 * <li>allowedKeyManagement</li> 394 * <li>allowedAuthAlgorithms</li> 395 * <li>allowedPairwiseCiphers</li> 396 * <li>allowedGroupCiphers</li> 397 * </ul> 398 * @return a list of network configurations in the form of a list 399 * of {@link WifiConfiguration} objects. 400 */ 401 public List<WifiConfiguration> getConfiguredNetworks() { 402 try { 403 return mService.getConfiguredNetworks(); 404 } catch (RemoteException e) { 405 return null; 406 } 407 } 408 409 /** 410 * Add a new network description to the set of configured networks. 411 * The {@code networkId} field of the supplied configuration object 412 * is ignored. 413 * <p/> 414 * The new network will be marked DISABLED by default. To enable it, 415 * called {@link #enableNetwork}. 416 * 417 * @param config the set of variables that describe the configuration, 418 * contained in a {@link WifiConfiguration} object. 419 * @return the ID of the newly created network description. This is used in 420 * other operations to specified the network to be acted upon. 421 * Returns {@code -1} on failure. 422 */ 423 public int addNetwork(WifiConfiguration config) { 424 if (config == null) { 425 return -1; 426 } 427 config.networkId = -1; 428 return addOrUpdateNetwork(config); 429 } 430 431 /** 432 * Update the network description of an existing configured network. 433 * 434 * @param config the set of variables that describe the configuration, 435 * contained in a {@link WifiConfiguration} object. It may 436 * be sparse, so that only the items that are being changed 437 * are non-<code>null</code>. The {@code networkId} field 438 * must be set to the ID of the existing network being updated. 439 * @return Returns the {@code networkId} of the supplied 440 * {@code WifiConfiguration} on success. 441 * <br/> 442 * Returns {@code -1} on failure, including when the {@code networkId} 443 * field of the {@code WifiConfiguration} does not refer to an 444 * existing network. 445 */ 446 public int updateNetwork(WifiConfiguration config) { 447 if (config == null || config.networkId < 0) { 448 return -1; 449 } 450 return addOrUpdateNetwork(config); 451 } 452 453 /** 454 * Internal method for doing the RPC that creates a new network description 455 * or updates an existing one. 456 * 457 * @param config The possibly sparse object containing the variables that 458 * are to set or updated in the network description. 459 * @return the ID of the network on success, {@code -1} on failure. 460 */ 461 private int addOrUpdateNetwork(WifiConfiguration config) { 462 try { 463 return mService.addOrUpdateNetwork(config); 464 } catch (RemoteException e) { 465 return -1; 466 } 467 } 468 469 /** 470 * Remove the specified network from the list of configured networks. 471 * This may result in the asynchronous delivery of state change 472 * events. 473 * @param netId the integer that identifies the network configuration 474 * to the supplicant 475 * @return {@code true} if the operation succeeded 476 */ 477 public boolean removeNetwork(int netId) { 478 try { 479 return mService.removeNetwork(netId); 480 } catch (RemoteException e) { 481 return false; 482 } 483 } 484 485 /** 486 * Allow a previously configured network to be associated with. If 487 * <code>disableOthers</code> is true, then all other configured 488 * networks are disabled, and an attempt to connect to the selected 489 * network is initiated. This may result in the asynchronous delivery 490 * of state change events. 491 * @param netId the ID of the network in the list of configured networks 492 * @param disableOthers if true, disable all other networks. The way to 493 * select a particular network to connect to is specify {@code true} 494 * for this parameter. 495 * @return {@code true} if the operation succeeded 496 */ 497 public boolean enableNetwork(int netId, boolean disableOthers) { 498 try { 499 return mService.enableNetwork(netId, disableOthers); 500 } catch (RemoteException e) { 501 return false; 502 } 503 } 504 505 /** 506 * Disable a configured network. The specified network will not be 507 * a candidate for associating. This may result in the asynchronous 508 * delivery of state change events. 509 * @param netId the ID of the network as returned by {@link #addNetwork}. 510 * @return {@code true} if the operation succeeded 511 */ 512 public boolean disableNetwork(int netId) { 513 try { 514 return mService.disableNetwork(netId); 515 } catch (RemoteException e) { 516 return false; 517 } 518 } 519 520 /** 521 * Disassociate from the currently active access point. This may result 522 * in the asynchronous delivery of state change events. 523 * @return {@code true} if the operation succeeded 524 */ 525 public boolean disconnect() { 526 try { 527 return mService.disconnect(); 528 } catch (RemoteException e) { 529 return false; 530 } 531 } 532 533 /** 534 * Reconnect to the currently active access point, if we are currently 535 * disconnected. This may result in the asynchronous delivery of state 536 * change events. 537 * @return {@code true} if the operation succeeded 538 */ 539 public boolean reconnect() { 540 try { 541 return mService.reconnect(); 542 } catch (RemoteException e) { 543 return false; 544 } 545 } 546 547 /** 548 * Reconnect to the currently active access point, even if we are already 549 * connected. This may result in the asynchronous delivery of state 550 * change events. 551 * @return {@code true} if the operation succeeded 552 */ 553 public boolean reassociate() { 554 try { 555 return mService.reassociate(); 556 } catch (RemoteException e) { 557 return false; 558 } 559 } 560 561 /** 562 * Check that the supplicant daemon is responding to requests. 563 * @return {@code true} if we were able to communicate with the supplicant and 564 * it returned the expected response to the PING message. 565 */ 566 public boolean pingSupplicant() { 567 if (mService == null) 568 return false; 569 try { 570 return mService.pingSupplicant(); 571 } catch (RemoteException e) { 572 return false; 573 } 574 } 575 576 /** 577 * Request a scan for access points. Returns immediately. The availability 578 * of the results is made known later by means of an asynchronous event sent 579 * on completion of the scan. 580 * @return {@code true} if the operation succeeded, i.e., the scan was initiated 581 */ 582 public boolean startScan() { 583 try { 584 return mService.startScan(false); 585 } catch (RemoteException e) { 586 return false; 587 } 588 } 589 590 /** 591 * Request a scan for access points. Returns immediately. The availability 592 * of the results is made known later by means of an asynchronous event sent 593 * on completion of the scan. 594 * This is a variant of startScan that forces an active scan, even if passive 595 * scans are the current default 596 * @return {@code true} if the operation succeeded, i.e., the scan was initiated 597 * 598 * @hide 599 */ 600 public boolean startScanActive() { 601 try { 602 return mService.startScan(true); 603 } catch (RemoteException e) { 604 return false; 605 } 606 } 607 608 /** 609 * Return dynamic information about the current Wi-Fi connection, if any is active. 610 * @return the Wi-Fi information, contained in {@link WifiInfo}. 611 */ 612 public WifiInfo getConnectionInfo() { 613 try { 614 return mService.getConnectionInfo(); 615 } catch (RemoteException e) { 616 return null; 617 } 618 } 619 620 /** 621 * Return the results of the latest access point scan. 622 * @return the list of access points found in the most recent scan. 623 */ 624 public List<ScanResult> getScanResults() { 625 try { 626 return mService.getScanResults(); 627 } catch (RemoteException e) { 628 return null; 629 } 630 } 631 632 /** 633 * Tell the supplicant to persist the current list of configured networks. 634 * <p> 635 * Note: It is possible for this method to change the network IDs of 636 * existing networks. You should assume the network IDs can be different 637 * after calling this method. 638 * 639 * @return {@code true} if the operation succeeded 640 */ 641 public boolean saveConfiguration() { 642 try { 643 return mService.saveConfiguration(); 644 } catch (RemoteException e) { 645 return false; 646 } 647 } 648 649 /** 650 * Return the number of frequency channels that are allowed 651 * to be used in the current regulatory domain. 652 * @return the number of allowed channels, or {@code -1} if an error occurs 653 * 654 * @hide pending API council 655 */ 656 public int getNumAllowedChannels() { 657 try { 658 return mService.getNumAllowedChannels(); 659 } catch (RemoteException e) { 660 return -1; 661 } 662 } 663 664 /** 665 * Set the number of frequency channels that are allowed to be used 666 * in the current regulatory domain. This method should be used only 667 * if the correct number of channels cannot be determined automatically 668 * for some reason. 669 * @param numChannels the number of allowed channels. Must be greater than 0 670 * and less than or equal to 16. 671 * @param persist {@code true} if you want this remembered 672 * @return {@code true} if the operation succeeds, {@code false} otherwise, e.g., 673 * {@code numChannels} is out of range. 674 * 675 * @hide pending API council 676 */ 677 public boolean setNumAllowedChannels(int numChannels, boolean persist) { 678 try { 679 return mService.setNumAllowedChannels(numChannels, persist); 680 } catch (RemoteException e) { 681 return false; 682 } 683 } 684 685 /** 686 * Return the list of valid values for the number of allowed radio channels 687 * for various regulatory domains. 688 * @return the list of channel counts, or {@code null} if the operation fails 689 * 690 * @hide pending API council review 691 */ 692 public int[] getValidChannelCounts() { 693 try { 694 return mService.getValidChannelCounts(); 695 } catch (RemoteException e) { 696 return null; 697 } 698 } 699 700 /** 701 * Return the DHCP-assigned addresses from the last successful DHCP request, 702 * if any. 703 * @return the DHCP information 704 */ 705 public DhcpInfo getDhcpInfo() { 706 try { 707 return mService.getDhcpInfo(); 708 } catch (RemoteException e) { 709 return null; 710 } 711 } 712 713 714 /** 715 * Enable or disable Wi-Fi. 716 * @param enabled {@code true} to enable, {@code false} to disable. 717 * @return {@code true} if the operation succeeds (or if the existing state 718 * is the same as the requested state). 719 */ 720 public boolean setWifiEnabled(boolean enabled) { 721 try { 722 return mService.setWifiEnabled(enabled); 723 } catch (RemoteException e) { 724 return false; 725 } 726 } 727 728 /** 729 * Gets the Wi-Fi enabled state. 730 * @return One of {@link #WIFI_STATE_DISABLED}, 731 * {@link #WIFI_STATE_DISABLING}, {@link #WIFI_STATE_ENABLED}, 732 * {@link #WIFI_STATE_ENABLING}, {@link #WIFI_STATE_UNKNOWN} 733 * @see #isWifiEnabled() 734 */ 735 public int getWifiState() { 736 try { 737 return mService.getWifiEnabledState(); 738 } catch (RemoteException e) { 739 return WIFI_STATE_UNKNOWN; 740 } 741 } 742 743 /** 744 * Return whether Wi-Fi is enabled or disabled. 745 * @return {@code true} if Wi-Fi is enabled 746 * @see #getWifiState() 747 */ 748 public boolean isWifiEnabled() { 749 return getWifiState() == WIFI_STATE_ENABLED; 750 } 751 752 /** 753 * Calculates the level of the signal. This should be used any time a signal 754 * is being shown. 755 * 756 * @param rssi The power of the signal measured in RSSI. 757 * @param numLevels The number of levels to consider in the calculated 758 * level. 759 * @return A level of the signal, given in the range of 0 to numLevels-1 760 * (both inclusive). 761 */ 762 public static int calculateSignalLevel(int rssi, int numLevels) { 763 if (rssi <= MIN_RSSI) { 764 return 0; 765 } else if (rssi >= MAX_RSSI) { 766 return numLevels - 1; 767 } else { 768 float inputRange = (MAX_RSSI - MIN_RSSI); 769 float outputRange = (numLevels - 1); 770 return (int)((float)(rssi - MIN_RSSI) * outputRange / inputRange); 771 } 772 } 773 774 /** 775 * Compares two signal strengths. 776 * 777 * @param rssiA The power of the first signal measured in RSSI. 778 * @param rssiB The power of the second signal measured in RSSI. 779 * @return Returns <0 if the first signal is weaker than the second signal, 780 * 0 if the two signals have the same strength, and >0 if the first 781 * signal is stronger than the second signal. 782 */ 783 public static int compareSignalLevel(int rssiA, int rssiB) { 784 return rssiA - rssiB; 785 } 786 787 /** 788 * Start AccessPoint mode with the specified 789 * configuration. If the radio is already running in 790 * AP mode, update the new configuration 791 * Note that starting in access point mode disables station 792 * mode operation 793 * @param wifiConfig SSID, security and channel details as 794 * part of WifiConfiguration 795 * @return {@code true} if the operation succeeds, {@code false} otherwise 796 * 797 * @hide Dont open up yet 798 */ 799 public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) { 800 try { 801 return mService.setWifiApEnabled(wifiConfig, enabled); 802 } catch (RemoteException e) { 803 return false; 804 } 805 } 806 807 /** 808 * Gets the Wi-Fi enabled state. 809 * @return One of {@link #WIFI_AP_STATE_DISABLED}, 810 * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED}, 811 * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED} 812 * @see #isWifiApEnabled() 813 * 814 * @hide Dont open yet 815 */ 816 public int getWifiApState() { 817 try { 818 return mService.getWifiApEnabledState(); 819 } catch (RemoteException e) { 820 return WIFI_AP_STATE_FAILED; 821 } 822 } 823 824 /** 825 * Return whether Wi-Fi AP is enabled or disabled. 826 * @return {@code true} if Wi-Fi AP is enabled 827 * @see #getWifiApState() 828 * 829 * @hide Dont open yet 830 */ 831 public boolean isWifiApEnabled() { 832 return getWifiApState() == WIFI_AP_STATE_ENABLED; 833 } 834 835 /** 836 * Gets the Wi-Fi AP Configuration. 837 * @return AP details in WifiConfiguration 838 * 839 * @hide Dont open yet 840 */ 841 public WifiConfiguration getWifiApConfiguration() { 842 try { 843 return mService.getWifiApConfiguration(); 844 } catch (RemoteException e) { 845 return null; 846 } 847 } 848 849 /** 850 * Sets the Wi-Fi AP Configuration. 851 * @return {@code true} if the operation succeeded, {@code false} otherwise 852 * 853 * @hide Dont open yet 854 */ 855 public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) { 856 try { 857 mService.setWifiApConfiguration(wifiConfig); 858 return true; 859 } catch (RemoteException e) { 860 return false; 861 } 862 } 863 864 /** 865 * Start the driver and connect to network. 866 * 867 * This function will over-ride WifiLock and device idle status. For example, 868 * even if the device is idle or there is only a scan-only lock held, 869 * a start wifi would mean that wifi connection is kept active until 870 * a stopWifi() is sent. 871 * 872 * This API is used by WifiStateTracker 873 * 874 * @return {@code true} if the operation succeeds else {@code false} 875 * @hide 876 */ 877 public boolean startWifi() { 878 try { 879 mService.startWifi(); 880 return true; 881 } catch (RemoteException e) { 882 return false; 883 } 884 } 885 886 /** 887 * Disconnect from a network (if any) and stop the driver. 888 * 889 * This function will over-ride WifiLock and device idle status. Wi-Fi 890 * stays inactive until a startWifi() is issued. 891 * 892 * This API is used by WifiStateTracker 893 * 894 * @return {@code true} if the operation succeeds else {@code false} 895 * @hide 896 */ 897 public boolean stopWifi() { 898 try { 899 mService.stopWifi(); 900 return true; 901 } catch (RemoteException e) { 902 return false; 903 } 904 } 905 906 /** 907 * Add a bssid to the supplicant blacklist 908 * 909 * This API is used by WifiWatchdogService 910 * 911 * @return {@code true} if the operation succeeds else {@code false} 912 * @hide 913 */ 914 public boolean addToBlacklist(String bssid) { 915 try { 916 mService.addToBlacklist(bssid); 917 return true; 918 } catch (RemoteException e) { 919 return false; 920 } 921 } 922 923 /** 924 * Clear the supplicant blacklist 925 * 926 * This API is used by WifiWatchdogService 927 * 928 * @return {@code true} if the operation succeeds else {@code false} 929 * @hide 930 */ 931 public boolean clearBlacklist() { 932 try { 933 mService.clearBlacklist(); 934 return true; 935 } catch (RemoteException e) { 936 return false; 937 } 938 } 939 940 /* TODO: deprecate synchronous API and open up the following API */ 941 /** 942 * Connect to a network with the given configuration. The network also 943 * gets added to the supplicant configuration. 944 * 945 * For a new network, this function is used instead of a 946 * sequence of addNetwork(), enableNetwork(), saveConfiguration() and 947 * reconnect() 948 * 949 * @param config the set of variables that describe the configuration, 950 * contained in a {@link WifiConfiguration} object. 951 * @hide 952 */ 953 public void connectNetwork(WifiConfiguration config) { 954 if (config == null) { 955 return; 956 } 957 try { 958 mService.connectNetworkWithConfig(config); 959 } catch (RemoteException e) { } 960 } 961 962 /** 963 * Connect to a network with the given networkId. 964 * 965 * This function is used instead of a enableNetwork(), saveConfiguration() and 966 * reconnect() 967 * 968 * @param networkId the network id identifiying the network in the 969 * supplicant configuration list 970 * @hide 971 */ 972 public void connectNetwork(int networkId) { 973 if (networkId < 0) { 974 return; 975 } 976 try { 977 mService.connectNetworkWithId(networkId); 978 } catch (RemoteException e) { } 979 } 980 981 /** 982 * Save the given network in the supplicant config. If the network already 983 * exists, the configuration is updated. A new network is enabled 984 * by default. 985 * 986 * For a new network, this function is used instead of a 987 * sequence of addNetwork(), enableNetwork() and saveConfiguration(). 988 * 989 * For an existing network, it accomplishes the task of updateNetwork() 990 * and saveConfiguration() 991 * 992 * @param config the set of variables that describe the configuration, 993 * contained in a {@link WifiConfiguration} object. 994 * @hide 995 */ 996 public void saveNetwork(WifiConfiguration config) { 997 if (config == null) { 998 return; 999 } 1000 try { 1001 mService.saveNetwork(config); 1002 } catch (RemoteException e) { } 1003 } 1004 1005 /** 1006 * Delete the network in the supplicant config. 1007 * 1008 * This function is used instead of a sequence of removeNetwork() 1009 * and saveConfiguration(). 1010 * 1011 * @param config the set of variables that describe the configuration, 1012 * contained in a {@link WifiConfiguration} object. 1013 * @hide 1014 */ 1015 public void forgetNetwork(int netId) { 1016 if (netId < 0) { 1017 return; 1018 } 1019 try { 1020 mService.forgetNetwork(netId); 1021 } catch (RemoteException e) { } 1022 } 1023 1024 /** 1025 * Allows an application to keep the Wi-Fi radio awake. 1026 * Normally the Wi-Fi radio may turn off when the user has not used the device in a while. 1027 * Acquiring a WifiLock will keep the radio on until the lock is released. Multiple 1028 * applications may hold WifiLocks, and the radio will only be allowed to turn off when no 1029 * WifiLocks are held in any application. 1030 * 1031 * Before using a WifiLock, consider carefully if your application requires Wi-Fi access, or 1032 * could function over a mobile network, if available. A program that needs to download large 1033 * files should hold a WifiLock to ensure that the download will complete, but a program whose 1034 * network usage is occasional or low-bandwidth should not hold a WifiLock to avoid adversely 1035 * affecting battery life. 1036 * 1037 * Note that WifiLocks cannot override the user-level "Wi-Fi Enabled" setting, nor Airplane 1038 * Mode. They simply keep the radio from turning off when Wi-Fi is already on but the device 1039 * is idle. 1040 */ 1041 public class WifiLock { 1042 private String mTag; 1043 private final IBinder mBinder; 1044 private int mRefCount; 1045 int mLockType; 1046 private boolean mRefCounted; 1047 private boolean mHeld; 1048 1049 private WifiLock(int lockType, String tag) { 1050 mTag = tag; 1051 mLockType = lockType; 1052 mBinder = new Binder(); 1053 mRefCount = 0; 1054 mRefCounted = true; 1055 mHeld = false; 1056 } 1057 1058 /** 1059 * Locks the Wi-Fi radio on until {@link #release} is called. 1060 * 1061 * If this WifiLock is reference-counted, each call to {@code acquire} will increment the 1062 * reference count, and the radio will remain locked as long as the reference count is 1063 * above zero. 1064 * 1065 * If this WifiLock is not reference-counted, the first call to {@code acquire} will lock 1066 * the radio, but subsequent calls will be ignored. Only one call to {@link #release} 1067 * will be required, regardless of the number of times that {@code acquire} is called. 1068 */ 1069 public void acquire() { 1070 synchronized (mBinder) { 1071 if (mRefCounted ? (++mRefCount > 0) : (!mHeld)) { 1072 try { 1073 mService.acquireWifiLock(mBinder, mLockType, mTag); 1074 synchronized (WifiManager.this) { 1075 if (mActiveLockCount >= MAX_ACTIVE_LOCKS) { 1076 mService.releaseWifiLock(mBinder); 1077 throw new UnsupportedOperationException( 1078 "Exceeded maximum number of wifi locks"); 1079 } 1080 mActiveLockCount++; 1081 } 1082 } catch (RemoteException ignore) { 1083 } 1084 mHeld = true; 1085 } 1086 } 1087 } 1088 1089 /** 1090 * Unlocks the Wi-Fi radio, allowing it to turn off when the device is idle. 1091 * 1092 * If this WifiLock is reference-counted, each call to {@code release} will decrement the 1093 * reference count, and the radio will be unlocked only when the reference count reaches 1094 * zero. If the reference count goes below zero (that is, if {@code release} is called 1095 * a greater number of times than {@link #acquire}), an exception is thrown. 1096 * 1097 * If this WifiLock is not reference-counted, the first call to {@code release} (after 1098 * the radio was locked using {@link #acquire}) will unlock the radio, and subsequent 1099 * calls will be ignored. 1100 */ 1101 public void release() { 1102 synchronized (mBinder) { 1103 if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { 1104 try { 1105 mService.releaseWifiLock(mBinder); 1106 synchronized (WifiManager.this) { 1107 mActiveLockCount--; 1108 } 1109 } catch (RemoteException ignore) { 1110 } 1111 mHeld = false; 1112 } 1113 if (mRefCount < 0) { 1114 throw new RuntimeException("WifiLock under-locked " + mTag); 1115 } 1116 } 1117 } 1118 1119 /** 1120 * Controls whether this is a reference-counted or non-reference-counted WifiLock. 1121 * 1122 * Reference-counted WifiLocks keep track of the number of calls to {@link #acquire} and 1123 * {@link #release}, and only allow the radio to sleep when every call to {@link #acquire} 1124 * has been balanced with a call to {@link #release}. Non-reference-counted WifiLocks 1125 * lock the radio whenever {@link #acquire} is called and it is unlocked, and unlock the 1126 * radio whenever {@link #release} is called and it is locked. 1127 * 1128 * @param refCounted true if this WifiLock should keep a reference count 1129 */ 1130 public void setReferenceCounted(boolean refCounted) { 1131 mRefCounted = refCounted; 1132 } 1133 1134 /** 1135 * Checks whether this WifiLock is currently held. 1136 * 1137 * @return true if this WifiLock is held, false otherwise 1138 */ 1139 public boolean isHeld() { 1140 synchronized (mBinder) { 1141 return mHeld; 1142 } 1143 } 1144 1145 public String toString() { 1146 String s1, s2, s3; 1147 synchronized (mBinder) { 1148 s1 = Integer.toHexString(System.identityHashCode(this)); 1149 s2 = mHeld ? "held; " : ""; 1150 if (mRefCounted) { 1151 s3 = "refcounted: refcount = " + mRefCount; 1152 } else { 1153 s3 = "not refcounted"; 1154 } 1155 return "WifiLock{ " + s1 + "; " + s2 + s3 + " }"; 1156 } 1157 } 1158 1159 @Override 1160 protected void finalize() throws Throwable { 1161 super.finalize(); 1162 synchronized (mBinder) { 1163 if (mHeld) { 1164 try { 1165 mService.releaseWifiLock(mBinder); 1166 synchronized (WifiManager.this) { 1167 mActiveLockCount--; 1168 } 1169 } catch (RemoteException ignore) { 1170 } 1171 } 1172 } 1173 } 1174 } 1175 1176 /** 1177 * Creates a new WifiLock. 1178 * 1179 * @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL} and 1180 * {@link #WIFI_MODE_SCAN_ONLY} for descriptions of the types of Wi-Fi locks. 1181 * @param tag a tag for the WifiLock to identify it in debugging messages. This string is 1182 * never shown to the user under normal conditions, but should be descriptive 1183 * enough to identify your application and the specific WifiLock within it, if it 1184 * holds multiple WifiLocks. 1185 * 1186 * @return a new, unacquired WifiLock with the given tag. 1187 * 1188 * @see WifiLock 1189 */ 1190 public WifiLock createWifiLock(int lockType, String tag) { 1191 return new WifiLock(lockType, tag); 1192 } 1193 1194 /** 1195 * Creates a new WifiLock. 1196 * 1197 * @param tag a tag for the WifiLock to identify it in debugging messages. This string is 1198 * never shown to the user under normal conditions, but should be descriptive 1199 * enough to identify your application and the specific WifiLock within it, if it 1200 * holds multiple WifiLocks. 1201 * 1202 * @return a new, unacquired WifiLock with the given tag. 1203 * 1204 * @see WifiLock 1205 */ 1206 public WifiLock createWifiLock(String tag) { 1207 return new WifiLock(WIFI_MODE_FULL, tag); 1208 } 1209 1210 1211 /** 1212 * Create a new MulticastLock 1213 * 1214 * @param tag a tag for the MulticastLock to identify it in debugging 1215 * messages. This string is never shown to the user under 1216 * normal conditions, but should be descriptive enough to 1217 * identify your application and the specific MulticastLock 1218 * within it, if it holds multiple MulticastLocks. 1219 * 1220 * @return a new, unacquired MulticastLock with the given tag. 1221 * 1222 * @see MulticastLock 1223 */ 1224 public MulticastLock createMulticastLock(String tag) { 1225 return new MulticastLock(tag); 1226 } 1227 1228 /** 1229 * Allows an application to receive Wifi Multicast packets. 1230 * Normally the Wifi stack filters out packets not explicitly 1231 * addressed to this device. Acquring a MulticastLock will 1232 * cause the stack to receive packets addressed to multicast 1233 * addresses. Processing these extra packets can cause a noticable 1234 * battery drain and should be disabled when not needed. 1235 */ 1236 public class MulticastLock { 1237 private String mTag; 1238 private final IBinder mBinder; 1239 private int mRefCount; 1240 private boolean mRefCounted; 1241 private boolean mHeld; 1242 1243 private MulticastLock(String tag) { 1244 mTag = tag; 1245 mBinder = new Binder(); 1246 mRefCount = 0; 1247 mRefCounted = true; 1248 mHeld = false; 1249 } 1250 1251 /** 1252 * Locks Wifi Multicast on until {@link #release} is called. 1253 * 1254 * If this MulticastLock is reference-counted each call to 1255 * {@code acquire} will increment the reference count, and the 1256 * wifi interface will receive multicast packets as long as the 1257 * reference count is above zero. 1258 * 1259 * If this MulticastLock is not reference-counted, the first call to 1260 * {@code acquire} will turn on the multicast packets, but subsequent 1261 * calls will be ignored. Only one call to {@link #release} will 1262 * be required, regardless of the number of times that {@code acquire} 1263 * is called. 1264 * 1265 * Note that other applications may also lock Wifi Multicast on. 1266 * Only they can relinquish their lock. 1267 * 1268 * Also note that applications cannot leave Multicast locked on. 1269 * When an app exits or crashes, any Multicast locks will be released. 1270 */ 1271 public void acquire() { 1272 synchronized (mBinder) { 1273 if (mRefCounted ? (++mRefCount > 0) : (!mHeld)) { 1274 try { 1275 mService.acquireMulticastLock(mBinder, mTag); 1276 synchronized (WifiManager.this) { 1277 if (mActiveLockCount >= MAX_ACTIVE_LOCKS) { 1278 mService.releaseMulticastLock(); 1279 throw new UnsupportedOperationException( 1280 "Exceeded maximum number of wifi locks"); 1281 } 1282 mActiveLockCount++; 1283 } 1284 } catch (RemoteException ignore) { 1285 } 1286 mHeld = true; 1287 } 1288 } 1289 } 1290 1291 /** 1292 * Unlocks Wifi Multicast, restoring the filter of packets 1293 * not addressed specifically to this device and saving power. 1294 * 1295 * If this MulticastLock is reference-counted, each call to 1296 * {@code release} will decrement the reference count, and the 1297 * multicast packets will only stop being received when the reference 1298 * count reaches zero. If the reference count goes below zero (that 1299 * is, if {@code release} is called a greater number of times than 1300 * {@link #acquire}), an exception is thrown. 1301 * 1302 * If this MulticastLock is not reference-counted, the first call to 1303 * {@code release} (after the radio was multicast locked using 1304 * {@link #acquire}) will unlock the multicast, and subsequent calls 1305 * will be ignored. 1306 * 1307 * Note that if any other Wifi Multicast Locks are still outstanding 1308 * this {@code release} call will not have an immediate effect. Only 1309 * when all applications have released all their Multicast Locks will 1310 * the Multicast filter be turned back on. 1311 * 1312 * Also note that when an app exits or crashes all of its Multicast 1313 * Locks will be automatically released. 1314 */ 1315 public void release() { 1316 synchronized (mBinder) { 1317 if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { 1318 try { 1319 mService.releaseMulticastLock(); 1320 synchronized (WifiManager.this) { 1321 mActiveLockCount--; 1322 } 1323 } catch (RemoteException ignore) { 1324 } 1325 mHeld = false; 1326 } 1327 if (mRefCount < 0) { 1328 throw new RuntimeException("MulticastLock under-locked " 1329 + mTag); 1330 } 1331 } 1332 } 1333 1334 /** 1335 * Controls whether this is a reference-counted or non-reference- 1336 * counted MulticastLock. 1337 * 1338 * Reference-counted MulticastLocks keep track of the number of calls 1339 * to {@link #acquire} and {@link #release}, and only stop the 1340 * reception of multicast packets when every call to {@link #acquire} 1341 * has been balanced with a call to {@link #release}. Non-reference- 1342 * counted MulticastLocks allow the reception of multicast packets 1343 * whenever {@link #acquire} is called and stop accepting multicast 1344 * packets whenever {@link #release} is called. 1345 * 1346 * @param refCounted true if this MulticastLock should keep a reference 1347 * count 1348 */ 1349 public void setReferenceCounted(boolean refCounted) { 1350 mRefCounted = refCounted; 1351 } 1352 1353 /** 1354 * Checks whether this MulticastLock is currently held. 1355 * 1356 * @return true if this MulticastLock is held, false otherwise 1357 */ 1358 public boolean isHeld() { 1359 synchronized (mBinder) { 1360 return mHeld; 1361 } 1362 } 1363 1364 public String toString() { 1365 String s1, s2, s3; 1366 synchronized (mBinder) { 1367 s1 = Integer.toHexString(System.identityHashCode(this)); 1368 s2 = mHeld ? "held; " : ""; 1369 if (mRefCounted) { 1370 s3 = "refcounted: refcount = " + mRefCount; 1371 } else { 1372 s3 = "not refcounted"; 1373 } 1374 return "MulticastLock{ " + s1 + "; " + s2 + s3 + " }"; 1375 } 1376 } 1377 1378 @Override 1379 protected void finalize() throws Throwable { 1380 super.finalize(); 1381 setReferenceCounted(false); 1382 release(); 1383 } 1384 } 1385 1386 /** 1387 * Check multicast filter status. 1388 * 1389 * @return true if multicast packets are allowed. 1390 * 1391 * @hide pending API council approval 1392 */ 1393 public boolean isMulticastEnabled() { 1394 try { 1395 return mService.isMulticastEnabled(); 1396 } catch (RemoteException e) { 1397 return false; 1398 } 1399 } 1400 1401 /** 1402 * Initialize the multicast filtering to 'on' 1403 * @hide no intent to publish 1404 */ 1405 public boolean initializeMulticastFiltering() { 1406 try { 1407 mService.initializeMulticastFiltering(); 1408 return true; 1409 } catch (RemoteException e) { 1410 return false; 1411 } 1412 } 1413} 1414