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