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