WifiManager.java revision e04653cbd0e8303eba92088344312b827e6b0bab
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 int partitionSize = (MAX_RSSI - MIN_RSSI) / (numLevels - 1); 769 return (rssi - MIN_RSSI) / partitionSize; 770 } 771 } 772 773 /** 774 * Compares two signal strengths. 775 * 776 * @param rssiA The power of the first signal measured in RSSI. 777 * @param rssiB The power of the second signal measured in RSSI. 778 * @return Returns <0 if the first signal is weaker than the second signal, 779 * 0 if the two signals have the same strength, and >0 if the first 780 * signal is stronger than the second signal. 781 */ 782 public static int compareSignalLevel(int rssiA, int rssiB) { 783 return rssiA - rssiB; 784 } 785 786 /** 787 * Start AccessPoint mode with the specified 788 * configuration. If the radio is already running in 789 * AP mode, update the new configuration 790 * Note that starting in access point mode disables station 791 * mode operation 792 * @param wifiConfig SSID, security and channel details as 793 * part of WifiConfiguration 794 * @return {@code true} if the operation succeeds, {@code false} otherwise 795 * 796 * @hide Dont open up yet 797 */ 798 public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) { 799 try { 800 return mService.setWifiApEnabled(wifiConfig, enabled); 801 } catch (RemoteException e) { 802 return false; 803 } 804 } 805 806 /** 807 * Gets the Wi-Fi enabled state. 808 * @return One of {@link #WIFI_AP_STATE_DISABLED}, 809 * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED}, 810 * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED} 811 * @see #isWifiApEnabled() 812 * 813 * @hide Dont open yet 814 */ 815 public int getWifiApState() { 816 try { 817 return mService.getWifiApEnabledState(); 818 } catch (RemoteException e) { 819 return WIFI_AP_STATE_FAILED; 820 } 821 } 822 823 /** 824 * Return whether Wi-Fi AP is enabled or disabled. 825 * @return {@code true} if Wi-Fi AP is enabled 826 * @see #getWifiApState() 827 * 828 * @hide Dont open yet 829 */ 830 public boolean isWifiApEnabled() { 831 return getWifiApState() == WIFI_AP_STATE_ENABLED; 832 } 833 834 /** 835 * Gets the Wi-Fi AP Configuration. 836 * @return AP details in WifiConfiguration 837 * 838 * @hide Dont open yet 839 */ 840 public WifiConfiguration getWifiApConfiguration() { 841 try { 842 return mService.getWifiApConfiguration(); 843 } catch (RemoteException e) { 844 return null; 845 } 846 } 847 848 /** 849 * Sets the Wi-Fi AP Configuration. 850 * @return {@code true} if the operation succeeded, {@code false} otherwise 851 * 852 * @hide Dont open yet 853 */ 854 public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) { 855 try { 856 mService.setWifiApConfiguration(wifiConfig); 857 return true; 858 } catch (RemoteException e) { 859 return false; 860 } 861 } 862 863 /** 864 * Start the driver and connect to network. 865 * 866 * This function will over-ride WifiLock and device idle status. For example, 867 * even if the device is idle or there is only a scan-only lock held, 868 * a start wifi would mean that wifi connection is kept active until 869 * a stopWifi() is sent. 870 * 871 * This API is used by WifiStateTracker 872 * 873 * @return {@code true} if the operation succeeds else {@code false} 874 * @hide 875 */ 876 public boolean startWifi() { 877 try { 878 mService.startWifi(); 879 return true; 880 } catch (RemoteException e) { 881 return false; 882 } 883 } 884 885 /** 886 * Disconnect from a network (if any) and stop the driver. 887 * 888 * This function will over-ride WifiLock and device idle status. Wi-Fi 889 * stays inactive until a startWifi() is issued. 890 * 891 * This API is used by WifiStateTracker 892 * 893 * @return {@code true} if the operation succeeds else {@code false} 894 * @hide 895 */ 896 public boolean stopWifi() { 897 try { 898 mService.stopWifi(); 899 return true; 900 } catch (RemoteException e) { 901 return false; 902 } 903 } 904 905 /** 906 * Add a bssid to the supplicant blacklist 907 * 908 * This API is used by WifiWatchdogService 909 * 910 * @return {@code true} if the operation succeeds else {@code false} 911 * @hide 912 */ 913 public boolean addToBlacklist(String bssid) { 914 try { 915 mService.addToBlacklist(bssid); 916 return true; 917 } catch (RemoteException e) { 918 return false; 919 } 920 } 921 922 /** 923 * Clear the supplicant blacklist 924 * 925 * This API is used by WifiWatchdogService 926 * 927 * @return {@code true} if the operation succeeds else {@code false} 928 * @hide 929 */ 930 public boolean clearBlacklist() { 931 try { 932 mService.clearBlacklist(); 933 return true; 934 } catch (RemoteException e) { 935 return false; 936 } 937 } 938 939 /* TODO: deprecate synchronous API and open up the following API */ 940 /** 941 * Connect to a network with the given configuration. The network also 942 * gets added to the supplicant configuration. 943 * 944 * For a new network, this function is used instead of a 945 * sequence of addNetwork(), enableNetwork(), saveConfiguration() and 946 * reconnect() 947 * 948 * @param config the set of variables that describe the configuration, 949 * contained in a {@link WifiConfiguration} object. 950 * @hide 951 */ 952 public void connectNetwork(WifiConfiguration config) { 953 if (config == null) { 954 return; 955 } 956 try { 957 mService.connectNetworkWithConfig(config); 958 } catch (RemoteException e) { } 959 } 960 961 /** 962 * Connect to a network with the given networkId. 963 * 964 * This function is used instead of a enableNetwork(), saveConfiguration() and 965 * reconnect() 966 * 967 * @param networkId the network id identifiying the network in the 968 * supplicant configuration list 969 * @hide 970 */ 971 public void connectNetwork(int networkId) { 972 if (networkId < 0) { 973 return; 974 } 975 try { 976 mService.connectNetworkWithId(networkId); 977 } catch (RemoteException e) { } 978 } 979 980 /** 981 * Save the given network in the supplicant config. If the network already 982 * exists, the configuration is updated. A new network is enabled 983 * by default. 984 * 985 * For a new network, this function is used instead of a 986 * sequence of addNetwork(), enableNetwork() and saveConfiguration(). 987 * 988 * For an existing network, it accomplishes the task of updateNetwork() 989 * and saveConfiguration() 990 * 991 * @param config the set of variables that describe the configuration, 992 * contained in a {@link WifiConfiguration} object. 993 * @hide 994 */ 995 public void saveNetwork(WifiConfiguration config) { 996 if (config == null) { 997 return; 998 } 999 try { 1000 mService.saveNetwork(config); 1001 } catch (RemoteException e) { } 1002 } 1003 1004 /** 1005 * Delete the network in the supplicant config. 1006 * 1007 * This function is used instead of a sequence of removeNetwork() 1008 * and saveConfiguration(). 1009 * 1010 * @param config the set of variables that describe the configuration, 1011 * contained in a {@link WifiConfiguration} object. 1012 * @hide 1013 */ 1014 public void forgetNetwork(int netId) { 1015 if (netId < 0) { 1016 return; 1017 } 1018 try { 1019 mService.forgetNetwork(netId); 1020 } catch (RemoteException e) { } 1021 } 1022 1023 /** 1024 * Allows an application to keep the Wi-Fi radio awake. 1025 * Normally the Wi-Fi radio may turn off when the user has not used the device in a while. 1026 * Acquiring a WifiLock will keep the radio on until the lock is released. Multiple 1027 * applications may hold WifiLocks, and the radio will only be allowed to turn off when no 1028 * WifiLocks are held in any application. 1029 * 1030 * Before using a WifiLock, consider carefully if your application requires Wi-Fi access, or 1031 * could function over a mobile network, if available. A program that needs to download large 1032 * files should hold a WifiLock to ensure that the download will complete, but a program whose 1033 * network usage is occasional or low-bandwidth should not hold a WifiLock to avoid adversely 1034 * affecting battery life. 1035 * 1036 * Note that WifiLocks cannot override the user-level "Wi-Fi Enabled" setting, nor Airplane 1037 * Mode. They simply keep the radio from turning off when Wi-Fi is already on but the device 1038 * is idle. 1039 */ 1040 public class WifiLock { 1041 private String mTag; 1042 private final IBinder mBinder; 1043 private int mRefCount; 1044 int mLockType; 1045 private boolean mRefCounted; 1046 private boolean mHeld; 1047 1048 private WifiLock(int lockType, String tag) { 1049 mTag = tag; 1050 mLockType = lockType; 1051 mBinder = new Binder(); 1052 mRefCount = 0; 1053 mRefCounted = true; 1054 mHeld = false; 1055 } 1056 1057 /** 1058 * Locks the Wi-Fi radio on until {@link #release} is called. 1059 * 1060 * If this WifiLock is reference-counted, each call to {@code acquire} will increment the 1061 * reference count, and the radio will remain locked as long as the reference count is 1062 * above zero. 1063 * 1064 * If this WifiLock is not reference-counted, the first call to {@code acquire} will lock 1065 * the radio, but subsequent calls will be ignored. Only one call to {@link #release} 1066 * will be required, regardless of the number of times that {@code acquire} is called. 1067 */ 1068 public void acquire() { 1069 synchronized (mBinder) { 1070 if (mRefCounted ? (++mRefCount > 0) : (!mHeld)) { 1071 try { 1072 mService.acquireWifiLock(mBinder, mLockType, mTag); 1073 synchronized (WifiManager.this) { 1074 if (mActiveLockCount >= MAX_ACTIVE_LOCKS) { 1075 mService.releaseWifiLock(mBinder); 1076 throw new UnsupportedOperationException( 1077 "Exceeded maximum number of wifi locks"); 1078 } 1079 mActiveLockCount++; 1080 } 1081 } catch (RemoteException ignore) { 1082 } 1083 mHeld = true; 1084 } 1085 } 1086 } 1087 1088 /** 1089 * Unlocks the Wi-Fi radio, allowing it to turn off when the device is idle. 1090 * 1091 * If this WifiLock is reference-counted, each call to {@code release} will decrement the 1092 * reference count, and the radio will be unlocked only when the reference count reaches 1093 * zero. If the reference count goes below zero (that is, if {@code release} is called 1094 * a greater number of times than {@link #acquire}), an exception is thrown. 1095 * 1096 * If this WifiLock is not reference-counted, the first call to {@code release} (after 1097 * the radio was locked using {@link #acquire}) will unlock the radio, and subsequent 1098 * calls will be ignored. 1099 */ 1100 public void release() { 1101 synchronized (mBinder) { 1102 if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { 1103 try { 1104 mService.releaseWifiLock(mBinder); 1105 synchronized (WifiManager.this) { 1106 mActiveLockCount--; 1107 } 1108 } catch (RemoteException ignore) { 1109 } 1110 mHeld = false; 1111 } 1112 if (mRefCount < 0) { 1113 throw new RuntimeException("WifiLock under-locked " + mTag); 1114 } 1115 } 1116 } 1117 1118 /** 1119 * Controls whether this is a reference-counted or non-reference-counted WifiLock. 1120 * 1121 * Reference-counted WifiLocks keep track of the number of calls to {@link #acquire} and 1122 * {@link #release}, and only allow the radio to sleep when every call to {@link #acquire} 1123 * has been balanced with a call to {@link #release}. Non-reference-counted WifiLocks 1124 * lock the radio whenever {@link #acquire} is called and it is unlocked, and unlock the 1125 * radio whenever {@link #release} is called and it is locked. 1126 * 1127 * @param refCounted true if this WifiLock should keep a reference count 1128 */ 1129 public void setReferenceCounted(boolean refCounted) { 1130 mRefCounted = refCounted; 1131 } 1132 1133 /** 1134 * Checks whether this WifiLock is currently held. 1135 * 1136 * @return true if this WifiLock is held, false otherwise 1137 */ 1138 public boolean isHeld() { 1139 synchronized (mBinder) { 1140 return mHeld; 1141 } 1142 } 1143 1144 public String toString() { 1145 String s1, s2, s3; 1146 synchronized (mBinder) { 1147 s1 = Integer.toHexString(System.identityHashCode(this)); 1148 s2 = mHeld ? "held; " : ""; 1149 if (mRefCounted) { 1150 s3 = "refcounted: refcount = " + mRefCount; 1151 } else { 1152 s3 = "not refcounted"; 1153 } 1154 return "WifiLock{ " + s1 + "; " + s2 + s3 + " }"; 1155 } 1156 } 1157 1158 @Override 1159 protected void finalize() throws Throwable { 1160 super.finalize(); 1161 synchronized (mBinder) { 1162 if (mHeld) { 1163 try { 1164 mService.releaseWifiLock(mBinder); 1165 synchronized (WifiManager.this) { 1166 mActiveLockCount--; 1167 } 1168 } catch (RemoteException ignore) { 1169 } 1170 } 1171 } 1172 } 1173 } 1174 1175 /** 1176 * Creates a new WifiLock. 1177 * 1178 * @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL} and 1179 * {@link #WIFI_MODE_SCAN_ONLY} for descriptions of the types of Wi-Fi locks. 1180 * @param tag a tag for the WifiLock to identify it in debugging messages. This string is 1181 * never shown to the user under normal conditions, but should be descriptive 1182 * enough to identify your application and the specific WifiLock within it, if it 1183 * holds multiple WifiLocks. 1184 * 1185 * @return a new, unacquired WifiLock with the given tag. 1186 * 1187 * @see WifiLock 1188 */ 1189 public WifiLock createWifiLock(int lockType, String tag) { 1190 return new WifiLock(lockType, tag); 1191 } 1192 1193 /** 1194 * Creates a new WifiLock. 1195 * 1196 * @param tag a tag for the WifiLock to identify it in debugging messages. This string is 1197 * never shown to the user under normal conditions, but should be descriptive 1198 * enough to identify your application and the specific WifiLock within it, if it 1199 * holds multiple WifiLocks. 1200 * 1201 * @return a new, unacquired WifiLock with the given tag. 1202 * 1203 * @see WifiLock 1204 */ 1205 public WifiLock createWifiLock(String tag) { 1206 return new WifiLock(WIFI_MODE_FULL, tag); 1207 } 1208 1209 1210 /** 1211 * Create a new MulticastLock 1212 * 1213 * @param tag a tag for the MulticastLock to identify it in debugging 1214 * messages. This string is never shown to the user under 1215 * normal conditions, but should be descriptive enough to 1216 * identify your application and the specific MulticastLock 1217 * within it, if it holds multiple MulticastLocks. 1218 * 1219 * @return a new, unacquired MulticastLock with the given tag. 1220 * 1221 * @see MulticastLock 1222 */ 1223 public MulticastLock createMulticastLock(String tag) { 1224 return new MulticastLock(tag); 1225 } 1226 1227 /** 1228 * Allows an application to receive Wifi Multicast packets. 1229 * Normally the Wifi stack filters out packets not explicitly 1230 * addressed to this device. Acquring a MulticastLock will 1231 * cause the stack to receive packets addressed to multicast 1232 * addresses. Processing these extra packets can cause a noticable 1233 * battery drain and should be disabled when not needed. 1234 */ 1235 public class MulticastLock { 1236 private String mTag; 1237 private final IBinder mBinder; 1238 private int mRefCount; 1239 private boolean mRefCounted; 1240 private boolean mHeld; 1241 1242 private MulticastLock(String tag) { 1243 mTag = tag; 1244 mBinder = new Binder(); 1245 mRefCount = 0; 1246 mRefCounted = true; 1247 mHeld = false; 1248 } 1249 1250 /** 1251 * Locks Wifi Multicast on until {@link #release} is called. 1252 * 1253 * If this MulticastLock is reference-counted each call to 1254 * {@code acquire} will increment the reference count, and the 1255 * wifi interface will receive multicast packets as long as the 1256 * reference count is above zero. 1257 * 1258 * If this MulticastLock is not reference-counted, the first call to 1259 * {@code acquire} will turn on the multicast packets, but subsequent 1260 * calls will be ignored. Only one call to {@link #release} will 1261 * be required, regardless of the number of times that {@code acquire} 1262 * is called. 1263 * 1264 * Note that other applications may also lock Wifi Multicast on. 1265 * Only they can relinquish their lock. 1266 * 1267 * Also note that applications cannot leave Multicast locked on. 1268 * When an app exits or crashes, any Multicast locks will be released. 1269 */ 1270 public void acquire() { 1271 synchronized (mBinder) { 1272 if (mRefCounted ? (++mRefCount > 0) : (!mHeld)) { 1273 try { 1274 mService.acquireMulticastLock(mBinder, mTag); 1275 synchronized (WifiManager.this) { 1276 if (mActiveLockCount >= MAX_ACTIVE_LOCKS) { 1277 mService.releaseMulticastLock(); 1278 throw new UnsupportedOperationException( 1279 "Exceeded maximum number of wifi locks"); 1280 } 1281 mActiveLockCount++; 1282 } 1283 } catch (RemoteException ignore) { 1284 } 1285 mHeld = true; 1286 } 1287 } 1288 } 1289 1290 /** 1291 * Unlocks Wifi Multicast, restoring the filter of packets 1292 * not addressed specifically to this device and saving power. 1293 * 1294 * If this MulticastLock is reference-counted, each call to 1295 * {@code release} will decrement the reference count, and the 1296 * multicast packets will only stop being received when the reference 1297 * count reaches zero. If the reference count goes below zero (that 1298 * is, if {@code release} is called a greater number of times than 1299 * {@link #acquire}), an exception is thrown. 1300 * 1301 * If this MulticastLock is not reference-counted, the first call to 1302 * {@code release} (after the radio was multicast locked using 1303 * {@link #acquire}) will unlock the multicast, and subsequent calls 1304 * will be ignored. 1305 * 1306 * Note that if any other Wifi Multicast Locks are still outstanding 1307 * this {@code release} call will not have an immediate effect. Only 1308 * when all applications have released all their Multicast Locks will 1309 * the Multicast filter be turned back on. 1310 * 1311 * Also note that when an app exits or crashes all of its Multicast 1312 * Locks will be automatically released. 1313 */ 1314 public void release() { 1315 synchronized (mBinder) { 1316 if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { 1317 try { 1318 mService.releaseMulticastLock(); 1319 synchronized (WifiManager.this) { 1320 mActiveLockCount--; 1321 } 1322 } catch (RemoteException ignore) { 1323 } 1324 mHeld = false; 1325 } 1326 if (mRefCount < 0) { 1327 throw new RuntimeException("MulticastLock under-locked " 1328 + mTag); 1329 } 1330 } 1331 } 1332 1333 /** 1334 * Controls whether this is a reference-counted or non-reference- 1335 * counted MulticastLock. 1336 * 1337 * Reference-counted MulticastLocks keep track of the number of calls 1338 * to {@link #acquire} and {@link #release}, and only stop the 1339 * reception of multicast packets when every call to {@link #acquire} 1340 * has been balanced with a call to {@link #release}. Non-reference- 1341 * counted MulticastLocks allow the reception of multicast packets 1342 * whenever {@link #acquire} is called and stop accepting multicast 1343 * packets whenever {@link #release} is called. 1344 * 1345 * @param refCounted true if this MulticastLock should keep a reference 1346 * count 1347 */ 1348 public void setReferenceCounted(boolean refCounted) { 1349 mRefCounted = refCounted; 1350 } 1351 1352 /** 1353 * Checks whether this MulticastLock is currently held. 1354 * 1355 * @return true if this MulticastLock is held, false otherwise 1356 */ 1357 public boolean isHeld() { 1358 synchronized (mBinder) { 1359 return mHeld; 1360 } 1361 } 1362 1363 public String toString() { 1364 String s1, s2, s3; 1365 synchronized (mBinder) { 1366 s1 = Integer.toHexString(System.identityHashCode(this)); 1367 s2 = mHeld ? "held; " : ""; 1368 if (mRefCounted) { 1369 s3 = "refcounted: refcount = " + mRefCount; 1370 } else { 1371 s3 = "not refcounted"; 1372 } 1373 return "MulticastLock{ " + s1 + "; " + s2 + s3 + " }"; 1374 } 1375 } 1376 1377 @Override 1378 protected void finalize() throws Throwable { 1379 super.finalize(); 1380 setReferenceCounted(false); 1381 release(); 1382 } 1383 } 1384 1385 /** 1386 * Check multicast filter status. 1387 * 1388 * @return true if multicast packets are allowed. 1389 * 1390 * @hide pending API council approval 1391 */ 1392 public boolean isMulticastEnabled() { 1393 try { 1394 return mService.isMulticastEnabled(); 1395 } catch (RemoteException e) { 1396 return false; 1397 } 1398 } 1399 1400 /** 1401 * Initialize the multicast filtering to 'on' 1402 * @hide no intent to publish 1403 */ 1404 public boolean initializeMulticastFiltering() { 1405 try { 1406 mService.initializeMulticastFiltering(); 1407 return true; 1408 } catch (RemoteException e) { 1409 return false; 1410 } 1411 } 1412} 1413