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