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 17 package android.net.wifi; 18 19 import static android.Manifest.permission.ACCESS_FINE_LOCATION; 20 import static android.Manifest.permission.ACCESS_WIFI_STATE; 21 import static android.Manifest.permission.READ_WIFI_CREDENTIAL; 22 23 import android.annotation.CallbackExecutor; 24 import android.annotation.IntDef; 25 import android.annotation.NonNull; 26 import android.annotation.Nullable; 27 import android.annotation.RequiresPermission; 28 import android.annotation.SdkConstant; 29 import android.annotation.SdkConstant.SdkConstantType; 30 import android.annotation.SystemApi; 31 import android.annotation.SystemService; 32 import android.annotation.UnsupportedAppUsage; 33 import android.app.ActivityManager; 34 import android.content.Context; 35 import android.content.pm.ParceledListSlice; 36 import android.net.ConnectivityManager; 37 import android.net.DhcpInfo; 38 import android.net.Network; 39 import android.net.NetworkCapabilities; 40 import android.net.NetworkRequest; 41 import android.net.wifi.hotspot2.IProvisioningCallback; 42 import android.net.wifi.hotspot2.OsuProvider; 43 import android.net.wifi.hotspot2.PasspointConfiguration; 44 import android.net.wifi.hotspot2.ProvisioningCallback; 45 import android.os.Binder; 46 import android.os.Build; 47 import android.os.Handler; 48 import android.os.IBinder; 49 import android.os.Looper; 50 import android.os.Message; 51 import android.os.Messenger; 52 import android.os.RemoteException; 53 import android.os.WorkSource; 54 import android.util.Log; 55 import android.util.Pair; 56 import android.util.SparseArray; 57 58 import com.android.internal.annotations.GuardedBy; 59 import com.android.internal.annotations.VisibleForTesting; 60 import com.android.internal.util.AsyncChannel; 61 import com.android.internal.util.Protocol; 62 import com.android.server.net.NetworkPinner; 63 64 import dalvik.system.CloseGuard; 65 66 import java.lang.annotation.Retention; 67 import java.lang.annotation.RetentionPolicy; 68 import java.lang.ref.WeakReference; 69 import java.net.InetAddress; 70 import java.util.ArrayList; 71 import java.util.Collections; 72 import java.util.HashMap; 73 import java.util.List; 74 import java.util.Map; 75 import java.util.Set; 76 import java.util.concurrent.CountDownLatch; 77 import java.util.concurrent.Executor; 78 79 /** 80 * This class provides the primary API for managing all aspects of Wi-Fi 81 * connectivity. 82 * <p> 83 * On releases before {@link android.os.Build.VERSION_CODES#N}, this object 84 * should only be obtained from an {@linkplain Context#getApplicationContext() 85 * application context}, and not from any other derived context to avoid memory 86 * leaks within the calling process. 87 * <p> 88 * It deals with several categories of items: 89 * </p> 90 * <ul> 91 * <li>The list of configured networks. The list can be viewed and updated, and 92 * attributes of individual entries can be modified.</li> 93 * <li>The currently active Wi-Fi network, if any. Connectivity can be 94 * established or torn down, and dynamic information about the state of the 95 * network can be queried.</li> 96 * <li>Results of access point scans, containing enough information to make 97 * decisions about what access point to connect to.</li> 98 * <li>It defines the names of various Intent actions that are broadcast upon 99 * any sort of change in Wi-Fi state. 100 * </ul> 101 * <p> 102 * This is the API to use when performing Wi-Fi specific operations. To perform 103 * operations that pertain to network connectivity at an abstract level, use 104 * {@link android.net.ConnectivityManager}. 105 * </p> 106 */ 107 @SystemService(Context.WIFI_SERVICE) 108 public class WifiManager { 109 110 private static final String TAG = "WifiManager"; 111 // Supplicant error codes: 112 /** 113 * The error code if there was a problem authenticating. 114 * @deprecated This is no longer supported. 115 */ 116 @Deprecated 117 public static final int ERROR_AUTHENTICATING = 1; 118 119 /** 120 * The reason code if there is no error during authentication. 121 * It could also imply that there no authentication in progress, 122 * this reason code also serves as a reset value. 123 * @deprecated This is no longer supported. 124 * @hide 125 */ 126 @Deprecated 127 public static final int ERROR_AUTH_FAILURE_NONE = 0; 128 129 /** 130 * The reason code if there was a timeout authenticating. 131 * @deprecated This is no longer supported. 132 * @hide 133 */ 134 @Deprecated 135 public static final int ERROR_AUTH_FAILURE_TIMEOUT = 1; 136 137 /** 138 * The reason code if there was a wrong password while 139 * authenticating. 140 * @deprecated This is no longer supported. 141 * @hide 142 */ 143 @Deprecated 144 public static final int ERROR_AUTH_FAILURE_WRONG_PSWD = 2; 145 146 /** 147 * The reason code if there was EAP failure while 148 * authenticating. 149 * @deprecated This is no longer supported. 150 * @hide 151 */ 152 @Deprecated 153 public static final int ERROR_AUTH_FAILURE_EAP_FAILURE = 3; 154 155 /** 156 * Maximum number of active network suggestions allowed per app. 157 * @hide 158 */ 159 public static final int NETWORK_SUGGESTIONS_MAX_PER_APP = 160 ActivityManager.isLowRamDeviceStatic() ? 256 : 1024; 161 162 /** 163 * Reason code if all of the network suggestions were successfully added or removed. 164 */ 165 public static final int STATUS_NETWORK_SUGGESTIONS_SUCCESS = 0; 166 167 /** 168 * Reason code if there was an internal error in the platform while processing the addition or 169 * removal of suggestions. 170 */ 171 public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL = 1; 172 173 /** 174 * Reason code if the user has disallowed "android:change_wifi_state" app-ops from the app. 175 * @see android.app.AppOpsManager#unsafeCheckOp(String, int, String). 176 */ 177 public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED = 2; 178 179 /** 180 * Reason code if one or more of the network suggestions added already exists in platform's 181 * database. 182 * @see WifiNetworkSuggestion#equals(Object) 183 */ 184 public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE = 3; 185 186 /** 187 * Reason code if the number of network suggestions provided by the app crosses the max 188 * threshold set per app. 189 * @see #getMaxNumberOfNetworkSuggestionsPerApp() 190 */ 191 public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP = 4; 192 193 /** 194 * Reason code if one or more of the network suggestions removed does not exist in platform's 195 * database. 196 */ 197 public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID = 5; 198 199 /** @hide */ 200 @IntDef(prefix = { "STATUS_NETWORK_SUGGESTIONS_" }, value = { 201 STATUS_NETWORK_SUGGESTIONS_SUCCESS, 202 STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL, 203 STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED, 204 STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE, 205 STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP, 206 STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID, 207 }) 208 @Retention(RetentionPolicy.SOURCE) 209 public @interface NetworkSuggestionsStatusCode {} 210 211 /** 212 * Broadcast intent action indicating whether Wi-Fi scanning is allowed currently 213 * @hide 214 */ 215 public static final String WIFI_SCAN_AVAILABLE = "wifi_scan_available"; 216 217 /** 218 * Extra int indicating scan availability, WIFI_STATE_ENABLED and WIFI_STATE_DISABLED 219 * @hide 220 */ 221 public static final String EXTRA_SCAN_AVAILABLE = "scan_enabled"; 222 223 /** 224 * Broadcast intent action indicating that the credential of a Wi-Fi network 225 * has been changed. One extra provides the ssid of the network. Another 226 * extra provides the event type, whether the credential is saved or forgot. 227 * @hide 228 */ 229 @SystemApi 230 public static final String WIFI_CREDENTIAL_CHANGED_ACTION = 231 "android.net.wifi.WIFI_CREDENTIAL_CHANGED"; 232 /** @hide */ 233 @SystemApi 234 public static final String EXTRA_WIFI_CREDENTIAL_EVENT_TYPE = "et"; 235 /** @hide */ 236 @SystemApi 237 public static final String EXTRA_WIFI_CREDENTIAL_SSID = "ssid"; 238 /** @hide */ 239 @SystemApi 240 public static final int WIFI_CREDENTIAL_SAVED = 0; 241 /** @hide */ 242 @SystemApi 243 public static final int WIFI_CREDENTIAL_FORGOT = 1; 244 245 /** @hide */ 246 @SystemApi 247 public static final int PASSPOINT_HOME_NETWORK = 0; 248 249 /** @hide */ 250 @SystemApi 251 public static final int PASSPOINT_ROAMING_NETWORK = 1; 252 253 /** 254 * Broadcast intent action indicating that a Passpoint provider icon has been received. 255 * 256 * Included extras: 257 * {@link #EXTRA_BSSID_LONG} 258 * {@link #EXTRA_FILENAME} 259 * {@link #EXTRA_ICON} 260 * 261 * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE 262 * 263 * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered 264 * components will be launched. 265 * 266 * @hide 267 */ 268 public static final String ACTION_PASSPOINT_ICON = "android.net.wifi.action.PASSPOINT_ICON"; 269 /** 270 * BSSID of an AP in long representation. The {@link #EXTRA_BSSID} contains BSSID in 271 * String representation. 272 * 273 * Retrieve with {@link android.content.Intent#getLongExtra(String, long)}. 274 * 275 * @hide 276 */ 277 public static final String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG"; 278 /** 279 * Icon data. 280 * 281 * Retrieve with {@link android.content.Intent#getParcelableExtra(String)} and cast into 282 * {@link android.graphics.drawable.Icon}. 283 * 284 * @hide 285 */ 286 public static final String EXTRA_ICON = "android.net.wifi.extra.ICON"; 287 /** 288 * Name of a file. 289 * 290 * Retrieve with {@link android.content.Intent#getStringExtra(String)}. 291 * 292 * @hide 293 */ 294 public static final String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME"; 295 296 /** 297 * Broadcast intent action indicating a Passpoint OSU Providers List element has been received. 298 * 299 * Included extras: 300 * {@link #EXTRA_BSSID_LONG} 301 * {@link #EXTRA_ANQP_ELEMENT_DATA} 302 * 303 * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE 304 * 305 * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered 306 * components will be launched. 307 * 308 * @hide 309 */ 310 public static final String ACTION_PASSPOINT_OSU_PROVIDERS_LIST = 311 "android.net.wifi.action.PASSPOINT_OSU_PROVIDERS_LIST"; 312 /** 313 * Raw binary data of an ANQP (Access Network Query Protocol) element. 314 * 315 * Retrieve with {@link android.content.Intent#getByteArrayExtra(String)}. 316 * 317 * @hide 318 */ 319 public static final String EXTRA_ANQP_ELEMENT_DATA = 320 "android.net.wifi.extra.ANQP_ELEMENT_DATA"; 321 322 /** 323 * Broadcast intent action indicating that a Passpoint Deauth Imminent frame has been received. 324 * 325 * Included extras: 326 * {@link #EXTRA_BSSID_LONG} 327 * {@link #EXTRA_ESS} 328 * {@link #EXTRA_DELAY} 329 * {@link #EXTRA_URL} 330 * 331 * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE 332 * 333 * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered 334 * components will be launched. 335 * 336 * @hide 337 */ 338 public static final String ACTION_PASSPOINT_DEAUTH_IMMINENT = 339 "android.net.wifi.action.PASSPOINT_DEAUTH_IMMINENT"; 340 /** 341 * Flag indicating BSS (Basic Service Set) or ESS (Extended Service Set). This will be set to 342 * {@code true} for ESS. 343 * 344 * Retrieve with {@link android.content.Intent#getBooleanExtra(String, boolean)}. 345 * 346 * @hide 347 */ 348 public static final String EXTRA_ESS = "android.net.wifi.extra.ESS"; 349 /** 350 * Delay in seconds. 351 * 352 * Retrieve with {@link android.content.Intent#getIntExtra(String, int)}. 353 * 354 * @hide 355 */ 356 public static final String EXTRA_DELAY = "android.net.wifi.extra.DELAY"; 357 /** 358 * String representation of an URL. 359 * 360 * Retrieve with {@link android.content.Intent#getStringExtra(String)}. 361 * 362 * @hide 363 */ 364 public static final String EXTRA_URL = "android.net.wifi.extra.URL"; 365 366 /** 367 * Broadcast intent action indicating a Passpoint subscription remediation frame has been 368 * received. 369 * 370 * Included extras: 371 * {@link #EXTRA_BSSID_LONG} 372 * {@link #EXTRA_SUBSCRIPTION_REMEDIATION_METHOD} 373 * {@link #EXTRA_URL} 374 * 375 * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE 376 * 377 * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered 378 * components will be launched. 379 * 380 * @hide 381 */ 382 public static final String ACTION_PASSPOINT_SUBSCRIPTION_REMEDIATION = 383 "android.net.wifi.action.PASSPOINT_SUBSCRIPTION_REMEDIATION"; 384 /** 385 * The protocol supported by the subscription remediation server. The possible values are: 386 * 0 - OMA DM 387 * 1 - SOAP XML SPP 388 * 389 * Retrieve with {@link android.content.Intent#getIntExtra(String, int)}. 390 * 391 * @hide 392 */ 393 public static final String EXTRA_SUBSCRIPTION_REMEDIATION_METHOD = 394 "android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD"; 395 396 /** 397 * Activity Action: lunch OSU (Online Sign Up) view. 398 * Included extras: 399 * 400 * {@link #EXTRA_OSU_NETWORK}: {@link Network} instance associated with OSU AP. 401 * {@link #EXTRA_URL}: String representation of a server URL used for OSU process. 402 * 403 * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered 404 * components will be launched. 405 * 406 * @hide 407 */ 408 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 409 public static final String ACTION_PASSPOINT_LAUNCH_OSU_VIEW = 410 "android.net.wifi.action.PASSPOINT_LAUNCH_OSU_VIEW"; 411 412 /** 413 * The lookup key for a {@link android.net.Network} associated with OSU server. 414 * 415 * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}. 416 * 417 * @hide 418 */ 419 public static final String EXTRA_OSU_NETWORK = "android.net.wifi.extra.OSU_NETWORK"; 420 421 /** 422 * Broadcast intent action indicating that Wi-Fi has been enabled, disabled, 423 * enabling, disabling, or unknown. One extra provides this state as an int. 424 * Another extra provides the previous state, if available. 425 * 426 * @see #EXTRA_WIFI_STATE 427 * @see #EXTRA_PREVIOUS_WIFI_STATE 428 */ 429 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 430 public static final String WIFI_STATE_CHANGED_ACTION = 431 "android.net.wifi.WIFI_STATE_CHANGED"; 432 /** 433 * The lookup key for an int that indicates whether Wi-Fi is enabled, 434 * disabled, enabling, disabling, or unknown. Retrieve it with 435 * {@link android.content.Intent#getIntExtra(String,int)}. 436 * 437 * @see #WIFI_STATE_DISABLED 438 * @see #WIFI_STATE_DISABLING 439 * @see #WIFI_STATE_ENABLED 440 * @see #WIFI_STATE_ENABLING 441 * @see #WIFI_STATE_UNKNOWN 442 */ 443 public static final String EXTRA_WIFI_STATE = "wifi_state"; 444 /** 445 * The previous Wi-Fi state. 446 * 447 * @see #EXTRA_WIFI_STATE 448 */ 449 public static final String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state"; 450 451 /** 452 * Wi-Fi is currently being disabled. The state will change to {@link #WIFI_STATE_DISABLED} if 453 * it finishes successfully. 454 * 455 * @see #WIFI_STATE_CHANGED_ACTION 456 * @see #getWifiState() 457 */ 458 public static final int WIFI_STATE_DISABLING = 0; 459 /** 460 * Wi-Fi is disabled. 461 * 462 * @see #WIFI_STATE_CHANGED_ACTION 463 * @see #getWifiState() 464 */ 465 public static final int WIFI_STATE_DISABLED = 1; 466 /** 467 * Wi-Fi is currently being enabled. The state will change to {@link #WIFI_STATE_ENABLED} if 468 * it finishes successfully. 469 * 470 * @see #WIFI_STATE_CHANGED_ACTION 471 * @see #getWifiState() 472 */ 473 public static final int WIFI_STATE_ENABLING = 2; 474 /** 475 * Wi-Fi is enabled. 476 * 477 * @see #WIFI_STATE_CHANGED_ACTION 478 * @see #getWifiState() 479 */ 480 public static final int WIFI_STATE_ENABLED = 3; 481 /** 482 * Wi-Fi is in an unknown state. This state will occur when an error happens while enabling 483 * or disabling. 484 * 485 * @see #WIFI_STATE_CHANGED_ACTION 486 * @see #getWifiState() 487 */ 488 public static final int WIFI_STATE_UNKNOWN = 4; 489 490 /** 491 * Broadcast intent action indicating that Wi-Fi AP has been enabled, disabled, 492 * enabling, disabling, or failed. 493 * 494 * @hide 495 */ 496 @SystemApi 497 public static final String WIFI_AP_STATE_CHANGED_ACTION = 498 "android.net.wifi.WIFI_AP_STATE_CHANGED"; 499 500 /** 501 * The lookup key for an int that indicates whether Wi-Fi AP is enabled, 502 * disabled, enabling, disabling, or failed. Retrieve it with 503 * {@link android.content.Intent#getIntExtra(String,int)}. 504 * 505 * @see #WIFI_AP_STATE_DISABLED 506 * @see #WIFI_AP_STATE_DISABLING 507 * @see #WIFI_AP_STATE_ENABLED 508 * @see #WIFI_AP_STATE_ENABLING 509 * @see #WIFI_AP_STATE_FAILED 510 * 511 * @hide 512 */ 513 @SystemApi 514 public static final String EXTRA_WIFI_AP_STATE = "wifi_state"; 515 516 /** 517 * The look up key for an int that indicates why softAP started failed 518 * currently support general and no_channel 519 * @see #SAP_START_FAILURE_GENERAL 520 * @see #SAP_START_FAILURE_NO_CHANNEL 521 * 522 * @hide 523 */ 524 public static final String EXTRA_WIFI_AP_FAILURE_REASON = "wifi_ap_error_code"; 525 /** 526 * The previous Wi-Fi state. 527 * 528 * @see #EXTRA_WIFI_AP_STATE 529 * 530 * @hide 531 */ 532 @SystemApi 533 public static final String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state"; 534 /** 535 * The interface used for the softap. 536 * 537 * @hide 538 */ 539 public static final String EXTRA_WIFI_AP_INTERFACE_NAME = "wifi_ap_interface_name"; 540 /** 541 * The intended ip mode for this softap. 542 * @see #IFACE_IP_MODE_TETHERED 543 * @see #IFACE_IP_MODE_LOCAL_ONLY 544 * 545 * @hide 546 */ 547 public static final String EXTRA_WIFI_AP_MODE = "wifi_ap_mode"; 548 549 /** @hide */ 550 @IntDef(flag = false, prefix = { "WIFI_AP_STATE_" }, value = { 551 WIFI_AP_STATE_DISABLING, 552 WIFI_AP_STATE_DISABLED, 553 WIFI_AP_STATE_ENABLING, 554 WIFI_AP_STATE_ENABLED, 555 WIFI_AP_STATE_FAILED, 556 }) 557 @Retention(RetentionPolicy.SOURCE) 558 public @interface WifiApState {} 559 560 /** 561 * Wi-Fi AP is currently being disabled. The state will change to 562 * {@link #WIFI_AP_STATE_DISABLED} if it finishes successfully. 563 * 564 * @see #WIFI_AP_STATE_CHANGED_ACTION 565 * @see #getWifiApState() 566 * 567 * @hide 568 */ 569 @SystemApi 570 public static final int WIFI_AP_STATE_DISABLING = 10; 571 /** 572 * Wi-Fi AP is disabled. 573 * 574 * @see #WIFI_AP_STATE_CHANGED_ACTION 575 * @see #getWifiState() 576 * 577 * @hide 578 */ 579 @SystemApi 580 public static final int WIFI_AP_STATE_DISABLED = 11; 581 /** 582 * Wi-Fi AP is currently being enabled. The state will change to 583 * {@link #WIFI_AP_STATE_ENABLED} if it finishes successfully. 584 * 585 * @see #WIFI_AP_STATE_CHANGED_ACTION 586 * @see #getWifiApState() 587 * 588 * @hide 589 */ 590 @SystemApi 591 public static final int WIFI_AP_STATE_ENABLING = 12; 592 /** 593 * Wi-Fi AP is enabled. 594 * 595 * @see #WIFI_AP_STATE_CHANGED_ACTION 596 * @see #getWifiApState() 597 * 598 * @hide 599 */ 600 @SystemApi 601 public static final int WIFI_AP_STATE_ENABLED = 13; 602 /** 603 * Wi-Fi AP is in a failed state. This state will occur when an error occurs during 604 * enabling or disabling 605 * 606 * @see #WIFI_AP_STATE_CHANGED_ACTION 607 * @see #getWifiApState() 608 * 609 * @hide 610 */ 611 @SystemApi 612 public static final int WIFI_AP_STATE_FAILED = 14; 613 614 /** @hide */ 615 @IntDef(flag = false, prefix = { "SAP_START_FAILURE_" }, value = { 616 SAP_START_FAILURE_GENERAL, 617 SAP_START_FAILURE_NO_CHANNEL, 618 }) 619 @Retention(RetentionPolicy.SOURCE) 620 public @interface SapStartFailure {} 621 622 /** 623 * All other reasons for AP start failure besides {@link #SAP_START_FAILURE_NO_CHANNEL}. 624 * 625 * @hide 626 */ 627 public static final int SAP_START_FAILURE_GENERAL= 0; 628 629 /** 630 * If Wi-Fi AP start failed, this reason code means that no legal channel exists on user 631 * selected band due to regulatory constraints. 632 * 633 * @hide 634 */ 635 public static final int SAP_START_FAILURE_NO_CHANNEL = 1; 636 637 /** 638 * Interface IP mode unspecified. 639 * 640 * @see updateInterfaceIpState(String, int) 641 * 642 * @hide 643 */ 644 public static final int IFACE_IP_MODE_UNSPECIFIED = -1; 645 646 /** 647 * Interface IP mode for configuration error. 648 * 649 * @see updateInterfaceIpState(String, int) 650 * 651 * @hide 652 */ 653 public static final int IFACE_IP_MODE_CONFIGURATION_ERROR = 0; 654 655 /** 656 * Interface IP mode for tethering. 657 * 658 * @see updateInterfaceIpState(String, int) 659 * 660 * @hide 661 */ 662 public static final int IFACE_IP_MODE_TETHERED = 1; 663 664 /** 665 * Interface IP mode for Local Only Hotspot. 666 * 667 * @see updateInterfaceIpState(String, int) 668 * 669 * @hide 670 */ 671 public static final int IFACE_IP_MODE_LOCAL_ONLY = 2; 672 673 /** 674 * Broadcast intent action indicating that a connection to the supplicant has 675 * been established (and it is now possible 676 * to perform Wi-Fi operations) or the connection to the supplicant has been 677 * lost. One extra provides the connection state as a boolean, where {@code true} 678 * means CONNECTED. 679 * @deprecated This is no longer supported. 680 * @see #EXTRA_SUPPLICANT_CONNECTED 681 */ 682 @Deprecated 683 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 684 public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION = 685 "android.net.wifi.supplicant.CONNECTION_CHANGE"; 686 /** 687 * The lookup key for a boolean that indicates whether a connection to 688 * the supplicant daemon has been gained or lost. {@code true} means 689 * a connection now exists. 690 * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}. 691 * @deprecated This is no longer supported. 692 */ 693 @Deprecated 694 public static final String EXTRA_SUPPLICANT_CONNECTED = "connected"; 695 /** 696 * Broadcast intent action indicating that the state of Wi-Fi connectivity 697 * has changed. An extra provides the new state 698 * in the form of a {@link android.net.NetworkInfo} object. 699 * @see #EXTRA_NETWORK_INFO 700 */ 701 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 702 public static final String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE"; 703 /** 704 * The lookup key for a {@link android.net.NetworkInfo} object associated with the 705 * Wi-Fi network. Retrieve with 706 * {@link android.content.Intent#getParcelableExtra(String)}. 707 */ 708 public static final String EXTRA_NETWORK_INFO = "networkInfo"; 709 /** 710 * The lookup key for a String giving the BSSID of the access point to which 711 * we are connected. No longer used. 712 */ 713 @Deprecated 714 public static final String EXTRA_BSSID = "bssid"; 715 /** 716 * The lookup key for a {@link android.net.wifi.WifiInfo} object giving the 717 * information about the access point to which we are connected. 718 * No longer used. 719 */ 720 @Deprecated 721 public static final String EXTRA_WIFI_INFO = "wifiInfo"; 722 /** 723 * Broadcast intent action indicating that the state of establishing a connection to 724 * an access point has changed.One extra provides the new 725 * {@link SupplicantState}. Note that the supplicant state is Wi-Fi specific, and 726 * is not generally the most useful thing to look at if you are just interested in 727 * the overall state of connectivity. 728 * @see #EXTRA_NEW_STATE 729 * @see #EXTRA_SUPPLICANT_ERROR 730 * @deprecated This is no longer supported. 731 */ 732 @Deprecated 733 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 734 public static final String SUPPLICANT_STATE_CHANGED_ACTION = 735 "android.net.wifi.supplicant.STATE_CHANGE"; 736 /** 737 * The lookup key for a {@link SupplicantState} describing the new state 738 * Retrieve with 739 * {@link android.content.Intent#getParcelableExtra(String)}. 740 * @deprecated This is no longer supported. 741 */ 742 @Deprecated 743 public static final String EXTRA_NEW_STATE = "newState"; 744 745 /** 746 * The lookup key for a {@link SupplicantState} describing the supplicant 747 * error code if any 748 * Retrieve with 749 * {@link android.content.Intent#getIntExtra(String, int)}. 750 * @see #ERROR_AUTHENTICATING 751 * @deprecated This is no longer supported. 752 */ 753 @Deprecated 754 public static final String EXTRA_SUPPLICANT_ERROR = "supplicantError"; 755 756 /** 757 * The lookup key for a {@link SupplicantState} describing the supplicant 758 * error reason if any 759 * Retrieve with 760 * {@link android.content.Intent#getIntExtra(String, int)}. 761 * @see #ERROR_AUTH_FAILURE_#REASON_CODE 762 * @deprecated This is no longer supported. 763 * @hide 764 */ 765 @Deprecated 766 public static final String EXTRA_SUPPLICANT_ERROR_REASON = "supplicantErrorReason"; 767 768 /** 769 * Broadcast intent action indicating that the configured networks changed. 770 * This can be as a result of adding/updating/deleting a network. If 771 * {@link #EXTRA_MULTIPLE_NETWORKS_CHANGED} is set to true the new configuration 772 * can be retreived with the {@link #EXTRA_WIFI_CONFIGURATION} extra. If multiple 773 * Wi-Fi configurations changed, {@link #EXTRA_WIFI_CONFIGURATION} will not be present. 774 * @hide 775 */ 776 @SystemApi 777 public static final String CONFIGURED_NETWORKS_CHANGED_ACTION = 778 "android.net.wifi.CONFIGURED_NETWORKS_CHANGE"; 779 /** 780 * The lookup key for a (@link android.net.wifi.WifiConfiguration} object representing 781 * the changed Wi-Fi configuration when the {@link #CONFIGURED_NETWORKS_CHANGED_ACTION} 782 * broadcast is sent. 783 * @hide 784 */ 785 @SystemApi 786 public static final String EXTRA_WIFI_CONFIGURATION = "wifiConfiguration"; 787 /** 788 * Multiple network configurations have changed. 789 * @see #CONFIGURED_NETWORKS_CHANGED_ACTION 790 * 791 * @hide 792 */ 793 @SystemApi 794 public static final String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges"; 795 /** 796 * The lookup key for an integer indicating the reason a Wi-Fi network configuration 797 * has changed. Only present if {@link #EXTRA_MULTIPLE_NETWORKS_CHANGED} is {@code false} 798 * @see #CONFIGURED_NETWORKS_CHANGED_ACTION 799 * @hide 800 */ 801 @SystemApi 802 public static final String EXTRA_CHANGE_REASON = "changeReason"; 803 /** 804 * The configuration is new and was added. 805 * @hide 806 */ 807 @SystemApi 808 public static final int CHANGE_REASON_ADDED = 0; 809 /** 810 * The configuration was removed and is no longer present in the system's list of 811 * configured networks. 812 * @hide 813 */ 814 @SystemApi 815 public static final int CHANGE_REASON_REMOVED = 1; 816 /** 817 * The configuration has changed as a result of explicit action or because the system 818 * took an automated action such as disabling a malfunctioning configuration. 819 * @hide 820 */ 821 @SystemApi 822 public static final int CHANGE_REASON_CONFIG_CHANGE = 2; 823 /** 824 * An access point scan has completed, and results are available. 825 * Call {@link #getScanResults()} to obtain the results. 826 * The broadcast intent may contain an extra field with the key {@link #EXTRA_RESULTS_UPDATED} 827 * and a {@code boolean} value indicating if the scan was successful. 828 */ 829 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 830 public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS"; 831 832 /** 833 * Lookup key for a {@code boolean} extra in intent {@link #SCAN_RESULTS_AVAILABLE_ACTION} 834 * representing if the scan was successful or not. 835 * Scans may fail for multiple reasons, these may include: 836 * <ol> 837 * <li>An app requested too many scans in a certain period of time. 838 * This may lead to additional scan request rejections via "scan throttling" for both 839 * foreground and background apps. 840 * Note: Apps holding android.Manifest.permission.NETWORK_SETTINGS permission are 841 * exempted from scan throttling. 842 * </li> 843 * <li>The device is idle and scanning is disabled.</li> 844 * <li>Wifi hardware reported a scan failure.</li> 845 * </ol> 846 * @return true scan was successful, results are updated 847 * @return false scan was not successful, results haven't been updated since previous scan 848 */ 849 public static final String EXTRA_RESULTS_UPDATED = "resultsUpdated"; 850 851 /** 852 * A batch of access point scans has been completed and the results areavailable. 853 * Call {@link #getBatchedScanResults()} to obtain the results. 854 * @deprecated This API is nolonger supported. 855 * Use {@link android.net.wifi.WifiScanner} API 856 * @hide 857 */ 858 @Deprecated 859 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 860 public static final String BATCHED_SCAN_RESULTS_AVAILABLE_ACTION = 861 "android.net.wifi.BATCHED_RESULTS"; 862 863 /** 864 * The RSSI (signal strength) has changed. 865 * 866 * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE 867 * @see {@link #EXTRA_NEW_RSSI} 868 */ 869 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 870 public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED"; 871 /** 872 * The lookup key for an {@code int} giving the new RSSI in dBm. 873 */ 874 public static final String EXTRA_NEW_RSSI = "newRssi"; 875 876 /** 877 * Broadcast intent action indicating that the link configuration 878 * changed on wifi. 879 * @hide 880 */ 881 @UnsupportedAppUsage 882 public static final String LINK_CONFIGURATION_CHANGED_ACTION = 883 "android.net.wifi.LINK_CONFIGURATION_CHANGED"; 884 885 /** 886 * The lookup key for a {@link android.net.LinkProperties} object associated with the 887 * Wi-Fi network. Retrieve with 888 * {@link android.content.Intent#getParcelableExtra(String)}. 889 * @hide 890 */ 891 public static final String EXTRA_LINK_PROPERTIES = "linkProperties"; 892 893 /** 894 * The lookup key for a {@link android.net.NetworkCapabilities} object associated with the 895 * Wi-Fi network. Retrieve with 896 * {@link android.content.Intent#getParcelableExtra(String)}. 897 * @hide 898 */ 899 public static final String EXTRA_NETWORK_CAPABILITIES = "networkCapabilities"; 900 901 /** 902 * The network IDs of the configured networks could have changed. 903 */ 904 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 905 public static final String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED"; 906 907 /** 908 * Activity Action: Show a system activity that allows the user to enable 909 * scans to be available even with Wi-Fi turned off. 910 * 911 * <p>Notification of the result of this activity is posted using the 912 * {@link android.app.Activity#onActivityResult} callback. The 913 * <code>resultCode</code> 914 * will be {@link android.app.Activity#RESULT_OK} if scan always mode has 915 * been turned on or {@link android.app.Activity#RESULT_CANCELED} if the user 916 * has rejected the request or an error has occurred. 917 */ 918 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 919 public static final String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = 920 "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE"; 921 922 /** 923 * Activity Action: Pick a Wi-Fi network to connect to. 924 * <p>Input: Nothing. 925 * <p>Output: Nothing. 926 */ 927 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 928 public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK"; 929 930 /** 931 * Activity Action: Show UI to get user approval to enable WiFi. 932 * <p>Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} string extra with 933 * the name of the app requesting the action. 934 * <p>Output: Nothing. 935 * 936 * @hide 937 */ 938 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 939 public static final String ACTION_REQUEST_ENABLE = "android.net.wifi.action.REQUEST_ENABLE"; 940 941 /** 942 * Activity Action: Show UI to get user approval to disable WiFi. 943 * <p>Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} string extra with 944 * the name of the app requesting the action. 945 * <p>Output: Nothing. 946 * 947 * @hide 948 */ 949 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 950 public static final String ACTION_REQUEST_DISABLE = "android.net.wifi.action.REQUEST_DISABLE"; 951 952 /** 953 * Directed broadcast intent action indicating that the device has connected to one of the 954 * network suggestions provided by the app. This will be sent post connection to a network 955 * which was created with {@link WifiNetworkSuggestion.Builder#setIsAppInteractionRequired( 956 * boolean)} 957 * flag set. 958 * <p> 959 * Note: The broadcast is sent to the app only if it holds 960 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission. 961 * 962 * @see #EXTRA_NETWORK_SUGGESTION 963 */ 964 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 965 public static final String ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION = 966 "android.net.wifi.action.WIFI_NETWORK_SUGGESTION_POST_CONNECTION"; 967 /** 968 * Sent as as a part of {@link #ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION} that holds 969 * an instance of {@link WifiNetworkSuggestion} corresponding to the connected network. 970 */ 971 public static final String EXTRA_NETWORK_SUGGESTION = 972 "android.net.wifi.extra.NETWORK_SUGGESTION"; 973 974 /** 975 * Internally used Wi-Fi lock mode representing the case were no locks are held. 976 * @hide 977 */ 978 public static final int WIFI_MODE_NO_LOCKS_HELD = 0; 979 980 /** 981 * In this Wi-Fi lock mode, Wi-Fi will be kept active, 982 * and will behave normally, i.e., it will attempt to automatically 983 * establish a connection to a remembered access point that is 984 * within range, and will do periodic scans if there are remembered 985 * access points but none are in range. 986 * 987 * @deprecated This API is non-functional and will have no impact. 988 */ 989 @Deprecated 990 public static final int WIFI_MODE_FULL = WifiProtoEnums.WIFI_MODE_FULL; // 1 991 992 /** 993 * In this Wi-Fi lock mode, Wi-Fi will be kept active, 994 * but the only operation that will be supported is initiation of 995 * scans, and the subsequent reporting of scan results. No attempts 996 * will be made to automatically connect to remembered access points, 997 * nor will periodic scans be automatically performed looking for 998 * remembered access points. Scans must be explicitly requested by 999 * an application in this mode. 1000 * 1001 * @deprecated This API is non-functional and will have no impact. 1002 */ 1003 @Deprecated 1004 public static final int WIFI_MODE_SCAN_ONLY = WifiProtoEnums.WIFI_MODE_SCAN_ONLY; // 2 1005 1006 /** 1007 * In this Wi-Fi lock mode, Wi-Fi will not go to power save. 1008 * This results in operating with low packet latency. 1009 * The lock is only active when the device is connected to an access point. 1010 * The lock is active even when the device screen is off or the acquiring application is 1011 * running in the background. 1012 * This mode will consume more power and hence should be used only 1013 * when there is a need for this tradeoff. 1014 * <p> 1015 * An example use case is when a voice connection needs to be 1016 * kept active even after the device screen goes off. 1017 * Holding a {@link #WIFI_MODE_FULL_HIGH_PERF} lock for the 1018 * duration of the voice call may improve the call quality. 1019 * <p> 1020 * When there is no support from the hardware, the {@link #WIFI_MODE_FULL_HIGH_PERF} 1021 * lock will have no impact. 1022 */ 1023 public static final int WIFI_MODE_FULL_HIGH_PERF = WifiProtoEnums.WIFI_MODE_FULL_HIGH_PERF; // 3 1024 1025 /** 1026 * In this Wi-Fi lock mode, Wi-Fi will operate with a priority to achieve low latency. 1027 * {@link #WIFI_MODE_FULL_LOW_LATENCY} lock has the following limitations: 1028 * <ol> 1029 * <li>The lock is only active when the device is connected to an access point.</li> 1030 * <li>The lock is only active when the screen is on.</li> 1031 * <li>The lock is only active when the acquiring app is running in the foreground.</li> 1032 * </ol> 1033 * Low latency mode optimizes for reduced packet latency, 1034 * and as a result other performance measures may suffer when there are trade-offs to make: 1035 * <ol> 1036 * <li>Battery life may be reduced.</li> 1037 * <li>Throughput may be reduced.</li> 1038 * <li>Frequency of Wi-Fi scanning may be reduced. This may result in: </li> 1039 * <ul> 1040 * <li>The device may not roam or switch to the AP with highest signal quality.</li> 1041 * <li>Location accuracy may be reduced.</li> 1042 * </ul> 1043 * </ol> 1044 * <p> 1045 * Example use cases are real time gaming or virtual reality applications where 1046 * low latency is a key factor for user experience. 1047 * <p> 1048 * Note: For an app which acquires both {@link #WIFI_MODE_FULL_LOW_LATENCY} and 1049 * {@link #WIFI_MODE_FULL_HIGH_PERF} locks, {@link #WIFI_MODE_FULL_LOW_LATENCY} 1050 * lock will be effective when app is running in foreground and screen is on, 1051 * while the {@link #WIFI_MODE_FULL_HIGH_PERF} lock will take effect otherwise. 1052 */ 1053 public static final int WIFI_MODE_FULL_LOW_LATENCY = 1054 WifiProtoEnums.WIFI_MODE_FULL_LOW_LATENCY; // 4 1055 1056 /** Anything worse than or equal to this will show 0 bars. */ 1057 @UnsupportedAppUsage 1058 private static final int MIN_RSSI = -100; 1059 1060 /** Anything better than or equal to this will show the max bars. */ 1061 @UnsupportedAppUsage 1062 private static final int MAX_RSSI = -55; 1063 1064 /** 1065 * Number of RSSI levels used in the framework to initiate 1066 * {@link #RSSI_CHANGED_ACTION} broadcast 1067 * @hide 1068 */ 1069 @UnsupportedAppUsage 1070 public static final int RSSI_LEVELS = 5; 1071 1072 /** 1073 * Auto settings in the driver. The driver could choose to operate on both 1074 * 2.4 GHz and 5 GHz or make a dynamic decision on selecting the band. 1075 * @hide 1076 */ 1077 @UnsupportedAppUsage 1078 public static final int WIFI_FREQUENCY_BAND_AUTO = 0; 1079 1080 /** 1081 * Operation on 5 GHz alone 1082 * @hide 1083 */ 1084 @UnsupportedAppUsage 1085 public static final int WIFI_FREQUENCY_BAND_5GHZ = 1; 1086 1087 /** 1088 * Operation on 2.4 GHz alone 1089 * @hide 1090 */ 1091 @UnsupportedAppUsage 1092 public static final int WIFI_FREQUENCY_BAND_2GHZ = 2; 1093 1094 /** @hide */ 1095 public static final boolean DEFAULT_POOR_NETWORK_AVOIDANCE_ENABLED = false; 1096 1097 /* Maximum number of active locks we allow. 1098 * This limit was added to prevent apps from creating a ridiculous number 1099 * of locks and crashing the system by overflowing the global ref table. 1100 */ 1101 private static final int MAX_ACTIVE_LOCKS = 50; 1102 1103 /* Number of currently active WifiLocks and MulticastLocks */ 1104 @UnsupportedAppUsage 1105 private int mActiveLockCount; 1106 1107 private Context mContext; 1108 @UnsupportedAppUsage 1109 IWifiManager mService; 1110 private final int mTargetSdkVersion; 1111 1112 private static final int INVALID_KEY = 0; 1113 private int mListenerKey = 1; 1114 private final SparseArray mListenerMap = new SparseArray(); 1115 private final Object mListenerMapLock = new Object(); 1116 1117 private AsyncChannel mAsyncChannel; 1118 private CountDownLatch mConnected; 1119 private Looper mLooper; 1120 private boolean mVerboseLoggingEnabled = false; 1121 1122 /* LocalOnlyHotspot callback message types */ 1123 /** @hide */ 1124 public static final int HOTSPOT_STARTED = 0; 1125 /** @hide */ 1126 public static final int HOTSPOT_STOPPED = 1; 1127 /** @hide */ 1128 public static final int HOTSPOT_FAILED = 2; 1129 /** @hide */ 1130 public static final int HOTSPOT_OBSERVER_REGISTERED = 3; 1131 1132 private final Object mLock = new Object(); // lock guarding access to the following vars 1133 @GuardedBy("mLock") 1134 private LocalOnlyHotspotCallbackProxy mLOHSCallbackProxy; 1135 @GuardedBy("mLock") 1136 private LocalOnlyHotspotObserverProxy mLOHSObserverProxy; 1137 1138 /** 1139 * Create a new WifiManager instance. 1140 * Applications will almost always want to use 1141 * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve 1142 * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}. 1143 * @param context the application context 1144 * @param service the Binder interface 1145 * @hide - hide this because it takes in a parameter of type IWifiManager, which 1146 * is a system private class. 1147 */ WifiManager(Context context, IWifiManager service, Looper looper)1148 public WifiManager(Context context, IWifiManager service, Looper looper) { 1149 mContext = context; 1150 mService = service; 1151 mLooper = looper; 1152 mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion; 1153 updateVerboseLoggingEnabledFromService(); 1154 } 1155 1156 /** 1157 * Return a list of all the networks configured for the current foreground 1158 * user. 1159 * 1160 * Not all fields of WifiConfiguration are returned. Only the following 1161 * fields are filled in: 1162 * <ul> 1163 * <li>networkId</li> 1164 * <li>SSID</li> 1165 * <li>BSSID</li> 1166 * <li>priority</li> 1167 * <li>allowedProtocols</li> 1168 * <li>allowedKeyManagement</li> 1169 * <li>allowedAuthAlgorithms</li> 1170 * <li>allowedPairwiseCiphers</li> 1171 * <li>allowedGroupCiphers</li> 1172 * </ul> 1173 * @return a list of network configurations in the form of a list 1174 * of {@link WifiConfiguration} objects. 1175 * 1176 * @deprecated 1177 * a) See {@link WifiNetworkSpecifier.Builder#build()} for new 1178 * mechanism to trigger connection to a Wi-Fi network. 1179 * b) See {@link #addNetworkSuggestions(List)}, 1180 * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration 1181 * when auto-connecting to wifi. 1182 * <b>Compatibility Note:</b> For applications targeting 1183 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will return an empty list, 1184 * except for: 1185 * <ul> 1186 * <li>Device Owner (DO) & Profile Owner (PO) apps will have access to the full list. 1187 * <li>Callers with Carrier privilege will receive a restricted list only containing 1188 * configurations which they created. 1189 * </ul> 1190 */ 1191 @Deprecated 1192 @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE}) getConfiguredNetworks()1193 public List<WifiConfiguration> getConfiguredNetworks() { 1194 try { 1195 ParceledListSlice<WifiConfiguration> parceledList = 1196 mService.getConfiguredNetworks(mContext.getOpPackageName()); 1197 if (parceledList == null) { 1198 return Collections.emptyList(); 1199 } 1200 return parceledList.getList(); 1201 } catch (RemoteException e) { 1202 throw e.rethrowFromSystemServer(); 1203 } 1204 } 1205 1206 /** @hide */ 1207 @SystemApi 1208 @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE, READ_WIFI_CREDENTIAL}) getPrivilegedConfiguredNetworks()1209 public List<WifiConfiguration> getPrivilegedConfiguredNetworks() { 1210 try { 1211 ParceledListSlice<WifiConfiguration> parceledList = 1212 mService.getPrivilegedConfiguredNetworks(mContext.getOpPackageName()); 1213 if (parceledList == null) { 1214 return Collections.emptyList(); 1215 } 1216 return parceledList.getList(); 1217 } catch (RemoteException e) { 1218 throw e.rethrowFromSystemServer(); 1219 } 1220 } 1221 1222 /** 1223 * Returns a list of all matching WifiConfigurations for a given list of ScanResult. 1224 * 1225 * An empty list will be returned when no configurations are installed or if no configurations 1226 * match the ScanResult. 1227 * 1228 * @param scanResults a list of scanResult that represents the BSSID 1229 * @return List that consists of {@link WifiConfiguration} and corresponding scanResults per 1230 * network type({@link #PASSPOINT_HOME_NETWORK} and {@link #PASSPOINT_ROAMING_NETWORK}). 1231 * @hide 1232 */ 1233 @SystemApi 1234 @RequiresPermission(anyOf = { 1235 android.Manifest.permission.NETWORK_SETTINGS, 1236 android.Manifest.permission.NETWORK_SETUP_WIZARD 1237 }) 1238 @NonNull getAllMatchingWifiConfigs( @onNull List<ScanResult> scanResults)1239 public List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> getAllMatchingWifiConfigs( 1240 @NonNull List<ScanResult> scanResults) { 1241 List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> configs = new ArrayList<>(); 1242 try { 1243 Map<String, Map<Integer, List<ScanResult>>> results = 1244 mService.getAllMatchingFqdnsForScanResults( 1245 scanResults); 1246 if (results.isEmpty()) { 1247 return configs; 1248 } 1249 List<WifiConfiguration> wifiConfigurations = 1250 mService.getWifiConfigsForPasspointProfiles( 1251 new ArrayList<>(results.keySet())); 1252 for (WifiConfiguration configuration : wifiConfigurations) { 1253 Map<Integer, List<ScanResult>> scanResultsPerNetworkType = results.get( 1254 configuration.FQDN); 1255 if (scanResultsPerNetworkType != null) { 1256 configs.add(Pair.create(configuration, scanResultsPerNetworkType)); 1257 } 1258 } 1259 } catch (RemoteException e) { 1260 throw e.rethrowFromSystemServer(); 1261 } 1262 1263 return configs; 1264 } 1265 1266 /** 1267 * Returns a list of unique Hotspot 2.0 OSU (Online Sign-Up) providers associated with a given 1268 * list of ScanResult. 1269 * 1270 * An empty list will be returned if no match is found. 1271 * 1272 * @param scanResults a list of ScanResult 1273 * @return Map that consists {@link OsuProvider} and a list of matching {@link ScanResult} 1274 * @hide 1275 */ 1276 @SystemApi 1277 @RequiresPermission(anyOf = { 1278 android.Manifest.permission.NETWORK_SETTINGS, 1279 android.Manifest.permission.NETWORK_SETUP_WIZARD 1280 }) 1281 @NonNull getMatchingOsuProviders( @ullable List<ScanResult> scanResults)1282 public Map<OsuProvider, List<ScanResult>> getMatchingOsuProviders( 1283 @Nullable List<ScanResult> scanResults) { 1284 if (scanResults == null) { 1285 return new HashMap<>(); 1286 } 1287 try { 1288 return mService.getMatchingOsuProviders(scanResults); 1289 } catch (RemoteException e) { 1290 throw e.rethrowFromSystemServer(); 1291 } 1292 } 1293 1294 /** 1295 * Returns the matching Passpoint R2 configurations for given OSU (Online Sign-Up) providers. 1296 * 1297 * Given a list of OSU providers, this only returns OSU providers that already have Passpoint R2 1298 * configurations in the device. 1299 * An empty map will be returned when there is no matching Passpoint R2 configuration for the 1300 * given OsuProviders. 1301 * 1302 * @param osuProviders a set of {@link OsuProvider} 1303 * @return Map that consists of {@link OsuProvider} and matching {@link PasspointConfiguration}. 1304 * @hide 1305 */ 1306 @SystemApi 1307 @RequiresPermission(anyOf = { 1308 android.Manifest.permission.NETWORK_SETTINGS, 1309 android.Manifest.permission.NETWORK_SETUP_WIZARD 1310 }) 1311 @NonNull getMatchingPasspointConfigsForOsuProviders( @onNull Set<OsuProvider> osuProviders)1312 public Map<OsuProvider, PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders( 1313 @NonNull Set<OsuProvider> osuProviders) { 1314 try { 1315 return mService.getMatchingPasspointConfigsForOsuProviders( 1316 new ArrayList<>(osuProviders)); 1317 } catch (RemoteException e) { 1318 throw e.rethrowFromSystemServer(); 1319 } 1320 } 1321 1322 /** 1323 * Add a new network description to the set of configured networks. 1324 * The {@code networkId} field of the supplied configuration object 1325 * is ignored. 1326 * <p/> 1327 * The new network will be marked DISABLED by default. To enable it, 1328 * called {@link #enableNetwork}. 1329 * 1330 * @param config the set of variables that describe the configuration, 1331 * contained in a {@link WifiConfiguration} object. 1332 * If the {@link WifiConfiguration} has an Http Proxy set 1333 * the calling app must be System, or be provisioned as the Profile or Device Owner. 1334 * @return the ID of the newly created network description. This is used in 1335 * other operations to specified the network to be acted upon. 1336 * Returns {@code -1} on failure. 1337 * 1338 * @deprecated 1339 * a) See {@link WifiNetworkSpecifier.Builder#build()} for new 1340 * mechanism to trigger connection to a Wi-Fi network. 1341 * b) See {@link #addNetworkSuggestions(List)}, 1342 * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration 1343 * when auto-connecting to wifi. 1344 * <b>Compatibility Note:</b> For applications targeting 1345 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return {@code -1}. 1346 */ 1347 @Deprecated addNetwork(WifiConfiguration config)1348 public int addNetwork(WifiConfiguration config) { 1349 if (config == null) { 1350 return -1; 1351 } 1352 config.networkId = -1; 1353 return addOrUpdateNetwork(config); 1354 } 1355 1356 /** 1357 * Update the network description of an existing configured network. 1358 * 1359 * @param config the set of variables that describe the configuration, 1360 * contained in a {@link WifiConfiguration} object. It may 1361 * be sparse, so that only the items that are being changed 1362 * are non-<code>null</code>. The {@code networkId} field 1363 * must be set to the ID of the existing network being updated. 1364 * If the {@link WifiConfiguration} has an Http Proxy set 1365 * the calling app must be System, or be provisioned as the Profile or Device Owner. 1366 * @return Returns the {@code networkId} of the supplied 1367 * {@code WifiConfiguration} on success. 1368 * <br/> 1369 * Returns {@code -1} on failure, including when the {@code networkId} 1370 * field of the {@code WifiConfiguration} does not refer to an 1371 * existing network. 1372 * 1373 * @deprecated 1374 * a) See {@link WifiNetworkSpecifier.Builder#build()} for new 1375 * mechanism to trigger connection to a Wi-Fi network. 1376 * b) See {@link #addNetworkSuggestions(List)}, 1377 * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration 1378 * when auto-connecting to wifi. 1379 * <b>Compatibility Note:</b> For applications targeting 1380 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return {@code -1}. 1381 */ 1382 @Deprecated updateNetwork(WifiConfiguration config)1383 public int updateNetwork(WifiConfiguration config) { 1384 if (config == null || config.networkId < 0) { 1385 return -1; 1386 } 1387 return addOrUpdateNetwork(config); 1388 } 1389 1390 /** 1391 * Internal method for doing the RPC that creates a new network description 1392 * or updates an existing one. 1393 * 1394 * @param config The possibly sparse object containing the variables that 1395 * are to set or updated in the network description. 1396 * @return the ID of the network on success, {@code -1} on failure. 1397 */ addOrUpdateNetwork(WifiConfiguration config)1398 private int addOrUpdateNetwork(WifiConfiguration config) { 1399 try { 1400 return mService.addOrUpdateNetwork(config, mContext.getOpPackageName()); 1401 } catch (RemoteException e) { 1402 throw e.rethrowFromSystemServer(); 1403 } 1404 } 1405 1406 /** 1407 * Interface for indicating user selection from the list of networks presented in the 1408 * {@link NetworkRequestMatchCallback#onMatch(List)}. 1409 * 1410 * The platform will implement this callback and pass it along with the 1411 * {@link NetworkRequestMatchCallback#onUserSelectionCallbackRegistration( 1412 * NetworkRequestUserSelectionCallback)}. The UI component handling 1413 * {@link NetworkRequestMatchCallback} will invoke {@link #select(WifiConfiguration)} or 1414 * {@link #reject()} to return the user's selection back to the platform via this callback. 1415 * @hide 1416 */ 1417 public interface NetworkRequestUserSelectionCallback { 1418 /** 1419 * User selected this network to connect to. 1420 * @param wifiConfiguration WifiConfiguration object corresponding to the network 1421 * user selected. 1422 */ select(@onNull WifiConfiguration wifiConfiguration)1423 void select(@NonNull WifiConfiguration wifiConfiguration); 1424 1425 /** 1426 * User rejected the app's request. 1427 */ reject()1428 void reject(); 1429 } 1430 1431 /** 1432 * Interface for network request callback. Should be implemented by applications and passed when 1433 * calling {@link #registerNetworkRequestMatchCallback(NetworkRequestMatchCallback, Handler)}. 1434 * 1435 * This is meant to be implemented by a UI component to present the user with a list of networks 1436 * matching the app's request. The user is allowed to pick one of these networks to connect to 1437 * or reject the request by the app. 1438 * @hide 1439 */ 1440 public interface NetworkRequestMatchCallback { 1441 /** 1442 * Invoked to register a callback to be invoked to convey user selection. The callback 1443 * object paased in this method is to be invoked by the UI component after the service sends 1444 * a list of matching scan networks using {@link #onMatch(List)} and user picks a network 1445 * from that list. 1446 * 1447 * @param userSelectionCallback Callback object to send back the user selection. 1448 */ onUserSelectionCallbackRegistration( @onNull NetworkRequestUserSelectionCallback userSelectionCallback)1449 void onUserSelectionCallbackRegistration( 1450 @NonNull NetworkRequestUserSelectionCallback userSelectionCallback); 1451 1452 /** 1453 * Invoked when the active network request is aborted, either because 1454 * <li> The app released the request, OR</li> 1455 * <li> Request was overridden by a new request</li> 1456 * This signals the end of processing for the current request and should stop the UI 1457 * component. No subsequent calls from the UI component will be handled by the platform. 1458 */ onAbort()1459 void onAbort(); 1460 1461 /** 1462 * Invoked when a network request initiated by an app matches some networks in scan results. 1463 * This may be invoked multiple times for a single network request as the platform finds new 1464 * matching networks in scan results. 1465 * 1466 * @param scanResults List of {@link ScanResult} objects corresponding to the networks 1467 * matching the request. 1468 */ onMatch(@onNull List<ScanResult> scanResults)1469 void onMatch(@NonNull List<ScanResult> scanResults); 1470 1471 /** 1472 * Invoked on a successful connection with the network that the user selected 1473 * via {@link NetworkRequestUserSelectionCallback}. 1474 * 1475 * @param wifiConfiguration WifiConfiguration object corresponding to the network that the 1476 * user selected. 1477 */ onUserSelectionConnectSuccess(@onNull WifiConfiguration wifiConfiguration)1478 void onUserSelectionConnectSuccess(@NonNull WifiConfiguration wifiConfiguration); 1479 1480 /** 1481 * Invoked on failure to establish connection with the network that the user selected 1482 * via {@link NetworkRequestUserSelectionCallback}. 1483 * 1484 * @param wifiConfiguration WifiConfiguration object corresponding to the network 1485 * user selected. 1486 */ onUserSelectionConnectFailure(@onNull WifiConfiguration wifiConfiguration)1487 void onUserSelectionConnectFailure(@NonNull WifiConfiguration wifiConfiguration); 1488 } 1489 1490 /** 1491 * Callback proxy for NetworkRequestUserSelectionCallback objects. 1492 * @hide 1493 */ 1494 private class NetworkRequestUserSelectionCallbackProxy implements 1495 NetworkRequestUserSelectionCallback { 1496 private final INetworkRequestUserSelectionCallback mCallback; 1497 NetworkRequestUserSelectionCallbackProxy( INetworkRequestUserSelectionCallback callback)1498 NetworkRequestUserSelectionCallbackProxy( 1499 INetworkRequestUserSelectionCallback callback) { 1500 mCallback = callback; 1501 } 1502 1503 @Override select(@onNull WifiConfiguration wifiConfiguration)1504 public void select(@NonNull WifiConfiguration wifiConfiguration) { 1505 if (mVerboseLoggingEnabled) { 1506 Log.v(TAG, "NetworkRequestUserSelectionCallbackProxy: select " 1507 + "wificonfiguration: " + wifiConfiguration); 1508 } 1509 try { 1510 mCallback.select(wifiConfiguration); 1511 } catch (RemoteException e) { 1512 Log.e(TAG, "Failed to invoke onSelected", e); 1513 throw e.rethrowFromSystemServer(); 1514 } 1515 } 1516 1517 @Override reject()1518 public void reject() { 1519 if (mVerboseLoggingEnabled) { 1520 Log.v(TAG, "NetworkRequestUserSelectionCallbackProxy: reject"); 1521 } 1522 try { 1523 mCallback.reject(); 1524 } catch (RemoteException e) { 1525 Log.e(TAG, "Failed to invoke onRejected", e); 1526 throw e.rethrowFromSystemServer(); 1527 } 1528 } 1529 } 1530 1531 /** 1532 * Callback proxy for NetworkRequestMatchCallback objects. 1533 * @hide 1534 */ 1535 private class NetworkRequestMatchCallbackProxy extends INetworkRequestMatchCallback.Stub { 1536 private final Handler mHandler; 1537 private final NetworkRequestMatchCallback mCallback; 1538 NetworkRequestMatchCallbackProxy(Looper looper, NetworkRequestMatchCallback callback)1539 NetworkRequestMatchCallbackProxy(Looper looper, NetworkRequestMatchCallback callback) { 1540 mHandler = new Handler(looper); 1541 mCallback = callback; 1542 } 1543 1544 @Override onUserSelectionCallbackRegistration( INetworkRequestUserSelectionCallback userSelectionCallback)1545 public void onUserSelectionCallbackRegistration( 1546 INetworkRequestUserSelectionCallback userSelectionCallback) { 1547 if (mVerboseLoggingEnabled) { 1548 Log.v(TAG, "NetworkRequestMatchCallbackProxy: " 1549 + "onUserSelectionCallbackRegistration callback: " + userSelectionCallback); 1550 } 1551 mHandler.post(() -> { 1552 mCallback.onUserSelectionCallbackRegistration( 1553 new NetworkRequestUserSelectionCallbackProxy(userSelectionCallback)); 1554 }); 1555 } 1556 1557 @Override onAbort()1558 public void onAbort() { 1559 if (mVerboseLoggingEnabled) { 1560 Log.v(TAG, "NetworkRequestMatchCallbackProxy: onAbort"); 1561 } 1562 mHandler.post(() -> { 1563 mCallback.onAbort(); 1564 }); 1565 } 1566 1567 @Override onMatch(List<ScanResult> scanResults)1568 public void onMatch(List<ScanResult> scanResults) { 1569 if (mVerboseLoggingEnabled) { 1570 Log.v(TAG, "NetworkRequestMatchCallbackProxy: onMatch scanResults: " 1571 + scanResults); 1572 } 1573 mHandler.post(() -> { 1574 mCallback.onMatch(scanResults); 1575 }); 1576 } 1577 1578 @Override onUserSelectionConnectSuccess(WifiConfiguration wifiConfiguration)1579 public void onUserSelectionConnectSuccess(WifiConfiguration wifiConfiguration) { 1580 if (mVerboseLoggingEnabled) { 1581 Log.v(TAG, "NetworkRequestMatchCallbackProxy: onUserSelectionConnectSuccess " 1582 + " wificonfiguration: " + wifiConfiguration); 1583 } 1584 mHandler.post(() -> { 1585 mCallback.onUserSelectionConnectSuccess(wifiConfiguration); 1586 }); 1587 } 1588 1589 @Override onUserSelectionConnectFailure(WifiConfiguration wifiConfiguration)1590 public void onUserSelectionConnectFailure(WifiConfiguration wifiConfiguration) { 1591 if (mVerboseLoggingEnabled) { 1592 Log.v(TAG, "NetworkRequestMatchCallbackProxy: onUserSelectionConnectFailure" 1593 + " wificonfiguration: " + wifiConfiguration); 1594 } 1595 mHandler.post(() -> { 1596 mCallback.onUserSelectionConnectFailure(wifiConfiguration); 1597 }); 1598 } 1599 } 1600 1601 /** 1602 * Registers a callback for NetworkRequest matches. See {@link NetworkRequestMatchCallback}. 1603 * Caller can unregister a previously registered callback using 1604 * {@link #unregisterNetworkRequestMatchCallback(NetworkRequestMatchCallback)} 1605 * <p> 1606 * Applications should have the 1607 * {@link android.Manifest.permission#NETWORK_SETTINGS} permission. Callers 1608 * without the permission will trigger a {@link java.lang.SecurityException}. 1609 * <p> 1610 * 1611 * @param callback Callback for network match events 1612 * @param handler The Handler on whose thread to execute the callbacks of the {@code callback} 1613 * object. If null, then the application's main thread will be used. 1614 * @hide 1615 */ 1616 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) registerNetworkRequestMatchCallback(@onNull NetworkRequestMatchCallback callback, @Nullable Handler handler)1617 public void registerNetworkRequestMatchCallback(@NonNull NetworkRequestMatchCallback callback, 1618 @Nullable Handler handler) { 1619 if (callback == null) throw new IllegalArgumentException("callback cannot be null"); 1620 Log.v(TAG, "registerNetworkRequestMatchCallback: callback=" + callback 1621 + ", handler=" + handler); 1622 1623 Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); 1624 Binder binder = new Binder(); 1625 try { 1626 mService.registerNetworkRequestMatchCallback( 1627 binder, new NetworkRequestMatchCallbackProxy(looper, callback), 1628 callback.hashCode()); 1629 } catch (RemoteException e) { 1630 throw e.rethrowFromSystemServer(); 1631 } 1632 } 1633 1634 /** 1635 * Unregisters a callback for NetworkRequest matches. See {@link NetworkRequestMatchCallback}. 1636 * <p> 1637 * Applications should have the 1638 * {@link android.Manifest.permission#NETWORK_SETTINGS} permission. Callers 1639 * without the permission will trigger a {@link java.lang.SecurityException}. 1640 * <p> 1641 * 1642 * @param callback Callback for network match events 1643 * @hide 1644 */ 1645 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) unregisterNetworkRequestMatchCallback( @onNull NetworkRequestMatchCallback callback)1646 public void unregisterNetworkRequestMatchCallback( 1647 @NonNull NetworkRequestMatchCallback callback) { 1648 if (callback == null) throw new IllegalArgumentException("callback cannot be null"); 1649 Log.v(TAG, "unregisterNetworkRequestMatchCallback: callback=" + callback); 1650 1651 try { 1652 mService.unregisterNetworkRequestMatchCallback(callback.hashCode()); 1653 } catch (RemoteException e) { 1654 throw e.rethrowFromSystemServer(); 1655 } 1656 } 1657 1658 /** 1659 * Provide a list of network suggestions to the device. See {@link WifiNetworkSuggestion} 1660 * for a detailed explanation of the parameters. 1661 * When the device decides to connect to one of the provided network suggestions, platform sends 1662 * a directed broadcast {@link #ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION} to the app if 1663 * the network was created with {@link WifiNetworkSuggestion.Builder 1664 * #setIsAppInteractionRequired()} flag set and the app holds 1665 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission. 1666 *<p> 1667 * NOTE: 1668 * <li> These networks are just a suggestion to the platform. The platform will ultimately 1669 * decide on which network the device connects to. </li> 1670 * <li> When an app is uninstalled, all its suggested networks are discarded. If the device is 1671 * currently connected to a suggested network which is being removed then the device will 1672 * disconnect from that network.</li> 1673 * <li> No in-place modification of existing suggestions are allowed. Apps are expected to 1674 * remove suggestions using {@link #removeNetworkSuggestions(List)} and then add the modified 1675 * suggestion back using this API.</li> 1676 * 1677 * @param networkSuggestions List of network suggestions provided by the app. 1678 * @return Status code for the operation. One of the STATUS_NETWORK_SUGGESTIONS_ values. 1679 * {@link WifiNetworkSuggestion#equals(Object)} any previously provided suggestions by the app. 1680 * @throws {@link SecurityException} if the caller is missing required permissions. 1681 */ 1682 @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) addNetworkSuggestions( @onNull List<WifiNetworkSuggestion> networkSuggestions)1683 public @NetworkSuggestionsStatusCode int addNetworkSuggestions( 1684 @NonNull List<WifiNetworkSuggestion> networkSuggestions) { 1685 try { 1686 return mService.addNetworkSuggestions(networkSuggestions, mContext.getOpPackageName()); 1687 } catch (RemoteException e) { 1688 throw e.rethrowFromSystemServer(); 1689 } 1690 } 1691 1692 /** 1693 * Remove some or all of the network suggestions that were previously provided by the app. 1694 * See {@link WifiNetworkSuggestion} for a detailed explanation of the parameters. 1695 * See {@link WifiNetworkSuggestion#equals(Object)} for the equivalence evaluation used. 1696 * 1697 * @param networkSuggestions List of network suggestions to be removed. Pass an empty list 1698 * to remove all the previous suggestions provided by the app. 1699 * @return Status code for the operation. One of the STATUS_NETWORK_SUGGESTIONS_ values. 1700 * Any matching suggestions are removed from the device and will not be considered for any 1701 * further connection attempts. 1702 */ 1703 @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) removeNetworkSuggestions( @onNull List<WifiNetworkSuggestion> networkSuggestions)1704 public @NetworkSuggestionsStatusCode int removeNetworkSuggestions( 1705 @NonNull List<WifiNetworkSuggestion> networkSuggestions) { 1706 try { 1707 return mService.removeNetworkSuggestions( 1708 networkSuggestions, mContext.getOpPackageName()); 1709 } catch (RemoteException e) { 1710 throw e.rethrowFromSystemServer(); 1711 } 1712 } 1713 1714 /** 1715 * Returns the max number of network suggestions that are allowed per app on the device. 1716 * @see #addNetworkSuggestions(List) 1717 * @see #removeNetworkSuggestions(List) 1718 */ getMaxNumberOfNetworkSuggestionsPerApp()1719 public int getMaxNumberOfNetworkSuggestionsPerApp() { 1720 return NETWORK_SUGGESTIONS_MAX_PER_APP; 1721 } 1722 1723 /** 1724 * Add or update a Passpoint configuration. The configuration provides a credential 1725 * for connecting to Passpoint networks that are operated by the Passpoint 1726 * service provider specified in the configuration. 1727 * 1728 * Each configuration is uniquely identified by its FQDN (Fully Qualified Domain 1729 * Name). In the case when there is an existing configuration with the same 1730 * FQDN, the new configuration will replace the existing configuration. 1731 * 1732 * @param config The Passpoint configuration to be added 1733 * @throws IllegalArgumentException if configuration is invalid or Passpoint is not enabled on 1734 * the device. 1735 */ addOrUpdatePasspointConfiguration(PasspointConfiguration config)1736 public void addOrUpdatePasspointConfiguration(PasspointConfiguration config) { 1737 try { 1738 if (!mService.addOrUpdatePasspointConfiguration(config, mContext.getOpPackageName())) { 1739 throw new IllegalArgumentException(); 1740 } 1741 } catch (RemoteException e) { 1742 throw e.rethrowFromSystemServer(); 1743 } 1744 } 1745 1746 /** 1747 * Remove the Passpoint configuration identified by its FQDN (Fully Qualified Domain Name). 1748 * 1749 * @param fqdn The FQDN of the Passpoint configuration to be removed 1750 * @throws IllegalArgumentException if no configuration is associated with the given FQDN or 1751 * Passpoint is not enabled on the device. 1752 * @deprecated This is no longer supported. 1753 */ 1754 @Deprecated 1755 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) removePasspointConfiguration(String fqdn)1756 public void removePasspointConfiguration(String fqdn) { 1757 try { 1758 if (!mService.removePasspointConfiguration(fqdn, mContext.getOpPackageName())) { 1759 throw new IllegalArgumentException(); 1760 } 1761 } catch (RemoteException e) { 1762 throw e.rethrowFromSystemServer(); 1763 } 1764 } 1765 1766 /** 1767 * Return the list of installed Passpoint configurations. 1768 * 1769 * An empty list will be returned when no configurations are installed. 1770 * 1771 * @return A list of {@link PasspointConfiguration} 1772 * @deprecated This is no longer supported. 1773 */ 1774 @Deprecated 1775 @RequiresPermission(anyOf = { 1776 android.Manifest.permission.NETWORK_SETTINGS, 1777 android.Manifest.permission.NETWORK_SETUP_WIZARD 1778 }) getPasspointConfigurations()1779 public List<PasspointConfiguration> getPasspointConfigurations() { 1780 try { 1781 return mService.getPasspointConfigurations(mContext.getOpPackageName()); 1782 } catch (RemoteException e) { 1783 throw e.rethrowFromSystemServer(); 1784 } 1785 } 1786 1787 /** 1788 * Query for a Hotspot 2.0 release 2 OSU icon file. An {@link #ACTION_PASSPOINT_ICON} intent 1789 * will be broadcasted once the request is completed. The presence of the intent extra 1790 * {@link #EXTRA_ICON} will indicate the result of the request. 1791 * A missing intent extra {@link #EXTRA_ICON} will indicate a failure. 1792 * 1793 * @param bssid The BSSID of the AP 1794 * @param fileName Name of the icon file (remote file) to query from the AP 1795 * 1796 * @throws UnsupportedOperationException if Passpoint is not enabled on the device. 1797 * @hide 1798 */ queryPasspointIcon(long bssid, String fileName)1799 public void queryPasspointIcon(long bssid, String fileName) { 1800 try { 1801 mService.queryPasspointIcon(bssid, fileName); 1802 } catch (RemoteException e) { 1803 throw e.rethrowFromSystemServer(); 1804 } 1805 } 1806 1807 /** 1808 * Match the currently associated network against the SP matching the given FQDN 1809 * @param fqdn FQDN of the SP 1810 * @return ordinal [HomeProvider, RoamingProvider, Incomplete, None, Declined] 1811 * @hide 1812 */ matchProviderWithCurrentNetwork(String fqdn)1813 public int matchProviderWithCurrentNetwork(String fqdn) { 1814 try { 1815 return mService.matchProviderWithCurrentNetwork(fqdn); 1816 } catch (RemoteException e) { 1817 throw e.rethrowFromSystemServer(); 1818 } 1819 } 1820 1821 /** 1822 * Deauthenticate and set the re-authentication hold off time for the current network 1823 * @param holdoff hold off time in milliseconds 1824 * @param ess set if the hold off pertains to an ESS rather than a BSS 1825 * @hide 1826 */ deauthenticateNetwork(long holdoff, boolean ess)1827 public void deauthenticateNetwork(long holdoff, boolean ess) { 1828 try { 1829 mService.deauthenticateNetwork(holdoff, ess); 1830 } catch (RemoteException e) { 1831 throw e.rethrowFromSystemServer(); 1832 } 1833 } 1834 1835 /** 1836 * Remove the specified network from the list of configured networks. 1837 * This may result in the asynchronous delivery of state change 1838 * events. 1839 * 1840 * Applications are not allowed to remove networks created by other 1841 * applications. 1842 * 1843 * @param netId the ID of the network as returned by {@link #addNetwork} or {@link 1844 * #getConfiguredNetworks}. 1845 * @return {@code true} if the operation succeeded 1846 * 1847 * @deprecated 1848 * a) See {@link WifiNetworkSpecifier.Builder#build()} for new 1849 * mechanism to trigger connection to a Wi-Fi network. 1850 * b) See {@link #addNetworkSuggestions(List)}, 1851 * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration 1852 * when auto-connecting to wifi. 1853 * <b>Compatibility Note:</b> For applications targeting 1854 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false. 1855 */ 1856 @Deprecated removeNetwork(int netId)1857 public boolean removeNetwork(int netId) { 1858 try { 1859 return mService.removeNetwork(netId, mContext.getOpPackageName()); 1860 } catch (RemoteException e) { 1861 throw e.rethrowFromSystemServer(); 1862 } 1863 } 1864 1865 /** 1866 * Allow a previously configured network to be associated with. If 1867 * <code>attemptConnect</code> is true, an attempt to connect to the selected 1868 * network is initiated. This may result in the asynchronous delivery 1869 * of state change events. 1870 * <p> 1871 * <b>Note:</b> Network communication may not use Wi-Fi even if Wi-Fi is connected; 1872 * traffic may instead be sent through another network, such as cellular data, 1873 * Bluetooth tethering, or Ethernet. For example, traffic will never use a 1874 * Wi-Fi network that does not provide Internet access (e.g. a wireless 1875 * printer), if another network that does offer Internet access (e.g. 1876 * cellular data) is available. Applications that need to ensure that their 1877 * network traffic uses Wi-Fi should use APIs such as 1878 * {@link Network#bindSocket(java.net.Socket)}, 1879 * {@link Network#openConnection(java.net.URL)}, or 1880 * {@link ConnectivityManager#bindProcessToNetwork} to do so. 1881 * 1882 * Applications are not allowed to enable networks created by other 1883 * applications. 1884 * 1885 * @param netId the ID of the network as returned by {@link #addNetwork} or {@link 1886 * #getConfiguredNetworks}. 1887 * @param attemptConnect The way to select a particular network to connect to is specify 1888 * {@code true} for this parameter. 1889 * @return {@code true} if the operation succeeded 1890 * 1891 * @deprecated 1892 * a) See {@link WifiNetworkSpecifier.Builder#build()} for new 1893 * mechanism to trigger connection to a Wi-Fi network. 1894 * b) See {@link #addNetworkSuggestions(List)}, 1895 * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration 1896 * when auto-connecting to wifi. 1897 * <b>Compatibility Note:</b> For applications targeting 1898 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false. 1899 */ 1900 @Deprecated enableNetwork(int netId, boolean attemptConnect)1901 public boolean enableNetwork(int netId, boolean attemptConnect) { 1902 final boolean pin = attemptConnect && mTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP; 1903 if (pin) { 1904 NetworkRequest request = new NetworkRequest.Builder() 1905 .clearCapabilities() 1906 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) 1907 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) 1908 .build(); 1909 NetworkPinner.pin(mContext, request); 1910 } 1911 1912 boolean success; 1913 try { 1914 success = mService.enableNetwork(netId, attemptConnect, mContext.getOpPackageName()); 1915 } catch (RemoteException e) { 1916 throw e.rethrowFromSystemServer(); 1917 } 1918 1919 if (pin && !success) { 1920 NetworkPinner.unpin(); 1921 } 1922 1923 return success; 1924 } 1925 1926 /** 1927 * Disable a configured network. The specified network will not be 1928 * a candidate for associating. This may result in the asynchronous 1929 * delivery of state change events. 1930 * 1931 * Applications are not allowed to disable networks created by other 1932 * applications. 1933 * 1934 * @param netId the ID of the network as returned by {@link #addNetwork} or {@link 1935 * #getConfiguredNetworks}. 1936 * @return {@code true} if the operation succeeded 1937 * 1938 * @deprecated 1939 * a) See {@link WifiNetworkSpecifier.Builder#build()} for new 1940 * mechanism to trigger connection to a Wi-Fi network. 1941 * b) See {@link #addNetworkSuggestions(List)}, 1942 * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration 1943 * when auto-connecting to wifi. 1944 * <b>Compatibility Note:</b> For applications targeting 1945 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false. 1946 */ 1947 @Deprecated 1948 public boolean disableNetwork(int netId) { 1949 try { 1950 return mService.disableNetwork(netId, mContext.getOpPackageName()); 1951 } catch (RemoteException e) { 1952 throw e.rethrowFromSystemServer(); 1953 } 1954 } 1955 1956 /** 1957 * Disassociate from the currently active access point. This may result 1958 * in the asynchronous delivery of state change events. 1959 * @return {@code true} if the operation succeeded 1960 * 1961 * @deprecated 1962 * a) See {@link WifiNetworkSpecifier.Builder#build()} for new 1963 * mechanism to trigger connection to a Wi-Fi network. 1964 * b) See {@link #addNetworkSuggestions(List)}, 1965 * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration 1966 * when auto-connecting to wifi. 1967 * <b>Compatibility Note:</b> For applications targeting 1968 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false. 1969 */ 1970 @Deprecated 1971 public boolean disconnect() { 1972 try { 1973 return mService.disconnect(mContext.getOpPackageName()); 1974 } catch (RemoteException e) { 1975 throw e.rethrowFromSystemServer(); 1976 } 1977 } 1978 1979 /** 1980 * Reconnect to the currently active access point, if we are currently 1981 * disconnected. This may result in the asynchronous delivery of state 1982 * change events. 1983 * @return {@code true} if the operation succeeded 1984 * 1985 * @deprecated 1986 * a) See {@link WifiNetworkSpecifier.Builder#build()} for new 1987 * mechanism to trigger connection to a Wi-Fi network. 1988 * b) See {@link #addNetworkSuggestions(List)}, 1989 * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration 1990 * when auto-connecting to wifi. 1991 * <b>Compatibility Note:</b> For applications targeting 1992 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false. 1993 */ 1994 @Deprecated 1995 public boolean reconnect() { 1996 try { 1997 return mService.reconnect(mContext.getOpPackageName()); 1998 } catch (RemoteException e) { 1999 throw e.rethrowFromSystemServer(); 2000 } 2001 } 2002 2003 /** 2004 * Reconnect to the currently active access point, even if we are already 2005 * connected. This may result in the asynchronous delivery of state 2006 * change events. 2007 * @return {@code true} if the operation succeeded 2008 * 2009 * @deprecated 2010 * a) See {@link WifiNetworkSpecifier.Builder#build()} for new 2011 * mechanism to trigger connection to a Wi-Fi network. 2012 * b) See {@link #addNetworkSuggestions(List)}, 2013 * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration 2014 * when auto-connecting to wifi. 2015 * <b>Compatibility Note:</b> For applications targeting 2016 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false. 2017 */ 2018 @Deprecated 2019 public boolean reassociate() { 2020 try { 2021 return mService.reassociate(mContext.getOpPackageName()); 2022 } catch (RemoteException e) { 2023 throw e.rethrowFromSystemServer(); 2024 } 2025 } 2026 2027 /** 2028 * Check that the supplicant daemon is responding to requests. 2029 * @return {@code true} if we were able to communicate with the supplicant and 2030 * it returned the expected response to the PING message. 2031 * @deprecated Will return the output of {@link #isWifiEnabled()} instead. 2032 */ 2033 @Deprecated 2034 public boolean pingSupplicant() { 2035 return isWifiEnabled(); 2036 } 2037 2038 /** @hide */ 2039 public static final int WIFI_FEATURE_INFRA = 0x0001; // Basic infrastructure mode 2040 /** @hide */ 2041 public static final int WIFI_FEATURE_INFRA_5G = 0x0002; // Support for 5 GHz Band 2042 /** @hide */ 2043 public static final int WIFI_FEATURE_PASSPOINT = 0x0004; // Support for GAS/ANQP 2044 /** @hide */ 2045 public static final int WIFI_FEATURE_P2P = 0x0008; // Wifi-Direct 2046 /** @hide */ 2047 public static final int WIFI_FEATURE_MOBILE_HOTSPOT = 0x0010; // Soft AP 2048 /** @hide */ 2049 public static final int WIFI_FEATURE_SCANNER = 0x0020; // WifiScanner APIs 2050 /** @hide */ 2051 public static final int WIFI_FEATURE_AWARE = 0x0040; // Wi-Fi AWare networking 2052 /** @hide */ 2053 public static final int WIFI_FEATURE_D2D_RTT = 0x0080; // Device-to-device RTT 2054 /** @hide */ 2055 public static final int WIFI_FEATURE_D2AP_RTT = 0x0100; // Device-to-AP RTT 2056 /** @hide */ 2057 public static final int WIFI_FEATURE_BATCH_SCAN = 0x0200; // Batched Scan (deprecated) 2058 /** @hide */ 2059 public static final int WIFI_FEATURE_PNO = 0x0400; // Preferred network offload 2060 /** @hide */ 2061 public static final int WIFI_FEATURE_ADDITIONAL_STA = 0x0800; // Support for two STAs 2062 /** @hide */ 2063 public static final int WIFI_FEATURE_TDLS = 0x1000; // Tunnel directed link setup 2064 /** @hide */ 2065 public static final int WIFI_FEATURE_TDLS_OFFCHANNEL = 0x2000; // Support for TDLS off channel 2066 /** @hide */ 2067 public static final int WIFI_FEATURE_EPR = 0x4000; // Enhanced power reporting 2068 /** @hide */ 2069 public static final int WIFI_FEATURE_AP_STA = 0x8000; // AP STA Concurrency 2070 /** @hide */ 2071 public static final int WIFI_FEATURE_LINK_LAYER_STATS = 0x10000; // Link layer stats collection 2072 /** @hide */ 2073 public static final int WIFI_FEATURE_LOGGER = 0x20000; // WiFi Logger 2074 /** @hide */ 2075 public static final int WIFI_FEATURE_HAL_EPNO = 0x40000; // Enhanced PNO 2076 /** @hide */ 2077 public static final int WIFI_FEATURE_RSSI_MONITOR = 0x80000; // RSSI Monitor 2078 /** @hide */ 2079 public static final int WIFI_FEATURE_MKEEP_ALIVE = 0x100000; // mkeep_alive 2080 /** @hide */ 2081 public static final int WIFI_FEATURE_CONFIG_NDO = 0x200000; // ND offload 2082 /** @hide */ 2083 public static final int WIFI_FEATURE_TRANSMIT_POWER = 0x400000; // Capture transmit power 2084 /** @hide */ 2085 public static final int WIFI_FEATURE_CONTROL_ROAMING = 0x800000; // Control firmware roaming 2086 /** @hide */ 2087 public static final int WIFI_FEATURE_IE_WHITELIST = 0x1000000; // Probe IE white listing 2088 /** @hide */ 2089 public static final int WIFI_FEATURE_SCAN_RAND = 0x2000000; // Random MAC & Probe seq 2090 /** @hide */ 2091 public static final int WIFI_FEATURE_TX_POWER_LIMIT = 0x4000000; // Set Tx power limit 2092 /** @hide */ 2093 public static final int WIFI_FEATURE_WPA3_SAE = 0x8000000; // WPA3-Personal SAE 2094 /** @hide */ 2095 public static final int WIFI_FEATURE_WPA3_SUITE_B = 0x10000000; // WPA3-Enterprise Suite-B 2096 /** @hide */ 2097 public static final int WIFI_FEATURE_OWE = 0x20000000; // Enhanced Open 2098 /** @hide */ 2099 public static final int WIFI_FEATURE_LOW_LATENCY = 0x40000000; // Low Latency modes 2100 /** @hide */ 2101 public static final int WIFI_FEATURE_DPP = 0x80000000; // DPP (Easy-Connect) 2102 /** @hide */ 2103 public static final long WIFI_FEATURE_P2P_RAND_MAC = 0x100000000L; // Random P2P MAC 2104 2105 private long getSupportedFeatures() { 2106 try { 2107 return mService.getSupportedFeatures(); 2108 } catch (RemoteException e) { 2109 throw e.rethrowFromSystemServer(); 2110 } 2111 } 2112 2113 private boolean isFeatureSupported(long feature) { 2114 return (getSupportedFeatures() & feature) == feature; 2115 } 2116 /** 2117 * @return true if this adapter supports 5 GHz band 2118 */ 2119 public boolean is5GHzBandSupported() { 2120 return isFeatureSupported(WIFI_FEATURE_INFRA_5G); 2121 } 2122 2123 /** 2124 * @return true if this adapter supports Passpoint 2125 * @hide 2126 */ 2127 public boolean isPasspointSupported() { 2128 return isFeatureSupported(WIFI_FEATURE_PASSPOINT); 2129 } 2130 2131 /** 2132 * @return true if this adapter supports WifiP2pManager (Wi-Fi Direct) 2133 */ 2134 public boolean isP2pSupported() { 2135 return isFeatureSupported(WIFI_FEATURE_P2P); 2136 } 2137 2138 /** 2139 * @return true if this adapter supports portable Wi-Fi hotspot 2140 * @hide 2141 */ 2142 @SystemApi 2143 public boolean isPortableHotspotSupported() { 2144 return isFeatureSupported(WIFI_FEATURE_MOBILE_HOTSPOT); 2145 } 2146 2147 /** 2148 * @return true if this adapter supports WifiScanner APIs 2149 * @hide 2150 */ 2151 @SystemApi 2152 public boolean isWifiScannerSupported() { 2153 return isFeatureSupported(WIFI_FEATURE_SCANNER); 2154 } 2155 2156 /** 2157 * @return true if this adapter supports Neighbour Awareness Network APIs 2158 * @hide 2159 */ 2160 public boolean isWifiAwareSupported() { 2161 return isFeatureSupported(WIFI_FEATURE_AWARE); 2162 } 2163 2164 /** 2165 * @deprecated Please use {@link android.content.pm.PackageManager#hasSystemFeature(String)} 2166 * with {@link android.content.pm.PackageManager#FEATURE_WIFI_RTT} and 2167 * {@link android.content.pm.PackageManager#FEATURE_WIFI_AWARE}. 2168 * 2169 * @return true if this adapter supports Device-to-device RTT 2170 * @hide 2171 */ 2172 @Deprecated 2173 @SystemApi 2174 public boolean isDeviceToDeviceRttSupported() { 2175 return isFeatureSupported(WIFI_FEATURE_D2D_RTT); 2176 } 2177 2178 /** 2179 * @deprecated Please use {@link android.content.pm.PackageManager#hasSystemFeature(String)} 2180 * with {@link android.content.pm.PackageManager#FEATURE_WIFI_RTT}. 2181 * 2182 * @return true if this adapter supports Device-to-AP RTT 2183 */ 2184 @Deprecated 2185 public boolean isDeviceToApRttSupported() { 2186 return isFeatureSupported(WIFI_FEATURE_D2AP_RTT); 2187 } 2188 2189 /** 2190 * @return true if this adapter supports offloaded connectivity scan 2191 */ 2192 public boolean isPreferredNetworkOffloadSupported() { 2193 return isFeatureSupported(WIFI_FEATURE_PNO); 2194 } 2195 2196 /** 2197 * @return true if this adapter supports multiple simultaneous connections 2198 * @hide 2199 */ 2200 public boolean isAdditionalStaSupported() { 2201 return isFeatureSupported(WIFI_FEATURE_ADDITIONAL_STA); 2202 } 2203 2204 /** 2205 * @return true if this adapter supports Tunnel Directed Link Setup 2206 */ 2207 public boolean isTdlsSupported() { 2208 return isFeatureSupported(WIFI_FEATURE_TDLS); 2209 } 2210 2211 /** 2212 * @return true if this adapter supports Off Channel Tunnel Directed Link Setup 2213 * @hide 2214 */ 2215 public boolean isOffChannelTdlsSupported() { 2216 return isFeatureSupported(WIFI_FEATURE_TDLS_OFFCHANNEL); 2217 } 2218 2219 /** 2220 * @return true if this adapter supports advanced power/performance counters 2221 */ 2222 public boolean isEnhancedPowerReportingSupported() { 2223 return isFeatureSupported(WIFI_FEATURE_LINK_LAYER_STATS); 2224 } 2225 2226 /** 2227 * Return the record of {@link WifiActivityEnergyInfo} object that 2228 * has the activity and energy info. This can be used to ascertain what 2229 * the controller has been up to, since the last sample. 2230 * 2231 * @return a record with {@link WifiActivityEnergyInfo} or null if 2232 * report is unavailable or unsupported 2233 * @hide 2234 */ 2235 public WifiActivityEnergyInfo getControllerActivityEnergyInfo() { 2236 if (mService == null) return null; 2237 try { 2238 synchronized(this) { 2239 return mService.reportActivityInfo(); 2240 } 2241 } catch (RemoteException e) { 2242 throw e.rethrowFromSystemServer(); 2243 } 2244 } 2245 2246 /** 2247 * Request a scan for access points. Returns immediately. The availability 2248 * of the results is made known later by means of an asynchronous event sent 2249 * on completion of the scan. 2250 * <p> 2251 * To initiate a Wi-Fi scan, declare the 2252 * {@link android.Manifest.permission#CHANGE_WIFI_STATE} 2253 * permission in the manifest, and perform these steps: 2254 * </p> 2255 * <ol style="1"> 2256 * <li>Invoke the following method: 2257 * {@code ((WifiManager) getSystemService(WIFI_SERVICE)).startScan()}</li> 2258 * <li> 2259 * Register a BroadcastReceiver to listen to 2260 * {@code SCAN_RESULTS_AVAILABLE_ACTION}.</li> 2261 * <li>When a broadcast is received, call: 2262 * {@code ((WifiManager) getSystemService(WIFI_SERVICE)).getScanResults()}</li> 2263 * </ol> 2264 * @return {@code true} if the operation succeeded, i.e., the scan was initiated. 2265 * @deprecated The ability for apps to trigger scan requests will be removed in a future 2266 * release. 2267 */ 2268 @Deprecated 2269 public boolean startScan() { 2270 return startScan(null); 2271 } 2272 2273 /** @hide */ 2274 @SystemApi 2275 @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) 2276 public boolean startScan(WorkSource workSource) { 2277 try { 2278 String packageName = mContext.getOpPackageName(); 2279 return mService.startScan(packageName); 2280 } catch (RemoteException e) { 2281 throw e.rethrowFromSystemServer(); 2282 } 2283 } 2284 2285 /** 2286 * WPS has been deprecated from Client mode operation. 2287 * 2288 * @return null 2289 * @hide 2290 * @deprecated This API is deprecated 2291 */ 2292 public String getCurrentNetworkWpsNfcConfigurationToken() { 2293 return null; 2294 } 2295 2296 /** 2297 * Return dynamic information about the current Wi-Fi connection, if any is active. 2298 * <p> 2299 * In the connected state, access to the SSID and BSSID requires 2300 * the same permissions as {@link #getScanResults}. If such access is not allowed, 2301 * {@link WifiInfo#getSSID} will return {@code "<unknown ssid>"} and 2302 * {@link WifiInfo#getBSSID} will return {@code "02:00:00:00:00:00"}. 2303 * 2304 * @return the Wi-Fi information, contained in {@link WifiInfo}. 2305 */ 2306 public WifiInfo getConnectionInfo() { 2307 try { 2308 return mService.getConnectionInfo(mContext.getOpPackageName()); 2309 } catch (RemoteException e) { 2310 throw e.rethrowFromSystemServer(); 2311 } 2312 } 2313 2314 /** 2315 * Return the results of the latest access point scan. 2316 * @return the list of access points found in the most recent scan. An app must hold 2317 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission 2318 * in order to get valid results. 2319 */ 2320 public List<ScanResult> getScanResults() { 2321 try { 2322 return mService.getScanResults(mContext.getOpPackageName()); 2323 } catch (RemoteException e) { 2324 throw e.rethrowFromSystemServer(); 2325 } 2326 } 2327 2328 /** 2329 * Check if scanning is always available. 2330 * 2331 * If this return {@code true}, apps can issue {@link #startScan} and fetch scan results 2332 * even when Wi-Fi is turned off. 2333 * 2334 * To change this setting, see {@link #ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE}. 2335 * @deprecated The ability for apps to trigger scan requests will be removed in a future 2336 * release. 2337 */ 2338 @Deprecated 2339 public boolean isScanAlwaysAvailable() { 2340 try { 2341 return mService.isScanAlwaysAvailable(); 2342 } catch (RemoteException e) { 2343 throw e.rethrowFromSystemServer(); 2344 } 2345 } 2346 2347 /** 2348 * Tell the device to persist the current list of configured networks. 2349 * <p> 2350 * Note: It is possible for this method to change the network IDs of 2351 * existing networks. You should assume the network IDs can be different 2352 * after calling this method. 2353 * 2354 * @return {@code false}. 2355 * @deprecated There is no need to call this method - 2356 * {@link #addNetwork(WifiConfiguration)}, {@link #updateNetwork(WifiConfiguration)} 2357 * and {@link #removeNetwork(int)} already persist the configurations automatically. 2358 */ 2359 @Deprecated 2360 public boolean saveConfiguration() { 2361 return false; 2362 } 2363 2364 /** 2365 * Set the country code. 2366 * @param countryCode country code in ISO 3166 format. 2367 * 2368 * @hide 2369 */ 2370 public void setCountryCode(@NonNull String country) { 2371 try { 2372 mService.setCountryCode(country); 2373 } catch (RemoteException e) { 2374 throw e.rethrowFromSystemServer(); 2375 } 2376 } 2377 2378 /** 2379 * get the country code. 2380 * @return the country code in ISO 3166 format. 2381 * 2382 * @hide 2383 */ 2384 @UnsupportedAppUsage 2385 public String getCountryCode() { 2386 try { 2387 String country = mService.getCountryCode(); 2388 return country; 2389 } catch (RemoteException e) { 2390 throw e.rethrowFromSystemServer(); 2391 } 2392 } 2393 2394 /** 2395 * Check if the chipset supports dual frequency band (2.4 GHz and 5 GHz) 2396 * @return {@code true} if supported, {@code false} otherwise. 2397 * @hide 2398 */ 2399 @UnsupportedAppUsage 2400 public boolean isDualBandSupported() { 2401 try { 2402 return mService.isDualBandSupported(); 2403 } catch (RemoteException e) { 2404 throw e.rethrowFromSystemServer(); 2405 } 2406 } 2407 2408 /** 2409 * Check if the chipset requires conversion of 5GHz Only apBand to ANY. 2410 * @return {@code true} if required, {@code false} otherwise. 2411 * @hide 2412 */ 2413 public boolean isDualModeSupported() { 2414 try { 2415 return mService.needs5GHzToAnyApBandConversion(); 2416 } catch (RemoteException e) { 2417 throw e.rethrowFromSystemServer(); 2418 } 2419 } 2420 2421 /** 2422 * Return the DHCP-assigned addresses from the last successful DHCP request, 2423 * if any. 2424 * @return the DHCP information 2425 */ 2426 public DhcpInfo getDhcpInfo() { 2427 try { 2428 return mService.getDhcpInfo(); 2429 } catch (RemoteException e) { 2430 throw e.rethrowFromSystemServer(); 2431 } 2432 } 2433 2434 /** 2435 * Enable or disable Wi-Fi. 2436 * <p> 2437 * Applications must have the {@link android.Manifest.permission#CHANGE_WIFI_STATE} 2438 * permission to toggle wifi. 2439 * 2440 * @param enabled {@code true} to enable, {@code false} to disable. 2441 * @return {@code false} if the request cannot be satisfied; {@code true} indicates that wifi is 2442 * either already in the requested state, or in progress toward the requested state. 2443 * @throws {@link java.lang.SecurityException} if the caller is missing required permissions. 2444 * 2445 * @deprecated Starting with Build.VERSION_CODES#Q, applications are not allowed to 2446 * enable/disable Wi-Fi. 2447 * <b>Compatibility Note:</b> For applications targeting 2448 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return {@code false} 2449 * and will have no effect. If apps are targeting an older SDK ( 2450 * {@link android.os.Build.VERSION_CODES#P} or below), they can continue to use this API. 2451 */ 2452 @Deprecated 2453 public boolean setWifiEnabled(boolean enabled) { 2454 try { 2455 return mService.setWifiEnabled(mContext.getOpPackageName(), enabled); 2456 } catch (RemoteException e) { 2457 throw e.rethrowFromSystemServer(); 2458 } 2459 } 2460 2461 /** 2462 * Gets the Wi-Fi enabled state. 2463 * @return One of {@link #WIFI_STATE_DISABLED}, 2464 * {@link #WIFI_STATE_DISABLING}, {@link #WIFI_STATE_ENABLED}, 2465 * {@link #WIFI_STATE_ENABLING}, {@link #WIFI_STATE_UNKNOWN} 2466 * @see #isWifiEnabled() 2467 */ 2468 public int getWifiState() { 2469 try { 2470 return mService.getWifiEnabledState(); 2471 } catch (RemoteException e) { 2472 throw e.rethrowFromSystemServer(); 2473 } 2474 } 2475 2476 /** 2477 * Return whether Wi-Fi is enabled or disabled. 2478 * @return {@code true} if Wi-Fi is enabled 2479 * @see #getWifiState() 2480 */ 2481 public boolean isWifiEnabled() { 2482 return getWifiState() == WIFI_STATE_ENABLED; 2483 } 2484 2485 /** 2486 * Return TX packet counter, for CTS test of WiFi watchdog. 2487 * @param listener is the interface to receive result 2488 * 2489 * @hide for CTS test only 2490 */ 2491 public void getTxPacketCount(TxPacketCountListener listener) { 2492 getChannel().sendMessage(RSSI_PKTCNT_FETCH, 0, putListener(listener)); 2493 } 2494 2495 /** 2496 * Calculates the level of the signal. This should be used any time a signal 2497 * is being shown. 2498 * 2499 * @param rssi The power of the signal measured in RSSI. 2500 * @param numLevels The number of levels to consider in the calculated 2501 * level. 2502 * @return A level of the signal, given in the range of 0 to numLevels-1 2503 * (both inclusive). 2504 */ 2505 public static int calculateSignalLevel(int rssi, int numLevels) { 2506 if (rssi <= MIN_RSSI) { 2507 return 0; 2508 } else if (rssi >= MAX_RSSI) { 2509 return numLevels - 1; 2510 } else { 2511 float inputRange = (MAX_RSSI - MIN_RSSI); 2512 float outputRange = (numLevels - 1); 2513 return (int)((float)(rssi - MIN_RSSI) * outputRange / inputRange); 2514 } 2515 } 2516 2517 /** 2518 * Compares two signal strengths. 2519 * 2520 * @param rssiA The power of the first signal measured in RSSI. 2521 * @param rssiB The power of the second signal measured in RSSI. 2522 * @return Returns <0 if the first signal is weaker than the second signal, 2523 * 0 if the two signals have the same strength, and >0 if the first 2524 * signal is stronger than the second signal. 2525 */ 2526 public static int compareSignalLevel(int rssiA, int rssiB) { 2527 return rssiA - rssiB; 2528 } 2529 2530 /** 2531 * Call allowing ConnectivityService to update WifiService with interface mode changes. 2532 * 2533 * The possible modes include: {@link IFACE_IP_MODE_TETHERED}, 2534 * {@link IFACE_IP_MODE_LOCAL_ONLY}, 2535 * {@link IFACE_IP_MODE_CONFIGURATION_ERROR} 2536 * 2537 * @param ifaceName String name of the updated interface 2538 * @param mode int representing the new mode 2539 * 2540 * @hide 2541 */ 2542 public void updateInterfaceIpState(String ifaceName, int mode) { 2543 try { 2544 mService.updateInterfaceIpState(ifaceName, mode); 2545 } catch (RemoteException e) { 2546 throw e.rethrowFromSystemServer(); 2547 } 2548 } 2549 2550 /** 2551 * Start SoftAp mode with the specified configuration. 2552 * Note that starting in access point mode disables station 2553 * mode operation 2554 * @param wifiConfig SSID, security and channel details as 2555 * part of WifiConfiguration 2556 * @return {@code true} if the operation succeeds, {@code false} otherwise 2557 * 2558 * @hide 2559 */ 2560 public boolean startSoftAp(@Nullable WifiConfiguration wifiConfig) { 2561 try { 2562 return mService.startSoftAp(wifiConfig); 2563 } catch (RemoteException e) { 2564 throw e.rethrowFromSystemServer(); 2565 } 2566 } 2567 2568 /** 2569 * Stop SoftAp mode. 2570 * Note that stopping softap mode will restore the previous wifi mode. 2571 * @return {@code true} if the operation succeeds, {@code false} otherwise 2572 * 2573 * @hide 2574 */ 2575 public boolean stopSoftAp() { 2576 try { 2577 return mService.stopSoftAp(); 2578 } catch (RemoteException e) { 2579 throw e.rethrowFromSystemServer(); 2580 } 2581 } 2582 2583 /** 2584 * Request a local only hotspot that an application can use to communicate between co-located 2585 * devices connected to the created WiFi hotspot. The network created by this method will not 2586 * have Internet access. Each application can make a single request for the hotspot, but 2587 * multiple applications could be requesting the hotspot at the same time. When multiple 2588 * applications have successfully registered concurrently, they will be sharing the underlying 2589 * hotspot. {@link LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} is called 2590 * when the hotspot is ready for use by the application. 2591 * <p> 2592 * Each application can make a single active call to this method. The {@link 2593 * LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} callback supplies the 2594 * requestor with a {@link LocalOnlyHotspotReservation} that contains a 2595 * {@link WifiConfiguration} with the SSID, security type and credentials needed to connect 2596 * to the hotspot. Communicating this information is up to the application. 2597 * <p> 2598 * If the LocalOnlyHotspot cannot be created, the {@link LocalOnlyHotspotCallback#onFailed(int)} 2599 * method will be called. Example failures include errors bringing up the network or if 2600 * there is an incompatible operating mode. For example, if the user is currently using Wifi 2601 * Tethering to provide an upstream to another device, LocalOnlyHotspot will not start due to 2602 * an incompatible mode. The possible error codes include: 2603 * {@link LocalOnlyHotspotCallback#ERROR_NO_CHANNEL}, 2604 * {@link LocalOnlyHotspotCallback#ERROR_GENERIC}, 2605 * {@link LocalOnlyHotspotCallback#ERROR_INCOMPATIBLE_MODE} and 2606 * {@link LocalOnlyHotspotCallback#ERROR_TETHERING_DISALLOWED}. 2607 * <p> 2608 * Internally, requests will be tracked to prevent the hotspot from being torn down while apps 2609 * are still using it. The {@link LocalOnlyHotspotReservation} object passed in the {@link 2610 * LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} call should be closed when 2611 * the LocalOnlyHotspot is no longer needed using {@link LocalOnlyHotspotReservation#close()}. 2612 * Since the hotspot may be shared among multiple applications, removing the final registered 2613 * application request will trigger the hotspot teardown. This means that applications should 2614 * not listen to broadcasts containing wifi state to determine if the hotspot was stopped after 2615 * they are done using it. Additionally, once {@link LocalOnlyHotspotReservation#close()} is 2616 * called, applications will not receive callbacks of any kind. 2617 * <p> 2618 * Applications should be aware that the user may also stop the LocalOnlyHotspot through the 2619 * Settings UI; it is not guaranteed to stay up as long as there is a requesting application. 2620 * The requestors will be notified of this case via 2621 * {@link LocalOnlyHotspotCallback#onStopped()}. Other cases may arise where the hotspot is 2622 * torn down (Emergency mode, etc). Application developers should be aware that it can stop 2623 * unexpectedly, but they will receive a notification if they have properly registered. 2624 * <p> 2625 * Applications should also be aware that this network will be shared with other applications. 2626 * Applications are responsible for protecting their data on this network (e.g., TLS). 2627 * <p> 2628 * Applications need to have the following permissions to start LocalOnlyHotspot: {@link 2629 * android.Manifest.permission#CHANGE_WIFI_STATE} and {@link 2630 * android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}. Callers without 2631 * the permissions will trigger a {@link java.lang.SecurityException}. 2632 * <p> 2633 * @param callback LocalOnlyHotspotCallback for the application to receive updates about 2634 * operating status. 2635 * @param handler Handler to be used for callbacks. If the caller passes a null Handler, the 2636 * main thread will be used. 2637 */ 2638 public void startLocalOnlyHotspot(LocalOnlyHotspotCallback callback, 2639 @Nullable Handler handler) { 2640 synchronized (mLock) { 2641 Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); 2642 LocalOnlyHotspotCallbackProxy proxy = 2643 new LocalOnlyHotspotCallbackProxy(this, looper, callback); 2644 try { 2645 String packageName = mContext.getOpPackageName(); 2646 int returnCode = mService.startLocalOnlyHotspot( 2647 proxy.getMessenger(), new Binder(), packageName); 2648 if (returnCode != LocalOnlyHotspotCallback.REQUEST_REGISTERED) { 2649 // Send message to the proxy to make sure we call back on the correct thread 2650 proxy.notifyFailed(returnCode); 2651 return; 2652 } 2653 mLOHSCallbackProxy = proxy; 2654 } catch (RemoteException e) { 2655 throw e.rethrowFromSystemServer(); 2656 } 2657 } 2658 } 2659 2660 /** 2661 * Cancels a pending local only hotspot request. This can be used by the calling application to 2662 * cancel the existing request if the provided callback has not been triggered. Calling this 2663 * method will be equivalent to closing the returned LocalOnlyHotspotReservation, but it is not 2664 * explicitly required. 2665 * <p> 2666 * When cancelling this request, application developers should be aware that there may still be 2667 * outstanding local only hotspot requests and the hotspot may still start, or continue running. 2668 * Additionally, if a callback was registered, it will no longer be triggered after calling 2669 * cancel. 2670 * 2671 * @hide 2672 */ 2673 @UnsupportedAppUsage 2674 public void cancelLocalOnlyHotspotRequest() { 2675 synchronized (mLock) { 2676 stopLocalOnlyHotspot(); 2677 } 2678 } 2679 2680 /** 2681 * Method used to inform WifiService that the LocalOnlyHotspot is no longer needed. This 2682 * method is used by WifiManager to release LocalOnlyHotspotReservations held by calling 2683 * applications and removes the internal tracking for the hotspot request. When all requesting 2684 * applications are finished using the hotspot, it will be stopped and WiFi will return to the 2685 * previous operational mode. 2686 * 2687 * This method should not be called by applications. Instead, they should call the close() 2688 * method on their LocalOnlyHotspotReservation. 2689 */ 2690 private void stopLocalOnlyHotspot() { 2691 synchronized (mLock) { 2692 if (mLOHSCallbackProxy == null) { 2693 // nothing to do, the callback was already cleaned up. 2694 return; 2695 } 2696 mLOHSCallbackProxy = null; 2697 try { 2698 mService.stopLocalOnlyHotspot(); 2699 } catch (RemoteException e) { 2700 throw e.rethrowFromSystemServer(); 2701 } 2702 } 2703 } 2704 2705 /** 2706 * Allow callers (Settings UI) to watch LocalOnlyHotspot state changes. Callers will 2707 * receive a {@link LocalOnlyHotspotSubscription} object as a parameter of the 2708 * {@link LocalOnlyHotspotObserver#onRegistered(LocalOnlyHotspotSubscription)}. The registered 2709 * callers will receive the {@link LocalOnlyHotspotObserver#onStarted(WifiConfiguration)} and 2710 * {@link LocalOnlyHotspotObserver#onStopped()} callbacks. 2711 * <p> 2712 * Applications should have the 2713 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} 2714 * permission. Callers without the permission will trigger a 2715 * {@link java.lang.SecurityException}. 2716 * <p> 2717 * @param observer LocalOnlyHotspotObserver callback. 2718 * @param handler Handler to use for callbacks 2719 * 2720 * @hide 2721 */ 2722 public void watchLocalOnlyHotspot(LocalOnlyHotspotObserver observer, 2723 @Nullable Handler handler) { 2724 synchronized (mLock) { 2725 Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); 2726 mLOHSObserverProxy = new LocalOnlyHotspotObserverProxy(this, looper, observer); 2727 try { 2728 mService.startWatchLocalOnlyHotspot( 2729 mLOHSObserverProxy.getMessenger(), new Binder()); 2730 mLOHSObserverProxy.registered(); 2731 } catch (RemoteException e) { 2732 mLOHSObserverProxy = null; 2733 throw e.rethrowFromSystemServer(); 2734 } 2735 } 2736 } 2737 2738 /** 2739 * Allow callers to stop watching LocalOnlyHotspot state changes. After calling this method, 2740 * applications will no longer receive callbacks. 2741 * 2742 * @hide 2743 */ 2744 public void unregisterLocalOnlyHotspotObserver() { 2745 synchronized (mLock) { 2746 if (mLOHSObserverProxy == null) { 2747 // nothing to do, the callback was already cleaned up 2748 return; 2749 } 2750 mLOHSObserverProxy = null; 2751 try { 2752 mService.stopWatchLocalOnlyHotspot(); 2753 } catch (RemoteException e) { 2754 throw e.rethrowFromSystemServer(); 2755 } 2756 } 2757 } 2758 2759 /** 2760 * Gets the Wi-Fi enabled state. 2761 * @return One of {@link #WIFI_AP_STATE_DISABLED}, 2762 * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED}, 2763 * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED} 2764 * @see #isWifiApEnabled() 2765 * 2766 * @hide 2767 */ 2768 @SystemApi 2769 @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) 2770 public int getWifiApState() { 2771 try { 2772 return mService.getWifiApEnabledState(); 2773 } catch (RemoteException e) { 2774 throw e.rethrowFromSystemServer(); 2775 } 2776 } 2777 2778 /** 2779 * Return whether Wi-Fi AP is enabled or disabled. 2780 * @return {@code true} if Wi-Fi AP is enabled 2781 * @see #getWifiApState() 2782 * 2783 * @hide 2784 */ 2785 @SystemApi 2786 @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) 2787 public boolean isWifiApEnabled() { 2788 return getWifiApState() == WIFI_AP_STATE_ENABLED; 2789 } 2790 2791 /** 2792 * Gets the Wi-Fi AP Configuration. 2793 * @return AP details in WifiConfiguration 2794 * 2795 * @hide 2796 */ 2797 @SystemApi 2798 @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) 2799 public WifiConfiguration getWifiApConfiguration() { 2800 try { 2801 return mService.getWifiApConfiguration(); 2802 } catch (RemoteException e) { 2803 throw e.rethrowFromSystemServer(); 2804 } 2805 } 2806 2807 /** 2808 * Sets the Wi-Fi AP Configuration. The AP configuration must either be open or 2809 * WPA2 PSK networks. 2810 * @return {@code true} if the operation succeeded, {@code false} otherwise 2811 * 2812 * @hide 2813 */ 2814 @SystemApi 2815 @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) 2816 public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) { 2817 try { 2818 return mService.setWifiApConfiguration(wifiConfig, mContext.getOpPackageName()); 2819 } catch (RemoteException e) { 2820 throw e.rethrowFromSystemServer(); 2821 } 2822 } 2823 2824 /** 2825 * Method that triggers a notification to the user about a conversion to their saved AP config. 2826 * 2827 * @hide 2828 */ 2829 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) 2830 public void notifyUserOfApBandConversion() { 2831 Log.d(TAG, "apBand was converted, notify the user"); 2832 try { 2833 mService.notifyUserOfApBandConversion(mContext.getOpPackageName()); 2834 } catch (RemoteException e) { 2835 throw e.rethrowFromSystemServer(); 2836 } 2837 } 2838 2839 /** 2840 * Enable/Disable TDLS on a specific local route. 2841 * 2842 * <p> 2843 * TDLS enables two wireless endpoints to talk to each other directly 2844 * without going through the access point that is managing the local 2845 * network. It saves bandwidth and improves quality of the link. 2846 * </p> 2847 * <p> 2848 * This API enables/disables the option of using TDLS. If enabled, the 2849 * underlying hardware is free to use TDLS or a hop through the access 2850 * point. If disabled, existing TDLS session is torn down and 2851 * hardware is restricted to use access point for transferring wireless 2852 * packets. Default value for all routes is 'disabled', meaning restricted 2853 * to use access point for transferring packets. 2854 * </p> 2855 * 2856 * @param remoteIPAddress IP address of the endpoint to setup TDLS with 2857 * @param enable true = setup and false = tear down TDLS 2858 */ 2859 public void setTdlsEnabled(InetAddress remoteIPAddress, boolean enable) { 2860 try { 2861 mService.enableTdls(remoteIPAddress.getHostAddress(), enable); 2862 } catch (RemoteException e) { 2863 throw e.rethrowFromSystemServer(); 2864 } 2865 } 2866 2867 /** 2868 * Similar to {@link #setTdlsEnabled(InetAddress, boolean) }, except 2869 * this version allows you to specify remote endpoint with a MAC address. 2870 * @param remoteMacAddress MAC address of the remote endpoint such as 00:00:0c:9f:f2:ab 2871 * @param enable true = setup and false = tear down TDLS 2872 */ 2873 public void setTdlsEnabledWithMacAddress(String remoteMacAddress, boolean enable) { 2874 try { 2875 mService.enableTdlsWithMacAddress(remoteMacAddress, enable); 2876 } catch (RemoteException e) { 2877 throw e.rethrowFromSystemServer(); 2878 } 2879 } 2880 2881 /* TODO: deprecate synchronous API and open up the following API */ 2882 2883 private static final int BASE = Protocol.BASE_WIFI_MANAGER; 2884 2885 /* Commands to WifiService */ 2886 /** @hide */ 2887 public static final int CONNECT_NETWORK = BASE + 1; 2888 /** @hide */ 2889 public static final int CONNECT_NETWORK_FAILED = BASE + 2; 2890 /** @hide */ 2891 public static final int CONNECT_NETWORK_SUCCEEDED = BASE + 3; 2892 2893 /** @hide */ 2894 public static final int FORGET_NETWORK = BASE + 4; 2895 /** @hide */ 2896 public static final int FORGET_NETWORK_FAILED = BASE + 5; 2897 /** @hide */ 2898 public static final int FORGET_NETWORK_SUCCEEDED = BASE + 6; 2899 2900 /** @hide */ 2901 public static final int SAVE_NETWORK = BASE + 7; 2902 /** @hide */ 2903 public static final int SAVE_NETWORK_FAILED = BASE + 8; 2904 /** @hide */ 2905 public static final int SAVE_NETWORK_SUCCEEDED = BASE + 9; 2906 2907 /** @hide 2908 * @deprecated This is deprecated 2909 */ 2910 public static final int START_WPS = BASE + 10; 2911 /** @hide 2912 * @deprecated This is deprecated 2913 */ 2914 public static final int START_WPS_SUCCEEDED = BASE + 11; 2915 /** @hide 2916 * @deprecated This is deprecated 2917 */ 2918 public static final int WPS_FAILED = BASE + 12; 2919 /** @hide 2920 * @deprecated This is deprecated 2921 */ 2922 public static final int WPS_COMPLETED = BASE + 13; 2923 2924 /** @hide 2925 * @deprecated This is deprecated 2926 */ 2927 public static final int CANCEL_WPS = BASE + 14; 2928 /** @hide 2929 * @deprecated This is deprecated 2930 */ 2931 public static final int CANCEL_WPS_FAILED = BASE + 15; 2932 /** @hide 2933 * @deprecated This is deprecated 2934 */ 2935 public static final int CANCEL_WPS_SUCCEDED = BASE + 16; 2936 2937 /** @hide */ 2938 public static final int DISABLE_NETWORK = BASE + 17; 2939 /** @hide */ 2940 public static final int DISABLE_NETWORK_FAILED = BASE + 18; 2941 /** @hide */ 2942 public static final int DISABLE_NETWORK_SUCCEEDED = BASE + 19; 2943 2944 /** @hide */ 2945 public static final int RSSI_PKTCNT_FETCH = BASE + 20; 2946 /** @hide */ 2947 public static final int RSSI_PKTCNT_FETCH_SUCCEEDED = BASE + 21; 2948 /** @hide */ 2949 public static final int RSSI_PKTCNT_FETCH_FAILED = BASE + 22; 2950 2951 /** 2952 * Passed with {@link ActionListener#onFailure}. 2953 * Indicates that the operation failed due to an internal error. 2954 * @hide 2955 */ 2956 public static final int ERROR = 0; 2957 2958 /** 2959 * Passed with {@link ActionListener#onFailure}. 2960 * Indicates that the operation is already in progress 2961 * @hide 2962 */ 2963 public static final int IN_PROGRESS = 1; 2964 2965 /** 2966 * Passed with {@link ActionListener#onFailure}. 2967 * Indicates that the operation failed because the framework is busy and 2968 * unable to service the request 2969 * @hide 2970 */ 2971 public static final int BUSY = 2; 2972 2973 /* WPS specific errors */ 2974 /** WPS overlap detected 2975 * @deprecated This is deprecated 2976 */ 2977 public static final int WPS_OVERLAP_ERROR = 3; 2978 /** WEP on WPS is prohibited 2979 * @deprecated This is deprecated 2980 */ 2981 public static final int WPS_WEP_PROHIBITED = 4; 2982 /** TKIP only prohibited 2983 * @deprecated This is deprecated 2984 */ 2985 public static final int WPS_TKIP_ONLY_PROHIBITED = 5; 2986 /** Authentication failure on WPS 2987 * @deprecated This is deprecated 2988 */ 2989 public static final int WPS_AUTH_FAILURE = 6; 2990 /** WPS timed out 2991 * @deprecated This is deprecated 2992 */ 2993 public static final int WPS_TIMED_OUT = 7; 2994 2995 /** 2996 * Passed with {@link ActionListener#onFailure}. 2997 * Indicates that the operation failed due to invalid inputs 2998 * @hide 2999 */ 3000 public static final int INVALID_ARGS = 8; 3001 3002 /** 3003 * Passed with {@link ActionListener#onFailure}. 3004 * Indicates that the operation failed due to user permissions. 3005 * @hide 3006 */ 3007 public static final int NOT_AUTHORIZED = 9; 3008 3009 /** 3010 * Interface for callback invocation on an application action 3011 * @hide 3012 */ 3013 @SystemApi 3014 public interface ActionListener { 3015 /** 3016 * The operation succeeded. 3017 * This is called when the scan request has been validated and ready 3018 * to sent to driver. 3019 */ 3020 public void onSuccess(); 3021 /** 3022 * The operation failed. 3023 * This is called when the scan request failed. 3024 * @param reason The reason for failure could be one of the following: 3025 * {@link #REASON_INVALID_REQUEST}} is specified when scan request parameters are invalid. 3026 * {@link #REASON_NOT_AUTHORIZED} is specified when requesting app doesn't have the required 3027 * permission to request a scan. 3028 * {@link #REASON_UNSPECIFIED} is specified when driver reports a scan failure. 3029 */ 3030 public void onFailure(int reason); 3031 } 3032 3033 /** Interface for callback invocation on a start WPS action 3034 * @deprecated This is deprecated 3035 */ 3036 public static abstract class WpsCallback { 3037 3038 /** WPS start succeeded 3039 * @deprecated This API is deprecated 3040 */ 3041 public abstract void onStarted(String pin); 3042 3043 /** WPS operation completed successfully 3044 * @deprecated This API is deprecated 3045 */ 3046 public abstract void onSucceeded(); 3047 3048 /** 3049 * WPS operation failed 3050 * @param reason The reason for failure could be one of 3051 * {@link #WPS_TKIP_ONLY_PROHIBITED}, {@link #WPS_OVERLAP_ERROR}, 3052 * {@link #WPS_WEP_PROHIBITED}, {@link #WPS_TIMED_OUT} or {@link #WPS_AUTH_FAILURE} 3053 * and some generic errors. 3054 * @deprecated This API is deprecated 3055 */ 3056 public abstract void onFailed(int reason); 3057 } 3058 3059 /** Interface for callback invocation on a TX packet count poll action {@hide} */ 3060 public interface TxPacketCountListener { 3061 /** 3062 * The operation succeeded 3063 * @param count TX packet counter 3064 */ 3065 public void onSuccess(int count); 3066 /** 3067 * The operation failed 3068 * @param reason The reason for failure could be one of 3069 * {@link #ERROR}, {@link #IN_PROGRESS} or {@link #BUSY} 3070 */ 3071 public void onFailure(int reason); 3072 } 3073 3074 /** 3075 * Base class for soft AP callback. Should be extended by applications and set when calling 3076 * {@link WifiManager#registerSoftApCallback(SoftApCallback, Handler)}. 3077 * 3078 * @hide 3079 */ 3080 public interface SoftApCallback { 3081 /** 3082 * Called when soft AP state changes. 3083 * 3084 * @param state new new AP state. One of {@link #WIFI_AP_STATE_DISABLED}, 3085 * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED}, 3086 * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED} 3087 * @param failureReason reason when in failed state. One of 3088 * {@link #SAP_START_FAILURE_GENERAL}, {@link #SAP_START_FAILURE_NO_CHANNEL} 3089 */ 3090 public abstract void onStateChanged(@WifiApState int state, 3091 @SapStartFailure int failureReason); 3092 3093 /** 3094 * Called when number of connected clients to soft AP changes. 3095 * 3096 * @param numClients number of connected clients 3097 */ 3098 public abstract void onNumClientsChanged(int numClients); 3099 } 3100 3101 /** 3102 * Callback proxy for SoftApCallback objects. 3103 * 3104 * @hide 3105 */ 3106 private class SoftApCallbackProxy extends ISoftApCallback.Stub { 3107 private final Handler mHandler; 3108 private final SoftApCallback mCallback; 3109 3110 SoftApCallbackProxy(Looper looper, SoftApCallback callback) { 3111 mHandler = new Handler(looper); 3112 mCallback = callback; 3113 } 3114 3115 @Override 3116 public void onStateChanged(int state, int failureReason) { 3117 if (mVerboseLoggingEnabled) { 3118 Log.v(TAG, "SoftApCallbackProxy: onStateChanged: state=" + state 3119 + ", failureReason=" + failureReason); 3120 } 3121 mHandler.post(() -> { 3122 mCallback.onStateChanged(state, failureReason); 3123 }); 3124 } 3125 3126 @Override onNumClientsChanged(int numClients)3127 public void onNumClientsChanged(int numClients) { 3128 if (mVerboseLoggingEnabled) { 3129 Log.v(TAG, "SoftApCallbackProxy: onNumClientsChanged: numClients=" + numClients); 3130 } 3131 mHandler.post(() -> { 3132 mCallback.onNumClientsChanged(numClients); 3133 }); 3134 } 3135 } 3136 3137 /** 3138 * Registers a callback for Soft AP. See {@link SoftApCallback}. Caller will receive the current 3139 * soft AP state and number of connected devices immediately after a successful call to this API 3140 * via callback. Note that receiving an immediate WIFI_AP_STATE_FAILED value for soft AP state 3141 * indicates that the latest attempt to start soft AP has failed. Caller can unregister a 3142 * previously registered callback using {@link unregisterSoftApCallback} 3143 * <p> 3144 * Applications should have the 3145 * {@link android.Manifest.permission#NETWORK_SETTINGS NETWORK_SETTINGS} permission. Callers 3146 * without the permission will trigger a {@link java.lang.SecurityException}. 3147 * <p> 3148 * 3149 * @param callback Callback for soft AP events 3150 * @param handler The Handler on whose thread to execute the callbacks of the {@code callback} 3151 * object. If null, then the application's main thread will be used. 3152 * 3153 * @hide 3154 */ 3155 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) registerSoftApCallback(@onNull SoftApCallback callback, @Nullable Handler handler)3156 public void registerSoftApCallback(@NonNull SoftApCallback callback, 3157 @Nullable Handler handler) { 3158 if (callback == null) throw new IllegalArgumentException("callback cannot be null"); 3159 Log.v(TAG, "registerSoftApCallback: callback=" + callback + ", handler=" + handler); 3160 3161 Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); 3162 Binder binder = new Binder(); 3163 try { 3164 mService.registerSoftApCallback(binder, new SoftApCallbackProxy(looper, callback), 3165 callback.hashCode()); 3166 } catch (RemoteException e) { 3167 throw e.rethrowFromSystemServer(); 3168 } 3169 } 3170 3171 /** 3172 * Allow callers to unregister a previously registered callback. After calling this method, 3173 * applications will no longer receive soft AP events. 3174 * 3175 * @param callback Callback to unregister for soft AP events 3176 * 3177 * @hide 3178 */ 3179 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) unregisterSoftApCallback(@onNull SoftApCallback callback)3180 public void unregisterSoftApCallback(@NonNull SoftApCallback callback) { 3181 if (callback == null) throw new IllegalArgumentException("callback cannot be null"); 3182 Log.v(TAG, "unregisterSoftApCallback: callback=" + callback); 3183 3184 try { 3185 mService.unregisterSoftApCallback(callback.hashCode()); 3186 } catch (RemoteException e) { 3187 throw e.rethrowFromSystemServer(); 3188 } 3189 } 3190 3191 /** 3192 * LocalOnlyHotspotReservation that contains the {@link WifiConfiguration} for the active 3193 * LocalOnlyHotspot request. 3194 * <p> 3195 * Applications requesting LocalOnlyHotspot for sharing will receive an instance of the 3196 * LocalOnlyHotspotReservation in the 3197 * {@link LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} call. This 3198 * reservation contains the relevant {@link WifiConfiguration}. 3199 * When an application is done with the LocalOnlyHotspot, they should call {@link 3200 * LocalOnlyHotspotReservation#close()}. Once this happens, the application will not receive 3201 * any further callbacks. If the LocalOnlyHotspot is stopped due to a 3202 * user triggered mode change, applications will be notified via the {@link 3203 * LocalOnlyHotspotCallback#onStopped()} callback. 3204 */ 3205 public class LocalOnlyHotspotReservation implements AutoCloseable { 3206 3207 private final CloseGuard mCloseGuard = CloseGuard.get(); 3208 private final WifiConfiguration mConfig; 3209 3210 /** @hide */ 3211 @VisibleForTesting LocalOnlyHotspotReservation(WifiConfiguration config)3212 public LocalOnlyHotspotReservation(WifiConfiguration config) { 3213 mConfig = config; 3214 mCloseGuard.open("close"); 3215 } 3216 getWifiConfiguration()3217 public WifiConfiguration getWifiConfiguration() { 3218 return mConfig; 3219 } 3220 3221 @Override close()3222 public void close() { 3223 try { 3224 stopLocalOnlyHotspot(); 3225 mCloseGuard.close(); 3226 } catch (Exception e) { 3227 Log.e(TAG, "Failed to stop Local Only Hotspot."); 3228 } 3229 } 3230 3231 @Override finalize()3232 protected void finalize() throws Throwable { 3233 try { 3234 if (mCloseGuard != null) { 3235 mCloseGuard.warnIfOpen(); 3236 } 3237 close(); 3238 } finally { 3239 super.finalize(); 3240 } 3241 } 3242 } 3243 3244 /** 3245 * Callback class for applications to receive updates about the LocalOnlyHotspot status. 3246 */ 3247 public static class LocalOnlyHotspotCallback { 3248 /** @hide */ 3249 public static final int REQUEST_REGISTERED = 0; 3250 3251 public static final int ERROR_NO_CHANNEL = 1; 3252 public static final int ERROR_GENERIC = 2; 3253 public static final int ERROR_INCOMPATIBLE_MODE = 3; 3254 public static final int ERROR_TETHERING_DISALLOWED = 4; 3255 3256 /** LocalOnlyHotspot start succeeded. */ onStarted(LocalOnlyHotspotReservation reservation)3257 public void onStarted(LocalOnlyHotspotReservation reservation) {}; 3258 3259 /** 3260 * LocalOnlyHotspot stopped. 3261 * <p> 3262 * The LocalOnlyHotspot can be disabled at any time by the user. When this happens, 3263 * applications will be notified that it was stopped. This will not be invoked when an 3264 * application calls {@link LocalOnlyHotspotReservation#close()}. 3265 */ onStopped()3266 public void onStopped() {}; 3267 3268 /** 3269 * LocalOnlyHotspot failed to start. 3270 * <p> 3271 * Applications can attempt to call 3272 * {@link WifiManager#startLocalOnlyHotspot(LocalOnlyHotspotCallback, Handler)} again at 3273 * a later time. 3274 * <p> 3275 * @param reason The reason for failure could be one of: {@link 3276 * #ERROR_TETHERING_DISALLOWED}, {@link #ERROR_INCOMPATIBLE_MODE}, 3277 * {@link #ERROR_NO_CHANNEL}, or {@link #ERROR_GENERIC}. 3278 */ onFailed(int reason)3279 public void onFailed(int reason) { }; 3280 } 3281 3282 /** 3283 * Callback proxy for LocalOnlyHotspotCallback objects. 3284 */ 3285 private static class LocalOnlyHotspotCallbackProxy { 3286 private final Handler mHandler; 3287 private final WeakReference<WifiManager> mWifiManager; 3288 private final Looper mLooper; 3289 private final Messenger mMessenger; 3290 3291 /** 3292 * Constructs a {@link LocalOnlyHotspotCallback} using the specified looper. All callbacks 3293 * will be delivered on the thread of the specified looper. 3294 * 3295 * @param manager WifiManager 3296 * @param looper Looper for delivering callbacks 3297 * @param callback LocalOnlyHotspotCallback to notify the calling application. 3298 */ LocalOnlyHotspotCallbackProxy(WifiManager manager, Looper looper, final LocalOnlyHotspotCallback callback)3299 LocalOnlyHotspotCallbackProxy(WifiManager manager, Looper looper, 3300 final LocalOnlyHotspotCallback callback) { 3301 mWifiManager = new WeakReference<>(manager); 3302 mLooper = looper; 3303 3304 mHandler = new Handler(looper) { 3305 @Override 3306 public void handleMessage(Message msg) { 3307 Log.d(TAG, "LocalOnlyHotspotCallbackProxy: handle message what: " 3308 + msg.what + " msg: " + msg); 3309 3310 WifiManager manager = mWifiManager.get(); 3311 if (manager == null) { 3312 Log.w(TAG, "LocalOnlyHotspotCallbackProxy: handle message post GC"); 3313 return; 3314 } 3315 3316 switch (msg.what) { 3317 case HOTSPOT_STARTED: 3318 WifiConfiguration config = (WifiConfiguration) msg.obj; 3319 if (config == null) { 3320 Log.e(TAG, "LocalOnlyHotspotCallbackProxy: config cannot be null."); 3321 callback.onFailed(LocalOnlyHotspotCallback.ERROR_GENERIC); 3322 return; 3323 } 3324 callback.onStarted(manager.new LocalOnlyHotspotReservation(config)); 3325 break; 3326 case HOTSPOT_STOPPED: 3327 Log.w(TAG, "LocalOnlyHotspotCallbackProxy: hotspot stopped"); 3328 callback.onStopped(); 3329 break; 3330 case HOTSPOT_FAILED: 3331 int reasonCode = msg.arg1; 3332 Log.w(TAG, "LocalOnlyHotspotCallbackProxy: failed to start. reason: " 3333 + reasonCode); 3334 callback.onFailed(reasonCode); 3335 Log.w(TAG, "done with the callback..."); 3336 break; 3337 default: 3338 Log.e(TAG, "LocalOnlyHotspotCallbackProxy unhandled message. type: " 3339 + msg.what); 3340 } 3341 } 3342 }; 3343 mMessenger = new Messenger(mHandler); 3344 } 3345 getMessenger()3346 public Messenger getMessenger() { 3347 return mMessenger; 3348 } 3349 3350 /** 3351 * Helper method allowing the the incoming application call to move the onFailed callback 3352 * over to the desired callback thread. 3353 * 3354 * @param reason int representing the error type 3355 */ notifyFailed(int reason)3356 public void notifyFailed(int reason) throws RemoteException { 3357 Message msg = Message.obtain(); 3358 msg.what = HOTSPOT_FAILED; 3359 msg.arg1 = reason; 3360 mMessenger.send(msg); 3361 } 3362 } 3363 3364 /** 3365 * LocalOnlyHotspotSubscription that is an AutoCloseable object for tracking applications 3366 * watching for LocalOnlyHotspot changes. 3367 * 3368 * @hide 3369 */ 3370 public class LocalOnlyHotspotSubscription implements AutoCloseable { 3371 private final CloseGuard mCloseGuard = CloseGuard.get(); 3372 3373 /** @hide */ 3374 @VisibleForTesting LocalOnlyHotspotSubscription()3375 public LocalOnlyHotspotSubscription() { 3376 mCloseGuard.open("close"); 3377 } 3378 3379 @Override close()3380 public void close() { 3381 try { 3382 unregisterLocalOnlyHotspotObserver(); 3383 mCloseGuard.close(); 3384 } catch (Exception e) { 3385 Log.e(TAG, "Failed to unregister LocalOnlyHotspotObserver."); 3386 } 3387 } 3388 3389 @Override finalize()3390 protected void finalize() throws Throwable { 3391 try { 3392 if (mCloseGuard != null) { 3393 mCloseGuard.warnIfOpen(); 3394 } 3395 close(); 3396 } finally { 3397 super.finalize(); 3398 } 3399 } 3400 } 3401 3402 /** 3403 * Class to notify calling applications that watch for changes in LocalOnlyHotspot of updates. 3404 * 3405 * @hide 3406 */ 3407 public static class LocalOnlyHotspotObserver { 3408 /** 3409 * Confirm registration for LocalOnlyHotspotChanges by returning a 3410 * LocalOnlyHotspotSubscription. 3411 */ onRegistered(LocalOnlyHotspotSubscription subscription)3412 public void onRegistered(LocalOnlyHotspotSubscription subscription) {}; 3413 3414 /** 3415 * LocalOnlyHotspot started with the supplied config. 3416 */ onStarted(WifiConfiguration config)3417 public void onStarted(WifiConfiguration config) {}; 3418 3419 /** 3420 * LocalOnlyHotspot stopped. 3421 */ onStopped()3422 public void onStopped() {}; 3423 } 3424 3425 /** 3426 * Callback proxy for LocalOnlyHotspotObserver objects. 3427 */ 3428 private static class LocalOnlyHotspotObserverProxy { 3429 private final Handler mHandler; 3430 private final WeakReference<WifiManager> mWifiManager; 3431 private final Looper mLooper; 3432 private final Messenger mMessenger; 3433 3434 /** 3435 * Constructs a {@link LocalOnlyHotspotObserverProxy} using the specified looper. 3436 * All callbacks will be delivered on the thread of the specified looper. 3437 * 3438 * @param manager WifiManager 3439 * @param looper Looper for delivering callbacks 3440 * @param observer LocalOnlyHotspotObserver to notify the calling application. 3441 */ LocalOnlyHotspotObserverProxy(WifiManager manager, Looper looper, final LocalOnlyHotspotObserver observer)3442 LocalOnlyHotspotObserverProxy(WifiManager manager, Looper looper, 3443 final LocalOnlyHotspotObserver observer) { 3444 mWifiManager = new WeakReference<>(manager); 3445 mLooper = looper; 3446 3447 mHandler = new Handler(looper) { 3448 @Override 3449 public void handleMessage(Message msg) { 3450 Log.d(TAG, "LocalOnlyHotspotObserverProxy: handle message what: " 3451 + msg.what + " msg: " + msg); 3452 3453 WifiManager manager = mWifiManager.get(); 3454 if (manager == null) { 3455 Log.w(TAG, "LocalOnlyHotspotObserverProxy: handle message post GC"); 3456 return; 3457 } 3458 3459 switch (msg.what) { 3460 case HOTSPOT_OBSERVER_REGISTERED: 3461 observer.onRegistered(manager.new LocalOnlyHotspotSubscription()); 3462 break; 3463 case HOTSPOT_STARTED: 3464 WifiConfiguration config = (WifiConfiguration) msg.obj; 3465 if (config == null) { 3466 Log.e(TAG, "LocalOnlyHotspotObserverProxy: config cannot be null."); 3467 return; 3468 } 3469 observer.onStarted(config); 3470 break; 3471 case HOTSPOT_STOPPED: 3472 observer.onStopped(); 3473 break; 3474 default: 3475 Log.e(TAG, "LocalOnlyHotspotObserverProxy unhandled message. type: " 3476 + msg.what); 3477 } 3478 } 3479 }; 3480 mMessenger = new Messenger(mHandler); 3481 } 3482 getMessenger()3483 public Messenger getMessenger() { 3484 return mMessenger; 3485 } 3486 registered()3487 public void registered() throws RemoteException { 3488 Message msg = Message.obtain(); 3489 msg.what = HOTSPOT_OBSERVER_REGISTERED; 3490 mMessenger.send(msg); 3491 } 3492 } 3493 3494 // Ensure that multiple ServiceHandler threads do not interleave message dispatch. 3495 private static final Object sServiceHandlerDispatchLock = new Object(); 3496 3497 private class ServiceHandler extends Handler { ServiceHandler(Looper looper)3498 ServiceHandler(Looper looper) { 3499 super(looper); 3500 } 3501 3502 @Override handleMessage(Message message)3503 public void handleMessage(Message message) { 3504 synchronized (sServiceHandlerDispatchLock) { 3505 dispatchMessageToListeners(message); 3506 } 3507 } 3508 dispatchMessageToListeners(Message message)3509 private void dispatchMessageToListeners(Message message) { 3510 Object listener = removeListener(message.arg2); 3511 switch (message.what) { 3512 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: 3513 if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 3514 mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); 3515 } else { 3516 Log.e(TAG, "Failed to set up channel connection"); 3517 // This will cause all further async API calls on the WifiManager 3518 // to fail and throw an exception 3519 mAsyncChannel = null; 3520 } 3521 mConnected.countDown(); 3522 break; 3523 case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED: 3524 // Ignore 3525 break; 3526 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: 3527 Log.e(TAG, "Channel connection lost"); 3528 // This will cause all further async API calls on the WifiManager 3529 // to fail and throw an exception 3530 mAsyncChannel = null; 3531 getLooper().quit(); 3532 break; 3533 /* ActionListeners grouped together */ 3534 case WifiManager.CONNECT_NETWORK_FAILED: 3535 case WifiManager.FORGET_NETWORK_FAILED: 3536 case WifiManager.SAVE_NETWORK_FAILED: 3537 case WifiManager.DISABLE_NETWORK_FAILED: 3538 if (listener != null) { 3539 ((ActionListener) listener).onFailure(message.arg1); 3540 } 3541 break; 3542 /* ActionListeners grouped together */ 3543 case WifiManager.CONNECT_NETWORK_SUCCEEDED: 3544 case WifiManager.FORGET_NETWORK_SUCCEEDED: 3545 case WifiManager.SAVE_NETWORK_SUCCEEDED: 3546 case WifiManager.DISABLE_NETWORK_SUCCEEDED: 3547 if (listener != null) { 3548 ((ActionListener) listener).onSuccess(); 3549 } 3550 break; 3551 case WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED: 3552 if (listener != null) { 3553 RssiPacketCountInfo info = (RssiPacketCountInfo) message.obj; 3554 if (info != null) 3555 ((TxPacketCountListener) listener).onSuccess(info.txgood + info.txbad); 3556 else 3557 ((TxPacketCountListener) listener).onFailure(ERROR); 3558 } 3559 break; 3560 case WifiManager.RSSI_PKTCNT_FETCH_FAILED: 3561 if (listener != null) { 3562 ((TxPacketCountListener) listener).onFailure(message.arg1); 3563 } 3564 break; 3565 default: 3566 //ignore 3567 break; 3568 } 3569 } 3570 } 3571 putListener(Object listener)3572 private int putListener(Object listener) { 3573 if (listener == null) return INVALID_KEY; 3574 int key; 3575 synchronized (mListenerMapLock) { 3576 do { 3577 key = mListenerKey++; 3578 } while (key == INVALID_KEY); 3579 mListenerMap.put(key, listener); 3580 } 3581 return key; 3582 } 3583 removeListener(int key)3584 private Object removeListener(int key) { 3585 if (key == INVALID_KEY) return null; 3586 synchronized (mListenerMapLock) { 3587 Object listener = mListenerMap.get(key); 3588 mListenerMap.remove(key); 3589 return listener; 3590 } 3591 } 3592 getChannel()3593 private synchronized AsyncChannel getChannel() { 3594 if (mAsyncChannel == null) { 3595 Messenger messenger = getWifiServiceMessenger(); 3596 if (messenger == null) { 3597 throw new IllegalStateException( 3598 "getWifiServiceMessenger() returned null! This is invalid."); 3599 } 3600 3601 mAsyncChannel = new AsyncChannel(); 3602 mConnected = new CountDownLatch(1); 3603 3604 Handler handler = new ServiceHandler(mLooper); 3605 mAsyncChannel.connect(mContext, handler, messenger); 3606 try { 3607 mConnected.await(); 3608 } catch (InterruptedException e) { 3609 Log.e(TAG, "interrupted wait at init"); 3610 } 3611 } 3612 return mAsyncChannel; 3613 } 3614 3615 /** 3616 * Connect to a network with the given configuration. The network also 3617 * gets added to the list of configured networks for the foreground user. 3618 * 3619 * For a new network, this function is used instead of a 3620 * sequence of addNetwork(), enableNetwork(), and reconnect() 3621 * 3622 * @param config the set of variables that describe the configuration, 3623 * contained in a {@link WifiConfiguration} object. 3624 * @param listener for callbacks on success or failure. Can be null. 3625 * @throws IllegalStateException if the WifiManager instance needs to be 3626 * initialized again 3627 * 3628 * @hide 3629 */ 3630 @SystemApi 3631 @RequiresPermission(anyOf = { 3632 android.Manifest.permission.NETWORK_SETTINGS, 3633 android.Manifest.permission.NETWORK_SETUP_WIZARD, 3634 android.Manifest.permission.NETWORK_STACK 3635 }) connect(@onNull WifiConfiguration config, @Nullable ActionListener listener)3636 public void connect(@NonNull WifiConfiguration config, @Nullable ActionListener listener) { 3637 if (config == null) throw new IllegalArgumentException("config cannot be null"); 3638 // Use INVALID_NETWORK_ID for arg1 when passing a config object 3639 // arg1 is used to pass network id when the network already exists 3640 getChannel().sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID, 3641 putListener(listener), config); 3642 } 3643 3644 /** 3645 * Connect to a network with the given networkId. 3646 * 3647 * This function is used instead of a enableNetwork() and reconnect() 3648 * 3649 * @param networkId the ID of the network as returned by {@link #addNetwork} or {@link 3650 * getConfiguredNetworks}. 3651 * @param listener for callbacks on success or failure. Can be null. 3652 * @throws IllegalStateException if the WifiManager instance needs to be 3653 * initialized again 3654 * @hide 3655 */ 3656 @SystemApi 3657 @RequiresPermission(anyOf = { 3658 android.Manifest.permission.NETWORK_SETTINGS, 3659 android.Manifest.permission.NETWORK_SETUP_WIZARD, 3660 android.Manifest.permission.NETWORK_STACK 3661 }) connect(int networkId, @Nullable ActionListener listener)3662 public void connect(int networkId, @Nullable ActionListener listener) { 3663 if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative"); 3664 getChannel().sendMessage(CONNECT_NETWORK, networkId, putListener(listener)); 3665 } 3666 3667 /** 3668 * Save the given network to the list of configured networks for the 3669 * foreground user. If the network already exists, the configuration 3670 * is updated. Any new network is enabled by default. 3671 * 3672 * For a new network, this function is used instead of a 3673 * sequence of addNetwork() and enableNetwork(). 3674 * 3675 * For an existing network, it accomplishes the task of updateNetwork() 3676 * 3677 * This API will cause reconnect if the crecdentials of the current active 3678 * connection has been changed. 3679 * 3680 * @param config the set of variables that describe the configuration, 3681 * contained in a {@link WifiConfiguration} object. 3682 * @param listener for callbacks on success or failure. Can be null. 3683 * @throws IllegalStateException if the WifiManager instance needs to be 3684 * initialized again 3685 * @hide 3686 */ 3687 @SystemApi 3688 @RequiresPermission(anyOf = { 3689 android.Manifest.permission.NETWORK_SETTINGS, 3690 android.Manifest.permission.NETWORK_SETUP_WIZARD, 3691 android.Manifest.permission.NETWORK_STACK 3692 }) save(@onNull WifiConfiguration config, @Nullable ActionListener listener)3693 public void save(@NonNull WifiConfiguration config, @Nullable ActionListener listener) { 3694 if (config == null) throw new IllegalArgumentException("config cannot be null"); 3695 getChannel().sendMessage(SAVE_NETWORK, 0, putListener(listener), config); 3696 } 3697 3698 /** 3699 * Delete the network from the list of configured networks for the 3700 * foreground user. 3701 * 3702 * This function is used instead of a sequence of removeNetwork() 3703 * 3704 * @param config the set of variables that describe the configuration, 3705 * contained in a {@link WifiConfiguration} object. 3706 * @param listener for callbacks on success or failure. Can be null. 3707 * @throws IllegalStateException if the WifiManager instance needs to be 3708 * initialized again 3709 * @hide 3710 */ 3711 @SystemApi 3712 @RequiresPermission(anyOf = { 3713 android.Manifest.permission.NETWORK_SETTINGS, 3714 android.Manifest.permission.NETWORK_SETUP_WIZARD, 3715 android.Manifest.permission.NETWORK_STACK 3716 }) forget(int netId, @Nullable ActionListener listener)3717 public void forget(int netId, @Nullable ActionListener listener) { 3718 if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative"); 3719 getChannel().sendMessage(FORGET_NETWORK, netId, putListener(listener)); 3720 } 3721 3722 /** 3723 * Disable network 3724 * 3725 * @param netId is the network Id 3726 * @param listener for callbacks on success or failure. Can be null. 3727 * @throws IllegalStateException if the WifiManager instance needs to be 3728 * initialized again 3729 * @hide 3730 */ 3731 @SystemApi 3732 @RequiresPermission(anyOf = { 3733 android.Manifest.permission.NETWORK_SETTINGS, 3734 android.Manifest.permission.NETWORK_SETUP_WIZARD, 3735 android.Manifest.permission.NETWORK_STACK 3736 }) disable(int netId, @Nullable ActionListener listener)3737 public void disable(int netId, @Nullable ActionListener listener) { 3738 if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative"); 3739 getChannel().sendMessage(DISABLE_NETWORK, netId, putListener(listener)); 3740 } 3741 3742 /** 3743 * Disable ephemeral Network 3744 * 3745 * @param SSID, in the format of WifiConfiguration's SSID. 3746 * @hide 3747 */ 3748 @RequiresPermission(anyOf = { 3749 android.Manifest.permission.NETWORK_SETTINGS, 3750 android.Manifest.permission.NETWORK_STACK 3751 }) disableEphemeralNetwork(String SSID)3752 public void disableEphemeralNetwork(String SSID) { 3753 if (SSID == null) throw new IllegalArgumentException("SSID cannot be null"); 3754 try { 3755 mService.disableEphemeralNetwork(SSID, mContext.getOpPackageName()); 3756 } catch (RemoteException e) { 3757 throw e.rethrowFromSystemServer(); 3758 } 3759 } 3760 3761 /** 3762 * WPS suport has been deprecated from Client mode and this method will immediately trigger 3763 * {@link WpsCallback#onFailed(int)} with a generic error. 3764 * 3765 * @param config WPS configuration (does not support {@link WpsInfo#LABEL}) 3766 * @param listener for callbacks on success or failure. Can be null. 3767 * @throws IllegalStateException if the WifiManager instance needs to be initialized again 3768 * @deprecated This API is deprecated 3769 */ startWps(WpsInfo config, WpsCallback listener)3770 public void startWps(WpsInfo config, WpsCallback listener) { 3771 if (listener != null ) { 3772 listener.onFailed(ERROR); 3773 } 3774 } 3775 3776 /** 3777 * WPS support has been deprecated from Client mode and this method will immediately trigger 3778 * {@link WpsCallback#onFailed(int)} with a generic error. 3779 * 3780 * @param listener for callbacks on success or failure. Can be null. 3781 * @throws IllegalStateException if the WifiManager instance needs to be initialized again 3782 * @deprecated This API is deprecated 3783 */ cancelWps(WpsCallback listener)3784 public void cancelWps(WpsCallback listener) { 3785 if (listener != null) { 3786 listener.onFailed(ERROR); 3787 } 3788 } 3789 3790 /** 3791 * Get a reference to WifiService handler. This is used by a client to establish 3792 * an AsyncChannel communication with WifiService 3793 * 3794 * @return Messenger pointing to the WifiService handler 3795 */ 3796 @UnsupportedAppUsage getWifiServiceMessenger()3797 private Messenger getWifiServiceMessenger() { 3798 try { 3799 return mService.getWifiServiceMessenger(mContext.getOpPackageName()); 3800 } catch (RemoteException e) { 3801 throw e.rethrowFromSystemServer(); 3802 } 3803 } 3804 3805 3806 /** 3807 * Allows an application to keep the Wi-Fi radio awake. 3808 * Normally the Wi-Fi radio may turn off when the user has not used the device in a while. 3809 * Acquiring a WifiLock will keep the radio on until the lock is released. Multiple 3810 * applications may hold WifiLocks, and the radio will only be allowed to turn off when no 3811 * WifiLocks are held in any application. 3812 * <p> 3813 * Before using a WifiLock, consider carefully if your application requires Wi-Fi access, or 3814 * could function over a mobile network, if available. A program that needs to download large 3815 * files should hold a WifiLock to ensure that the download will complete, but a program whose 3816 * network usage is occasional or low-bandwidth should not hold a WifiLock to avoid adversely 3817 * affecting battery life. 3818 * <p> 3819 * Note that WifiLocks cannot override the user-level "Wi-Fi Enabled" setting, nor Airplane 3820 * Mode. They simply keep the radio from turning off when Wi-Fi is already on but the device 3821 * is idle. 3822 * <p> 3823 * Any application using a WifiLock must request the {@code android.permission.WAKE_LOCK} 3824 * permission in an {@code <uses-permission>} element of the application's manifest. 3825 */ 3826 public class WifiLock { 3827 private String mTag; 3828 private final IBinder mBinder; 3829 private int mRefCount; 3830 int mLockType; 3831 private boolean mRefCounted; 3832 private boolean mHeld; 3833 private WorkSource mWorkSource; 3834 WifiLock(int lockType, String tag)3835 private WifiLock(int lockType, String tag) { 3836 mTag = tag; 3837 mLockType = lockType; 3838 mBinder = new Binder(); 3839 mRefCount = 0; 3840 mRefCounted = true; 3841 mHeld = false; 3842 } 3843 3844 /** 3845 * Locks the Wi-Fi radio on until {@link #release} is called. 3846 * 3847 * If this WifiLock is reference-counted, each call to {@code acquire} will increment the 3848 * reference count, and the radio will remain locked as long as the reference count is 3849 * above zero. 3850 * 3851 * If this WifiLock is not reference-counted, the first call to {@code acquire} will lock 3852 * the radio, but subsequent calls will be ignored. Only one call to {@link #release} 3853 * will be required, regardless of the number of times that {@code acquire} is called. 3854 */ acquire()3855 public void acquire() { 3856 synchronized (mBinder) { 3857 if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) { 3858 try { 3859 mService.acquireWifiLock(mBinder, mLockType, mTag, mWorkSource); 3860 synchronized (WifiManager.this) { 3861 if (mActiveLockCount >= MAX_ACTIVE_LOCKS) { 3862 mService.releaseWifiLock(mBinder); 3863 throw new UnsupportedOperationException( 3864 "Exceeded maximum number of wifi locks"); 3865 } 3866 mActiveLockCount++; 3867 } 3868 } catch (RemoteException e) { 3869 throw e.rethrowFromSystemServer(); 3870 } 3871 mHeld = true; 3872 } 3873 } 3874 } 3875 3876 /** 3877 * Unlocks the Wi-Fi radio, allowing it to turn off when the device is idle. 3878 * 3879 * If this WifiLock is reference-counted, each call to {@code release} will decrement the 3880 * reference count, and the radio will be unlocked only when the reference count reaches 3881 * zero. If the reference count goes below zero (that is, if {@code release} is called 3882 * a greater number of times than {@link #acquire}), an exception is thrown. 3883 * 3884 * If this WifiLock is not reference-counted, the first call to {@code release} (after 3885 * the radio was locked using {@link #acquire}) will unlock the radio, and subsequent 3886 * calls will be ignored. 3887 */ release()3888 public void release() { 3889 synchronized (mBinder) { 3890 if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { 3891 try { 3892 mService.releaseWifiLock(mBinder); 3893 synchronized (WifiManager.this) { 3894 mActiveLockCount--; 3895 } 3896 } catch (RemoteException e) { 3897 throw e.rethrowFromSystemServer(); 3898 } 3899 mHeld = false; 3900 } 3901 if (mRefCount < 0) { 3902 throw new RuntimeException("WifiLock under-locked " + mTag); 3903 } 3904 } 3905 } 3906 3907 /** 3908 * Controls whether this is a reference-counted or non-reference-counted WifiLock. 3909 * 3910 * Reference-counted WifiLocks keep track of the number of calls to {@link #acquire} and 3911 * {@link #release}, and only allow the radio to sleep when every call to {@link #acquire} 3912 * has been balanced with a call to {@link #release}. Non-reference-counted WifiLocks 3913 * lock the radio whenever {@link #acquire} is called and it is unlocked, and unlock the 3914 * radio whenever {@link #release} is called and it is locked. 3915 * 3916 * @param refCounted true if this WifiLock should keep a reference count 3917 */ setReferenceCounted(boolean refCounted)3918 public void setReferenceCounted(boolean refCounted) { 3919 mRefCounted = refCounted; 3920 } 3921 3922 /** 3923 * Checks whether this WifiLock is currently held. 3924 * 3925 * @return true if this WifiLock is held, false otherwise 3926 */ isHeld()3927 public boolean isHeld() { 3928 synchronized (mBinder) { 3929 return mHeld; 3930 } 3931 } 3932 setWorkSource(WorkSource ws)3933 public void setWorkSource(WorkSource ws) { 3934 synchronized (mBinder) { 3935 if (ws != null && ws.isEmpty()) { 3936 ws = null; 3937 } 3938 boolean changed = true; 3939 if (ws == null) { 3940 mWorkSource = null; 3941 } else { 3942 ws.clearNames(); 3943 if (mWorkSource == null) { 3944 changed = mWorkSource != null; 3945 mWorkSource = new WorkSource(ws); 3946 } else { 3947 changed = !mWorkSource.equals(ws); 3948 if (changed) { 3949 mWorkSource.set(ws); 3950 } 3951 } 3952 } 3953 if (changed && mHeld) { 3954 try { 3955 mService.updateWifiLockWorkSource(mBinder, mWorkSource); 3956 } catch (RemoteException e) { 3957 throw e.rethrowFromSystemServer(); 3958 } 3959 } 3960 } 3961 } 3962 toString()3963 public String toString() { 3964 String s1, s2, s3; 3965 synchronized (mBinder) { 3966 s1 = Integer.toHexString(System.identityHashCode(this)); 3967 s2 = mHeld ? "held; " : ""; 3968 if (mRefCounted) { 3969 s3 = "refcounted: refcount = " + mRefCount; 3970 } else { 3971 s3 = "not refcounted"; 3972 } 3973 return "WifiLock{ " + s1 + "; " + s2 + s3 + " }"; 3974 } 3975 } 3976 3977 @Override finalize()3978 protected void finalize() throws Throwable { 3979 super.finalize(); 3980 synchronized (mBinder) { 3981 if (mHeld) { 3982 try { 3983 mService.releaseWifiLock(mBinder); 3984 synchronized (WifiManager.this) { 3985 mActiveLockCount--; 3986 } 3987 } catch (RemoteException e) { 3988 throw e.rethrowFromSystemServer(); 3989 } 3990 } 3991 } 3992 } 3993 } 3994 3995 /** 3996 * Creates a new WifiLock. 3997 * 3998 * @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL_HIGH_PERF} 3999 * and {@link #WIFI_MODE_FULL_LOW_LATENCY} for descriptions of the types of Wi-Fi locks. 4000 * @param tag a tag for the WifiLock to identify it in debugging messages. This string is 4001 * never shown to the user under normal conditions, but should be descriptive 4002 * enough to identify your application and the specific WifiLock within it, if it 4003 * holds multiple WifiLocks. 4004 * 4005 * @return a new, unacquired WifiLock with the given tag. 4006 * 4007 * @see WifiLock 4008 */ createWifiLock(int lockType, String tag)4009 public WifiLock createWifiLock(int lockType, String tag) { 4010 return new WifiLock(lockType, tag); 4011 } 4012 4013 /** 4014 * Creates a new WifiLock. 4015 * 4016 * @param tag a tag for the WifiLock to identify it in debugging messages. This string is 4017 * never shown to the user under normal conditions, but should be descriptive 4018 * enough to identify your application and the specific WifiLock within it, if it 4019 * holds multiple WifiLocks. 4020 * 4021 * @return a new, unacquired WifiLock with the given tag. 4022 * 4023 * @see WifiLock 4024 * 4025 * @deprecated This API is non-functional. 4026 */ 4027 @Deprecated createWifiLock(String tag)4028 public WifiLock createWifiLock(String tag) { 4029 return new WifiLock(WIFI_MODE_FULL, tag); 4030 } 4031 4032 /** 4033 * Create a new MulticastLock 4034 * 4035 * @param tag a tag for the MulticastLock to identify it in debugging 4036 * messages. This string is never shown to the user under 4037 * normal conditions, but should be descriptive enough to 4038 * identify your application and the specific MulticastLock 4039 * within it, if it holds multiple MulticastLocks. 4040 * 4041 * @return a new, unacquired MulticastLock with the given tag. 4042 * 4043 * @see MulticastLock 4044 */ createMulticastLock(String tag)4045 public MulticastLock createMulticastLock(String tag) { 4046 return new MulticastLock(tag); 4047 } 4048 4049 /** 4050 * Allows an application to receive Wifi Multicast packets. 4051 * Normally the Wifi stack filters out packets not explicitly 4052 * addressed to this device. Acquring a MulticastLock will 4053 * cause the stack to receive packets addressed to multicast 4054 * addresses. Processing these extra packets can cause a noticeable 4055 * battery drain and should be disabled when not needed. 4056 */ 4057 public class MulticastLock { 4058 private String mTag; 4059 private final IBinder mBinder; 4060 private int mRefCount; 4061 private boolean mRefCounted; 4062 private boolean mHeld; 4063 MulticastLock(String tag)4064 private MulticastLock(String tag) { 4065 mTag = tag; 4066 mBinder = new Binder(); 4067 mRefCount = 0; 4068 mRefCounted = true; 4069 mHeld = false; 4070 } 4071 4072 /** 4073 * Locks Wifi Multicast on until {@link #release} is called. 4074 * 4075 * If this MulticastLock is reference-counted each call to 4076 * {@code acquire} will increment the reference count, and the 4077 * wifi interface will receive multicast packets as long as the 4078 * reference count is above zero. 4079 * 4080 * If this MulticastLock is not reference-counted, the first call to 4081 * {@code acquire} will turn on the multicast packets, but subsequent 4082 * calls will be ignored. Only one call to {@link #release} will 4083 * be required, regardless of the number of times that {@code acquire} 4084 * is called. 4085 * 4086 * Note that other applications may also lock Wifi Multicast on. 4087 * Only they can relinquish their lock. 4088 * 4089 * Also note that applications cannot leave Multicast locked on. 4090 * When an app exits or crashes, any Multicast locks will be released. 4091 */ acquire()4092 public void acquire() { 4093 synchronized (mBinder) { 4094 if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) { 4095 try { 4096 mService.acquireMulticastLock(mBinder, mTag); 4097 synchronized (WifiManager.this) { 4098 if (mActiveLockCount >= MAX_ACTIVE_LOCKS) { 4099 mService.releaseMulticastLock(mTag); 4100 throw new UnsupportedOperationException( 4101 "Exceeded maximum number of wifi locks"); 4102 } 4103 mActiveLockCount++; 4104 } 4105 } catch (RemoteException e) { 4106 throw e.rethrowFromSystemServer(); 4107 } 4108 mHeld = true; 4109 } 4110 } 4111 } 4112 4113 /** 4114 * Unlocks Wifi Multicast, restoring the filter of packets 4115 * not addressed specifically to this device and saving power. 4116 * 4117 * If this MulticastLock is reference-counted, each call to 4118 * {@code release} will decrement the reference count, and the 4119 * multicast packets will only stop being received when the reference 4120 * count reaches zero. If the reference count goes below zero (that 4121 * is, if {@code release} is called a greater number of times than 4122 * {@link #acquire}), an exception is thrown. 4123 * 4124 * If this MulticastLock is not reference-counted, the first call to 4125 * {@code release} (after the radio was multicast locked using 4126 * {@link #acquire}) will unlock the multicast, and subsequent calls 4127 * will be ignored. 4128 * 4129 * Note that if any other Wifi Multicast Locks are still outstanding 4130 * this {@code release} call will not have an immediate effect. Only 4131 * when all applications have released all their Multicast Locks will 4132 * the Multicast filter be turned back on. 4133 * 4134 * Also note that when an app exits or crashes all of its Multicast 4135 * Locks will be automatically released. 4136 */ release()4137 public void release() { 4138 synchronized (mBinder) { 4139 if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { 4140 try { 4141 mService.releaseMulticastLock(mTag); 4142 synchronized (WifiManager.this) { 4143 mActiveLockCount--; 4144 } 4145 } catch (RemoteException e) { 4146 throw e.rethrowFromSystemServer(); 4147 } 4148 mHeld = false; 4149 } 4150 if (mRefCount < 0) { 4151 throw new RuntimeException("MulticastLock under-locked " 4152 + mTag); 4153 } 4154 } 4155 } 4156 4157 /** 4158 * Controls whether this is a reference-counted or non-reference- 4159 * counted MulticastLock. 4160 * 4161 * Reference-counted MulticastLocks keep track of the number of calls 4162 * to {@link #acquire} and {@link #release}, and only stop the 4163 * reception of multicast packets when every call to {@link #acquire} 4164 * has been balanced with a call to {@link #release}. Non-reference- 4165 * counted MulticastLocks allow the reception of multicast packets 4166 * whenever {@link #acquire} is called and stop accepting multicast 4167 * packets whenever {@link #release} is called. 4168 * 4169 * @param refCounted true if this MulticastLock should keep a reference 4170 * count 4171 */ setReferenceCounted(boolean refCounted)4172 public void setReferenceCounted(boolean refCounted) { 4173 mRefCounted = refCounted; 4174 } 4175 4176 /** 4177 * Checks whether this MulticastLock is currently held. 4178 * 4179 * @return true if this MulticastLock is held, false otherwise 4180 */ isHeld()4181 public boolean isHeld() { 4182 synchronized (mBinder) { 4183 return mHeld; 4184 } 4185 } 4186 toString()4187 public String toString() { 4188 String s1, s2, s3; 4189 synchronized (mBinder) { 4190 s1 = Integer.toHexString(System.identityHashCode(this)); 4191 s2 = mHeld ? "held; " : ""; 4192 if (mRefCounted) { 4193 s3 = "refcounted: refcount = " + mRefCount; 4194 } else { 4195 s3 = "not refcounted"; 4196 } 4197 return "MulticastLock{ " + s1 + "; " + s2 + s3 + " }"; 4198 } 4199 } 4200 4201 @Override finalize()4202 protected void finalize() throws Throwable { 4203 super.finalize(); 4204 setReferenceCounted(false); 4205 release(); 4206 } 4207 } 4208 4209 /** 4210 * Check multicast filter status. 4211 * 4212 * @return true if multicast packets are allowed. 4213 * 4214 * @hide pending API council approval 4215 */ isMulticastEnabled()4216 public boolean isMulticastEnabled() { 4217 try { 4218 return mService.isMulticastEnabled(); 4219 } catch (RemoteException e) { 4220 throw e.rethrowFromSystemServer(); 4221 } 4222 } 4223 4224 /** 4225 * Initialize the multicast filtering to 'on' 4226 * @hide no intent to publish 4227 */ 4228 @UnsupportedAppUsage initializeMulticastFiltering()4229 public boolean initializeMulticastFiltering() { 4230 try { 4231 mService.initializeMulticastFiltering(); 4232 return true; 4233 } catch (RemoteException e) { 4234 throw e.rethrowFromSystemServer(); 4235 } 4236 } 4237 finalize()4238 protected void finalize() throws Throwable { 4239 try { 4240 if (mAsyncChannel != null) { 4241 mAsyncChannel.disconnect(); 4242 } 4243 } finally { 4244 super.finalize(); 4245 } 4246 } 4247 4248 /** 4249 * Set wifi verbose log. Called from developer settings. 4250 * @hide 4251 */ 4252 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) 4253 @UnsupportedAppUsage enableVerboseLogging(int verbose)4254 public void enableVerboseLogging (int verbose) { 4255 try { 4256 mService.enableVerboseLogging(verbose); 4257 } catch (Exception e) { 4258 //ignore any failure here 4259 Log.e(TAG, "enableVerboseLogging " + e.toString()); 4260 } 4261 } 4262 4263 /** 4264 * Get the WiFi verbose logging level.This is used by settings 4265 * to decide what to show within the picker. 4266 * @hide 4267 */ 4268 @UnsupportedAppUsage getVerboseLoggingLevel()4269 public int getVerboseLoggingLevel() { 4270 try { 4271 return mService.getVerboseLoggingLevel(); 4272 } catch (RemoteException e) { 4273 throw e.rethrowFromSystemServer(); 4274 } 4275 } 4276 4277 /** 4278 * Removes all saved wifi networks. 4279 * 4280 * @hide 4281 */ factoryReset()4282 public void factoryReset() { 4283 try { 4284 mService.factoryReset(mContext.getOpPackageName()); 4285 } catch (RemoteException e) { 4286 throw e.rethrowFromSystemServer(); 4287 } 4288 } 4289 4290 /** 4291 * Get Network object of current wifi network 4292 * @return Get Network object of current wifi network 4293 * @hide 4294 */ 4295 @UnsupportedAppUsage getCurrentNetwork()4296 public Network getCurrentNetwork() { 4297 try { 4298 return mService.getCurrentNetwork(); 4299 } catch (RemoteException e) { 4300 throw e.rethrowFromSystemServer(); 4301 } 4302 } 4303 4304 /** 4305 * Deprecated 4306 * returns false 4307 * @hide 4308 * @deprecated 4309 */ setEnableAutoJoinWhenAssociated(boolean enabled)4310 public boolean setEnableAutoJoinWhenAssociated(boolean enabled) { 4311 return false; 4312 } 4313 4314 /** 4315 * Deprecated 4316 * returns false 4317 * @hide 4318 * @deprecated 4319 */ getEnableAutoJoinWhenAssociated()4320 public boolean getEnableAutoJoinWhenAssociated() { 4321 return false; 4322 } 4323 4324 /** 4325 * Enable/disable WifiConnectivityManager 4326 * @hide 4327 */ enableWifiConnectivityManager(boolean enabled)4328 public void enableWifiConnectivityManager(boolean enabled) { 4329 try { 4330 mService.enableWifiConnectivityManager(enabled); 4331 } catch (RemoteException e) { 4332 throw e.rethrowFromSystemServer(); 4333 } 4334 } 4335 4336 /** 4337 * Retrieve the data to be backed to save the current state. 4338 * @hide 4339 */ retrieveBackupData()4340 public byte[] retrieveBackupData() { 4341 try { 4342 return mService.retrieveBackupData(); 4343 } catch (RemoteException e) { 4344 throw e.rethrowFromSystemServer(); 4345 } 4346 } 4347 4348 /** 4349 * Restore state from the backed up data. 4350 * @hide 4351 */ restoreBackupData(byte[] data)4352 public void restoreBackupData(byte[] data) { 4353 try { 4354 mService.restoreBackupData(data); 4355 } catch (RemoteException e) { 4356 throw e.rethrowFromSystemServer(); 4357 } 4358 } 4359 4360 /** 4361 * Restore state from the older version of back up data. 4362 * The old backup data was essentially a backup of wpa_supplicant.conf 4363 * and ipconfig.txt file. 4364 * @deprecated this is no longer supported. 4365 * @hide 4366 */ 4367 @Deprecated restoreSupplicantBackupData(byte[] supplicantData, byte[] ipConfigData)4368 public void restoreSupplicantBackupData(byte[] supplicantData, byte[] ipConfigData) { 4369 try { 4370 mService.restoreSupplicantBackupData(supplicantData, ipConfigData); 4371 } catch (RemoteException e) { 4372 throw e.rethrowFromSystemServer(); 4373 } 4374 } 4375 4376 /** 4377 * Start subscription provisioning flow 4378 * 4379 * @param provider {@link OsuProvider} to provision with 4380 * @param executor the Executor on which to run the callback. 4381 * @param callback {@link ProvisioningCallback} for updates regarding provisioning flow 4382 * @hide 4383 */ 4384 @SystemApi 4385 @RequiresPermission(anyOf = { 4386 android.Manifest.permission.NETWORK_SETTINGS, 4387 android.Manifest.permission.NETWORK_SETUP_WIZARD 4388 }) startSubscriptionProvisioning(@onNull OsuProvider provider, @NonNull @CallbackExecutor Executor executor, @NonNull ProvisioningCallback callback)4389 public void startSubscriptionProvisioning(@NonNull OsuProvider provider, 4390 @NonNull @CallbackExecutor Executor executor, @NonNull ProvisioningCallback callback) { 4391 // Verify arguments 4392 if (executor == null) { 4393 throw new IllegalArgumentException("executor must not be null"); 4394 } 4395 if (callback == null) { 4396 throw new IllegalArgumentException("callback must not be null"); 4397 } 4398 try { 4399 mService.startSubscriptionProvisioning(provider, 4400 new ProvisioningCallbackProxy(executor, callback)); 4401 } catch (RemoteException e) { 4402 throw e.rethrowFromSystemServer(); 4403 } 4404 } 4405 4406 /** 4407 * Helper class to support OSU Provisioning callbacks 4408 */ 4409 private static class ProvisioningCallbackProxy extends IProvisioningCallback.Stub { 4410 private final Executor mExecutor; 4411 private final ProvisioningCallback mCallback; 4412 ProvisioningCallbackProxy(Executor executor, ProvisioningCallback callback)4413 ProvisioningCallbackProxy(Executor executor, ProvisioningCallback callback) { 4414 mExecutor = executor; 4415 mCallback = callback; 4416 } 4417 4418 @Override onProvisioningStatus(int status)4419 public void onProvisioningStatus(int status) { 4420 mExecutor.execute(() -> mCallback.onProvisioningStatus(status)); 4421 } 4422 4423 @Override onProvisioningFailure(int status)4424 public void onProvisioningFailure(int status) { 4425 mExecutor.execute(() -> mCallback.onProvisioningFailure(status)); 4426 } 4427 4428 @Override onProvisioningComplete()4429 public void onProvisioningComplete() { 4430 mExecutor.execute(() -> mCallback.onProvisioningComplete()); 4431 } 4432 } 4433 4434 /** 4435 * Base class for Traffic state callback. Should be extended by applications and set when 4436 * calling {@link WifiManager#registerTrafficStateCallback(TrafficStateCallback, Handler)}. 4437 * @hide 4438 */ 4439 public interface TrafficStateCallback { 4440 /** 4441 * Lowest bit indicates data reception and the second lowest 4442 * bit indicates data transmitted 4443 */ 4444 /** @hide */ 4445 int DATA_ACTIVITY_NONE = 0x00; 4446 /** @hide */ 4447 int DATA_ACTIVITY_IN = 0x01; 4448 /** @hide */ 4449 int DATA_ACTIVITY_OUT = 0x02; 4450 /** @hide */ 4451 int DATA_ACTIVITY_INOUT = 0x03; 4452 4453 /** 4454 * Callback invoked to inform clients about the current traffic state. 4455 * 4456 * @param state One of the values: {@link #DATA_ACTIVITY_NONE}, {@link #DATA_ACTIVITY_IN}, 4457 * {@link #DATA_ACTIVITY_OUT} & {@link #DATA_ACTIVITY_INOUT}. 4458 * @hide 4459 */ onStateChanged(int state)4460 void onStateChanged(int state); 4461 } 4462 4463 /** 4464 * Callback proxy for TrafficStateCallback objects. 4465 * 4466 * @hide 4467 */ 4468 private class TrafficStateCallbackProxy extends ITrafficStateCallback.Stub { 4469 private final Handler mHandler; 4470 private final TrafficStateCallback mCallback; 4471 TrafficStateCallbackProxy(Looper looper, TrafficStateCallback callback)4472 TrafficStateCallbackProxy(Looper looper, TrafficStateCallback callback) { 4473 mHandler = new Handler(looper); 4474 mCallback = callback; 4475 } 4476 4477 @Override onStateChanged(int state)4478 public void onStateChanged(int state) { 4479 if (mVerboseLoggingEnabled) { 4480 Log.v(TAG, "TrafficStateCallbackProxy: onStateChanged state=" + state); 4481 } 4482 mHandler.post(() -> { 4483 mCallback.onStateChanged(state); 4484 }); 4485 } 4486 } 4487 4488 /** 4489 * Registers a callback for monitoring traffic state. See {@link TrafficStateCallback}. These 4490 * callbacks will be invoked periodically by platform to inform clients about the current 4491 * traffic state. Caller can unregister a previously registered callback using 4492 * {@link #unregisterTrafficStateCallback(TrafficStateCallback)} 4493 * <p> 4494 * Applications should have the 4495 * {@link android.Manifest.permission#NETWORK_SETTINGS NETWORK_SETTINGS} permission. Callers 4496 * without the permission will trigger a {@link java.lang.SecurityException}. 4497 * <p> 4498 * 4499 * @param callback Callback for traffic state events 4500 * @param handler The Handler on whose thread to execute the callbacks of the {@code callback} 4501 * object. If null, then the application's main thread will be used. 4502 * @hide 4503 */ 4504 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) registerTrafficStateCallback(@onNull TrafficStateCallback callback, @Nullable Handler handler)4505 public void registerTrafficStateCallback(@NonNull TrafficStateCallback callback, 4506 @Nullable Handler handler) { 4507 if (callback == null) throw new IllegalArgumentException("callback cannot be null"); 4508 Log.v(TAG, "registerTrafficStateCallback: callback=" + callback + ", handler=" + handler); 4509 4510 Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); 4511 Binder binder = new Binder(); 4512 try { 4513 mService.registerTrafficStateCallback( 4514 binder, new TrafficStateCallbackProxy(looper, callback), callback.hashCode()); 4515 } catch (RemoteException e) { 4516 throw e.rethrowFromSystemServer(); 4517 } 4518 } 4519 4520 /** 4521 * Allow callers to unregister a previously registered callback. After calling this method, 4522 * applications will no longer receive traffic state notifications. 4523 * 4524 * @param callback Callback to unregister for traffic state events 4525 * @hide 4526 */ 4527 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) unregisterTrafficStateCallback(@onNull TrafficStateCallback callback)4528 public void unregisterTrafficStateCallback(@NonNull TrafficStateCallback callback) { 4529 if (callback == null) throw new IllegalArgumentException("callback cannot be null"); 4530 Log.v(TAG, "unregisterTrafficStateCallback: callback=" + callback); 4531 4532 try { 4533 mService.unregisterTrafficStateCallback(callback.hashCode()); 4534 } catch (RemoteException e) { 4535 throw e.rethrowFromSystemServer(); 4536 } 4537 } 4538 4539 /** 4540 * Helper method to update the local verbose logging flag based on the verbose logging 4541 * level from wifi service. 4542 */ updateVerboseLoggingEnabledFromService()4543 private void updateVerboseLoggingEnabledFromService() { 4544 mVerboseLoggingEnabled = getVerboseLoggingLevel() > 0; 4545 } 4546 4547 /** 4548 * @return true if this device supports WPA3-Personal SAE 4549 */ isWpa3SaeSupported()4550 public boolean isWpa3SaeSupported() { 4551 return isFeatureSupported(WIFI_FEATURE_WPA3_SAE); 4552 } 4553 4554 /** 4555 * @return true if this device supports WPA3-Enterprise Suite-B-192 4556 */ isWpa3SuiteBSupported()4557 public boolean isWpa3SuiteBSupported() { 4558 return isFeatureSupported(WIFI_FEATURE_WPA3_SUITE_B); 4559 } 4560 4561 /** 4562 * @return true if this device supports Wi-Fi Enhanced Open (OWE) 4563 */ isEnhancedOpenSupported()4564 public boolean isEnhancedOpenSupported() { 4565 return isFeatureSupported(WIFI_FEATURE_OWE); 4566 } 4567 4568 /** 4569 * Wi-Fi Easy Connect (DPP) introduces standardized mechanisms to simplify the provisioning and 4570 * configuration of Wi-Fi devices. 4571 * For more details, visit <a href="https://www.wi-fi.org/">https://www.wi-fi.org/</a> and 4572 * search for "Easy Connect" or "Device Provisioning Protocol specification". 4573 * 4574 * @return true if this device supports Wi-Fi Easy-connect (Device Provisioning Protocol) 4575 */ isEasyConnectSupported()4576 public boolean isEasyConnectSupported() { 4577 return isFeatureSupported(WIFI_FEATURE_DPP); 4578 } 4579 4580 /** 4581 * Gets the factory Wi-Fi MAC addresses. 4582 * @return Array of String representing Wi-Fi MAC addresses sorted lexically or an empty Array 4583 * if failed. 4584 * @hide 4585 */ 4586 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) getFactoryMacAddresses()4587 public String[] getFactoryMacAddresses() { 4588 try { 4589 return mService.getFactoryMacAddresses(); 4590 } catch (RemoteException e) { 4591 throw e.rethrowFromSystemServer(); 4592 } 4593 } 4594 4595 /** @hide */ 4596 @Retention(RetentionPolicy.SOURCE) 4597 @IntDef(prefix = {"DEVICE_MOBILITY_STATE_"}, value = { 4598 DEVICE_MOBILITY_STATE_UNKNOWN, 4599 DEVICE_MOBILITY_STATE_HIGH_MVMT, 4600 DEVICE_MOBILITY_STATE_LOW_MVMT, 4601 DEVICE_MOBILITY_STATE_STATIONARY}) 4602 public @interface DeviceMobilityState {} 4603 4604 /** 4605 * Unknown device mobility state 4606 * 4607 * @see #setDeviceMobilityState(int) 4608 * 4609 * @hide 4610 */ 4611 @SystemApi 4612 public static final int DEVICE_MOBILITY_STATE_UNKNOWN = 0; 4613 4614 /** 4615 * High movement device mobility state. 4616 * e.g. on a bike, in a motor vehicle 4617 * 4618 * @see #setDeviceMobilityState(int) 4619 * 4620 * @hide 4621 */ 4622 @SystemApi 4623 public static final int DEVICE_MOBILITY_STATE_HIGH_MVMT = 1; 4624 4625 /** 4626 * Low movement device mobility state. 4627 * e.g. walking, running 4628 * 4629 * @see #setDeviceMobilityState(int) 4630 * 4631 * @hide 4632 */ 4633 @SystemApi 4634 public static final int DEVICE_MOBILITY_STATE_LOW_MVMT = 2; 4635 4636 /** 4637 * Stationary device mobility state 4638 * 4639 * @see #setDeviceMobilityState(int) 4640 * 4641 * @hide 4642 */ 4643 @SystemApi 4644 public static final int DEVICE_MOBILITY_STATE_STATIONARY = 3; 4645 4646 /** 4647 * Updates the device mobility state. Wifi uses this information to adjust the interval between 4648 * Wifi scans in order to balance power consumption with scan accuracy. 4649 * The default mobility state when the device boots is {@link #DEVICE_MOBILITY_STATE_UNKNOWN}. 4650 * This API should be called whenever there is a change in the mobility state. 4651 * @param state the updated device mobility state 4652 * @hide 4653 */ 4654 @SystemApi 4655 @RequiresPermission(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE) setDeviceMobilityState(@eviceMobilityState int state)4656 public void setDeviceMobilityState(@DeviceMobilityState int state) { 4657 try { 4658 mService.setDeviceMobilityState(state); 4659 } catch (RemoteException e) { 4660 throw e.rethrowFromSystemServer(); 4661 } 4662 } 4663 4664 /* Easy Connect - AKA Device Provisioning Protocol (DPP) */ 4665 4666 /** 4667 * Easy Connect Network role: Station. 4668 * 4669 * @hide 4670 */ 4671 @SystemApi 4672 public static final int EASY_CONNECT_NETWORK_ROLE_STA = 0; 4673 4674 /** 4675 * Easy Connect Network role: Access Point. 4676 * 4677 * @hide 4678 */ 4679 @SystemApi 4680 public static final int EASY_CONNECT_NETWORK_ROLE_AP = 1; 4681 4682 /** @hide */ 4683 @IntDef(prefix = {"EASY_CONNECT_NETWORK_ROLE_"}, value = { 4684 EASY_CONNECT_NETWORK_ROLE_STA, 4685 EASY_CONNECT_NETWORK_ROLE_AP, 4686 }) 4687 @Retention(RetentionPolicy.SOURCE) 4688 public @interface EasyConnectNetworkRole { 4689 } 4690 4691 /** 4692 * Start Easy Connect (DPP) in Configurator-Initiator role. The current device will initiate 4693 * Easy Connect bootstrapping with a peer, and configure the peer with the SSID and password of 4694 * the specified network using the Easy Connect protocol on an encrypted link. 4695 * 4696 * @param enrolleeUri URI of the Enrollee obtained separately (e.g. QR code scanning) 4697 * @param selectedNetworkId Selected network ID to be sent to the peer 4698 * @param enrolleeNetworkRole The network role of the enrollee 4699 * @param callback Callback for status updates 4700 * @param executor The Executor on which to run the callback. 4701 * @hide 4702 */ 4703 @SystemApi 4704 @RequiresPermission(anyOf = { 4705 android.Manifest.permission.NETWORK_SETTINGS, 4706 android.Manifest.permission.NETWORK_SETUP_WIZARD}) startEasyConnectAsConfiguratorInitiator(@onNull String enrolleeUri, int selectedNetworkId, @EasyConnectNetworkRole int enrolleeNetworkRole, @NonNull @CallbackExecutor Executor executor, @NonNull EasyConnectStatusCallback callback)4707 public void startEasyConnectAsConfiguratorInitiator(@NonNull String enrolleeUri, 4708 int selectedNetworkId, @EasyConnectNetworkRole int enrolleeNetworkRole, 4709 @NonNull @CallbackExecutor Executor executor, 4710 @NonNull EasyConnectStatusCallback callback) { 4711 Binder binder = new Binder(); 4712 try { 4713 mService.startDppAsConfiguratorInitiator(binder, enrolleeUri, selectedNetworkId, 4714 enrolleeNetworkRole, new EasyConnectCallbackProxy(executor, callback)); 4715 } catch (RemoteException e) { 4716 throw e.rethrowFromSystemServer(); 4717 } 4718 } 4719 4720 /** 4721 * Start Easy Connect (DPP) in Enrollee-Initiator role. The current device will initiate Easy 4722 * Connect bootstrapping with a peer, and receive the SSID and password from the peer 4723 * configurator. 4724 * 4725 * @param configuratorUri URI of the Configurator obtained separately (e.g. QR code scanning) 4726 * @param callback Callback for status updates 4727 * @param executor The Executor on which to run the callback. 4728 * @hide 4729 */ 4730 @SystemApi 4731 @RequiresPermission(anyOf = { 4732 android.Manifest.permission.NETWORK_SETTINGS, 4733 android.Manifest.permission.NETWORK_SETUP_WIZARD}) startEasyConnectAsEnrolleeInitiator(@onNull String configuratorUri, @NonNull @CallbackExecutor Executor executor, @NonNull EasyConnectStatusCallback callback)4734 public void startEasyConnectAsEnrolleeInitiator(@NonNull String configuratorUri, 4735 @NonNull @CallbackExecutor Executor executor, 4736 @NonNull EasyConnectStatusCallback callback) { 4737 Binder binder = new Binder(); 4738 try { 4739 mService.startDppAsEnrolleeInitiator(binder, configuratorUri, 4740 new EasyConnectCallbackProxy(executor, callback)); 4741 } catch (RemoteException e) { 4742 throw e.rethrowFromSystemServer(); 4743 } 4744 } 4745 4746 /** 4747 * Stop or abort a current Easy Connect (DPP) session. This call, once processed, will 4748 * terminate any ongoing transaction, and clean up all associated resources. Caller should not 4749 * expect any callbacks once this call is made. However, due to the asynchronous nature of 4750 * this call, a callback may be fired if it was already pending in the queue. 4751 * 4752 * @hide 4753 */ 4754 @SystemApi 4755 @RequiresPermission(anyOf = { 4756 android.Manifest.permission.NETWORK_SETTINGS, 4757 android.Manifest.permission.NETWORK_SETUP_WIZARD}) stopEasyConnectSession()4758 public void stopEasyConnectSession() { 4759 try { 4760 /* Request lower layers to stop/abort and clear resources */ 4761 mService.stopDppSession(); 4762 } catch (RemoteException e) { 4763 throw e.rethrowFromSystemServer(); 4764 } 4765 } 4766 4767 /** 4768 * Helper class to support Easy Connect (DPP) callbacks 4769 * 4770 * @hide 4771 */ 4772 private static class EasyConnectCallbackProxy extends IDppCallback.Stub { 4773 private final Executor mExecutor; 4774 private final EasyConnectStatusCallback mEasyConnectStatusCallback; 4775 EasyConnectCallbackProxy(Executor executor, EasyConnectStatusCallback easyConnectStatusCallback)4776 EasyConnectCallbackProxy(Executor executor, 4777 EasyConnectStatusCallback easyConnectStatusCallback) { 4778 mExecutor = executor; 4779 mEasyConnectStatusCallback = easyConnectStatusCallback; 4780 } 4781 4782 @Override onSuccessConfigReceived(int newNetworkId)4783 public void onSuccessConfigReceived(int newNetworkId) { 4784 Log.d(TAG, "Easy Connect onSuccessConfigReceived callback"); 4785 mExecutor.execute(() -> { 4786 mEasyConnectStatusCallback.onEnrolleeSuccess(newNetworkId); 4787 }); 4788 } 4789 4790 @Override onSuccess(int status)4791 public void onSuccess(int status) { 4792 Log.d(TAG, "Easy Connect onSuccess callback"); 4793 mExecutor.execute(() -> { 4794 mEasyConnectStatusCallback.onConfiguratorSuccess(status); 4795 }); 4796 } 4797 4798 @Override onFailure(int status)4799 public void onFailure(int status) { 4800 Log.d(TAG, "Easy Connect onFailure callback"); 4801 mExecutor.execute(() -> { 4802 mEasyConnectStatusCallback.onFailure(status); 4803 }); 4804 } 4805 4806 @Override onProgress(int status)4807 public void onProgress(int status) { 4808 Log.d(TAG, "Easy Connect onProgress callback"); 4809 mExecutor.execute(() -> { 4810 mEasyConnectStatusCallback.onProgress(status); 4811 }); 4812 } 4813 } 4814 4815 /** 4816 * Interface for Wi-Fi usability statistics listener. Should be implemented by applications and 4817 * set when calling {@link WifiManager#addOnWifiUsabilityStatsListener(Executor, 4818 * OnWifiUsabilityStatsListener)}. 4819 * 4820 * @hide 4821 */ 4822 @SystemApi 4823 public interface OnWifiUsabilityStatsListener { 4824 /** 4825 * Called when Wi-Fi usability statistics is updated. 4826 * 4827 * @param seqNum The sequence number of statistics, used to derive the timing of updated 4828 * Wi-Fi usability statistics, set by framework and incremented by one after 4829 * each update. 4830 * @param isSameBssidAndFreq The flag to indicate whether the BSSID and the frequency of 4831 * network stays the same or not relative to the last update of 4832 * Wi-Fi usability stats. 4833 * @param stats The updated Wi-Fi usability statistics. 4834 */ onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq, @NonNull WifiUsabilityStatsEntry stats)4835 void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq, 4836 @NonNull WifiUsabilityStatsEntry stats); 4837 } 4838 4839 /** 4840 * Adds a listener for Wi-Fi usability statistics. See {@link OnWifiUsabilityStatsListener}. 4841 * Multiple listeners can be added. Callers will be invoked periodically by framework to 4842 * inform clients about the current Wi-Fi usability statistics. Callers can remove a previously 4843 * added listener using {@link removeOnWifiUsabilityStatsListener}. 4844 * 4845 * @param executor The executor on which callback will be invoked. 4846 * @param listener Listener for Wifi usability statistics. 4847 * 4848 * @hide 4849 */ 4850 @SystemApi 4851 @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) addOnWifiUsabilityStatsListener(@onNull @allbackExecutor Executor executor, @NonNull OnWifiUsabilityStatsListener listener)4852 public void addOnWifiUsabilityStatsListener(@NonNull @CallbackExecutor Executor executor, 4853 @NonNull OnWifiUsabilityStatsListener listener) { 4854 if (executor == null) throw new IllegalArgumentException("executor cannot be null"); 4855 if (listener == null) throw new IllegalArgumentException("listener cannot be null"); 4856 if (mVerboseLoggingEnabled) { 4857 Log.v(TAG, "addOnWifiUsabilityStatsListener: listener=" + listener); 4858 } 4859 try { 4860 mService.addOnWifiUsabilityStatsListener(new Binder(), 4861 new IOnWifiUsabilityStatsListener.Stub() { 4862 @Override 4863 public void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq, 4864 WifiUsabilityStatsEntry stats) { 4865 if (mVerboseLoggingEnabled) { 4866 Log.v(TAG, "OnWifiUsabilityStatsListener: " 4867 + "onWifiUsabilityStats: seqNum=" + seqNum); 4868 } 4869 Binder.withCleanCallingIdentity(() -> 4870 executor.execute(() -> listener.onWifiUsabilityStats(seqNum, 4871 isSameBssidAndFreq, stats))); 4872 } 4873 }, 4874 listener.hashCode() 4875 ); 4876 } catch (RemoteException e) { 4877 throw e.rethrowFromSystemServer(); 4878 } 4879 } 4880 4881 /** 4882 * Allow callers to remove a previously registered listener. After calling this method, 4883 * applications will no longer receive Wi-Fi usability statistics. 4884 * 4885 * @param listener Listener to remove the Wi-Fi usability statistics. 4886 * 4887 * @hide 4888 */ 4889 @SystemApi 4890 @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) removeOnWifiUsabilityStatsListener(@onNull OnWifiUsabilityStatsListener listener)4891 public void removeOnWifiUsabilityStatsListener(@NonNull OnWifiUsabilityStatsListener listener) { 4892 if (listener == null) throw new IllegalArgumentException("listener cannot be null"); 4893 if (mVerboseLoggingEnabled) { 4894 Log.v(TAG, "removeOnWifiUsabilityStatsListener: listener=" + listener); 4895 } 4896 try { 4897 mService.removeOnWifiUsabilityStatsListener(listener.hashCode()); 4898 } catch (RemoteException e) { 4899 throw e.rethrowFromSystemServer(); 4900 } 4901 } 4902 4903 /** 4904 * Provide a Wi-Fi usability score information to be recorded (but not acted upon) by the 4905 * framework. The Wi-Fi usability score is derived from {@link OnWifiUsabilityStatsListener} 4906 * where a score is matched to Wi-Fi usability statistics using the sequence number. The score 4907 * is used to quantify whether Wi-Fi is usable in a future time. 4908 * 4909 * @param seqNum Sequence number of the Wi-Fi usability score. 4910 * @param score The Wi-Fi usability score, expected range: [0, 100]. 4911 * @param predictionHorizonSec Prediction horizon of the Wi-Fi usability score in second, 4912 * expected range: [0, 30]. 4913 * 4914 * @hide 4915 */ 4916 @SystemApi 4917 @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec)4918 public void updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec) { 4919 try { 4920 mService.updateWifiUsabilityScore(seqNum, score, predictionHorizonSec); 4921 } catch (RemoteException e) { 4922 throw e.rethrowFromSystemServer(); 4923 } 4924 } 4925 } 4926