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