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.IntRange; 26 import android.annotation.NonNull; 27 import android.annotation.Nullable; 28 import android.annotation.RequiresPermission; 29 import android.annotation.SdkConstant; 30 import android.annotation.SdkConstant.SdkConstantType; 31 import android.annotation.SuppressLint; 32 import android.annotation.SystemApi; 33 import android.annotation.SystemService; 34 import android.app.ActivityManager; 35 import android.compat.annotation.UnsupportedAppUsage; 36 import android.content.Context; 37 import android.content.pm.ParceledListSlice; 38 import android.net.ConnectivityManager; 39 import android.net.DhcpInfo; 40 import android.net.MacAddress; 41 import android.net.Network; 42 import android.net.NetworkStack; 43 import android.net.wifi.hotspot2.IProvisioningCallback; 44 import android.net.wifi.hotspot2.OsuProvider; 45 import android.net.wifi.hotspot2.PasspointConfiguration; 46 import android.net.wifi.hotspot2.ProvisioningCallback; 47 import android.os.Binder; 48 import android.os.Build; 49 import android.os.Handler; 50 import android.os.HandlerExecutor; 51 import android.os.IBinder; 52 import android.os.Looper; 53 import android.os.RemoteException; 54 import android.os.WorkSource; 55 import android.os.connectivity.WifiActivityEnergyInfo; 56 import android.text.TextUtils; 57 import android.util.CloseGuard; 58 import android.util.Log; 59 import android.util.Pair; 60 import android.util.SparseArray; 61 62 import com.android.internal.annotations.GuardedBy; 63 import com.android.internal.annotations.VisibleForTesting; 64 65 import java.lang.annotation.Retention; 66 import java.lang.annotation.RetentionPolicy; 67 import java.lang.ref.Reference; 68 import java.lang.ref.WeakReference; 69 import java.net.InetAddress; 70 import java.util.ArrayList; 71 import java.util.Collections; 72 import java.util.HashMap; 73 import java.util.List; 74 import java.util.Map; 75 import java.util.Objects; 76 import java.util.Set; 77 import java.util.StringTokenizer; 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 /** @hide */ 157 public static final int NETWORK_SUGGESTIONS_MAX_PER_APP_LOW_RAM = 256; 158 159 /** @hide */ 160 public static final int NETWORK_SUGGESTIONS_MAX_PER_APP_HIGH_RAM = 1024; 161 162 /** 163 * Reason code if all of the network suggestions were successfully added or removed. 164 */ 165 public static final int STATUS_NETWORK_SUGGESTIONS_SUCCESS = 0; 166 167 /** 168 * Reason code if there was an internal error in the platform while processing the addition or 169 * removal of suggestions. 170 */ 171 public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL = 1; 172 173 /** 174 * Reason code if the user has disallowed "android:change_wifi_state" app-ops from the app. 175 * @see android.app.AppOpsManager#unsafeCheckOp(String, int, String). 176 */ 177 public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED = 2; 178 179 /** 180 * Reason code if one or more of the network suggestions added already exists in platform's 181 * database. 182 * Note: this code will not be returned with Android 11 as in-place modification is allowed, 183 * please check {@link #addNetworkSuggestions(List)}. 184 * @see WifiNetworkSuggestion#equals(Object) 185 */ 186 public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE = 3; 187 188 /** 189 * Reason code if the number of network suggestions provided by the app crosses the max 190 * threshold set per app. 191 * The framework will reject all suggestions provided by {@link #addNetworkSuggestions(List)} if 192 * the total size exceeds the limit. 193 * @see #getMaxNumberOfNetworkSuggestionsPerApp() 194 */ 195 public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP = 4; 196 197 /** 198 * Reason code if one or more of the network suggestions removed does not exist in platform's 199 * database. 200 * The framework won't remove any suggestions if one or more of suggestions provided 201 * by {@link #removeNetworkSuggestions(List)} does not exist in database. 202 * @see WifiNetworkSuggestion#equals(Object) 203 */ 204 public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID = 5; 205 206 /** 207 * Reason code if one or more of the network suggestions added is not allowed. 208 * The framework will reject all suggestions provided by {@link #addNetworkSuggestions(List)} 209 * if one or more of them is not allowed. 210 * This error may be caused by suggestion is using SIM-based encryption method, but calling app 211 * is not carrier privileged. 212 */ 213 public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED = 6; 214 215 /** 216 * Reason code if one or more of the network suggestions added is invalid. Framework will reject 217 * all the suggestions in the list. 218 * The framework will reject all suggestions provided by {@link #addNetworkSuggestions(List)} 219 * if one or more of them is invalid. 220 * Please use {@link WifiNetworkSuggestion.Builder} to create network suggestions. 221 */ 222 public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_INVALID = 7; 223 224 /** @hide */ 225 @IntDef(prefix = { "STATUS_NETWORK_SUGGESTIONS_" }, value = { 226 STATUS_NETWORK_SUGGESTIONS_SUCCESS, 227 STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL, 228 STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED, 229 STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE, 230 STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP, 231 STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID, 232 STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED, 233 STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_INVALID, 234 }) 235 @Retention(RetentionPolicy.SOURCE) 236 public @interface NetworkSuggestionsStatusCode {} 237 238 /** 239 * Reason code if suggested network connection attempt failed with an unknown failure. 240 */ 241 public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN = 0; 242 /** 243 * Reason code if suggested network connection attempt failed with association failure. 244 */ 245 public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION = 1; 246 /** 247 * Reason code if suggested network connection attempt failed with an authentication failure. 248 */ 249 public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION = 2; 250 /** 251 * Reason code if suggested network connection attempt failed with an IP provision failure. 252 */ 253 public static final int STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING = 3; 254 255 /** @hide */ 256 @IntDef(prefix = {"STATUS_SUGGESTION_CONNECTION_FAILURE_"}, 257 value = {STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN, 258 STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION, 259 STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION, 260 STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING 261 }) 262 @Retention(RetentionPolicy.SOURCE) 263 public @interface SuggestionConnectionStatusCode {} 264 265 /** 266 * Broadcast intent action indicating whether Wi-Fi scanning is currently available. 267 * Available extras: 268 * - {@link #EXTRA_SCAN_AVAILABLE} 269 */ 270 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 271 public static final String ACTION_WIFI_SCAN_AVAILABILITY_CHANGED = 272 "android.net.wifi.action.WIFI_SCAN_AVAILABILITY_CHANGED"; 273 274 /** 275 * A boolean extra indicating whether scanning is currently available. 276 * Sent in the broadcast {@link #ACTION_WIFI_SCAN_AVAILABILITY_CHANGED}. 277 * Its value is true if scanning is currently available, false otherwise. 278 */ 279 public static final String EXTRA_SCAN_AVAILABLE = "android.net.wifi.extra.SCAN_AVAILABLE"; 280 281 /** 282 * Broadcast intent action indicating that the credential of a Wi-Fi network 283 * has been changed. One extra provides the ssid of the network. Another 284 * extra provides the event type, whether the credential is saved or forgot. 285 * @hide 286 */ 287 @SystemApi 288 public static final String WIFI_CREDENTIAL_CHANGED_ACTION = 289 "android.net.wifi.WIFI_CREDENTIAL_CHANGED"; 290 /** @hide */ 291 @SystemApi 292 public static final String EXTRA_WIFI_CREDENTIAL_EVENT_TYPE = "et"; 293 /** @hide */ 294 @SystemApi 295 public static final String EXTRA_WIFI_CREDENTIAL_SSID = "ssid"; 296 /** @hide */ 297 @SystemApi 298 public static final int WIFI_CREDENTIAL_SAVED = 0; 299 /** @hide */ 300 @SystemApi 301 public static final int WIFI_CREDENTIAL_FORGOT = 1; 302 303 /** @hide */ 304 @SystemApi 305 public static final int PASSPOINT_HOME_NETWORK = 0; 306 307 /** @hide */ 308 @SystemApi 309 public static final int PASSPOINT_ROAMING_NETWORK = 1; 310 311 /** 312 * Broadcast intent action indicating that a Passpoint provider icon has been received. 313 * 314 * Included extras: 315 * {@link #EXTRA_BSSID_LONG} 316 * {@link #EXTRA_FILENAME} 317 * {@link #EXTRA_ICON} 318 * 319 * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE 320 * 321 * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered 322 * components will be launched. 323 * 324 * @hide 325 */ 326 public static final String ACTION_PASSPOINT_ICON = "android.net.wifi.action.PASSPOINT_ICON"; 327 /** 328 * BSSID of an AP in long representation. The {@link #EXTRA_BSSID} contains BSSID in 329 * String representation. 330 * 331 * Retrieve with {@link android.content.Intent#getLongExtra(String, long)}. 332 * 333 * @hide 334 */ 335 public static final String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG"; 336 /** 337 * Icon data. 338 * 339 * Retrieve with {@link android.content.Intent#getParcelableExtra(String)} and cast into 340 * {@link android.graphics.drawable.Icon}. 341 * 342 * @hide 343 */ 344 public static final String EXTRA_ICON = "android.net.wifi.extra.ICON"; 345 /** 346 * Name of a file. 347 * 348 * Retrieve with {@link android.content.Intent#getStringExtra(String)}. 349 * 350 * @hide 351 */ 352 public static final String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME"; 353 354 /** 355 * Broadcast intent action indicating a Passpoint OSU Providers List element has been received. 356 * 357 * Included extras: 358 * {@link #EXTRA_BSSID_LONG} 359 * {@link #EXTRA_ANQP_ELEMENT_DATA} 360 * 361 * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE 362 * 363 * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered 364 * components will be launched. 365 * 366 * @hide 367 */ 368 public static final String ACTION_PASSPOINT_OSU_PROVIDERS_LIST = 369 "android.net.wifi.action.PASSPOINT_OSU_PROVIDERS_LIST"; 370 /** 371 * Raw binary data of an ANQP (Access Network Query Protocol) element. 372 * 373 * Retrieve with {@link android.content.Intent#getByteArrayExtra(String)}. 374 * 375 * @hide 376 */ 377 public static final String EXTRA_ANQP_ELEMENT_DATA = 378 "android.net.wifi.extra.ANQP_ELEMENT_DATA"; 379 380 /** 381 * Broadcast intent action indicating that a Passpoint Deauth Imminent frame has been received. 382 * 383 * Included extras: 384 * {@link #EXTRA_BSSID_LONG} 385 * {@link #EXTRA_ESS} 386 * {@link #EXTRA_DELAY} 387 * {@link #EXTRA_URL} 388 * 389 * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE 390 * 391 * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered 392 * components will be launched. 393 * 394 * @hide 395 */ 396 public static final String ACTION_PASSPOINT_DEAUTH_IMMINENT = 397 "android.net.wifi.action.PASSPOINT_DEAUTH_IMMINENT"; 398 /** 399 * Flag indicating BSS (Basic Service Set) or ESS (Extended Service Set). This will be set to 400 * {@code true} for ESS. 401 * 402 * Retrieve with {@link android.content.Intent#getBooleanExtra(String, boolean)}. 403 * 404 * @hide 405 */ 406 public static final String EXTRA_ESS = "android.net.wifi.extra.ESS"; 407 /** 408 * Delay in seconds. 409 * 410 * Retrieve with {@link android.content.Intent#getIntExtra(String, int)}. 411 * 412 * @hide 413 */ 414 public static final String EXTRA_DELAY = "android.net.wifi.extra.DELAY"; 415 416 /** 417 * Broadcast intent action indicating a Passpoint subscription remediation frame has been 418 * received. 419 * 420 * Included extras: 421 * {@link #EXTRA_BSSID_LONG} 422 * {@link #EXTRA_SUBSCRIPTION_REMEDIATION_METHOD} 423 * {@link #EXTRA_URL} 424 * 425 * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE 426 * 427 * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered 428 * components will be launched. 429 * 430 * @hide 431 */ 432 public static final String ACTION_PASSPOINT_SUBSCRIPTION_REMEDIATION = 433 "android.net.wifi.action.PASSPOINT_SUBSCRIPTION_REMEDIATION"; 434 /** 435 * The protocol supported by the subscription remediation server. The possible values are: 436 * 0 - OMA DM 437 * 1 - SOAP XML SPP 438 * 439 * Retrieve with {@link android.content.Intent#getIntExtra(String, int)}. 440 * 441 * @hide 442 */ 443 public static final String EXTRA_SUBSCRIPTION_REMEDIATION_METHOD = 444 "android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD"; 445 446 /** 447 * Activity Action: Receiver should launch Passpoint OSU (Online Sign Up) view. 448 * Included extras: 449 * 450 * {@link #EXTRA_OSU_NETWORK}: {@link Network} instance associated with OSU AP. 451 * {@link #EXTRA_URL}: String representation of a server URL used for OSU process. 452 * 453 * @hide 454 */ 455 @SystemApi 456 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 457 public static final String ACTION_PASSPOINT_LAUNCH_OSU_VIEW = 458 "android.net.wifi.action.PASSPOINT_LAUNCH_OSU_VIEW"; 459 460 /** 461 * The lookup key for a {@link android.net.Network} associated with a Passpoint OSU server. 462 * Included in the {@link #ACTION_PASSPOINT_LAUNCH_OSU_VIEW} broadcast. 463 * 464 * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}. 465 * 466 * @hide 467 */ 468 @SystemApi 469 public static final String EXTRA_OSU_NETWORK = "android.net.wifi.extra.OSU_NETWORK"; 470 471 /** 472 * String representation of an URL for Passpoint OSU. 473 * Included in the {@link #ACTION_PASSPOINT_LAUNCH_OSU_VIEW} broadcast. 474 * 475 * Retrieve with {@link android.content.Intent#getStringExtra(String)}. 476 * 477 * @hide 478 */ 479 @SystemApi 480 public static final String EXTRA_URL = "android.net.wifi.extra.URL"; 481 482 /** 483 * Broadcast intent action indicating that Wi-Fi has been enabled, disabled, 484 * enabling, disabling, or unknown. One extra provides this state as an int. 485 * Another extra provides the previous state, if available. No network-related 486 * permissions are required to subscribe to this broadcast. 487 * 488 * <p class="note">This broadcast is not delivered to manifest receivers in 489 * applications that target API version 26 or later. 490 * 491 * @see #EXTRA_WIFI_STATE 492 * @see #EXTRA_PREVIOUS_WIFI_STATE 493 */ 494 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 495 public static final String WIFI_STATE_CHANGED_ACTION = 496 "android.net.wifi.WIFI_STATE_CHANGED"; 497 /** 498 * The lookup key for an int that indicates whether Wi-Fi is enabled, 499 * disabled, enabling, disabling, or unknown. Retrieve it with 500 * {@link android.content.Intent#getIntExtra(String,int)}. 501 * 502 * @see #WIFI_STATE_DISABLED 503 * @see #WIFI_STATE_DISABLING 504 * @see #WIFI_STATE_ENABLED 505 * @see #WIFI_STATE_ENABLING 506 * @see #WIFI_STATE_UNKNOWN 507 */ 508 public static final String EXTRA_WIFI_STATE = "wifi_state"; 509 /** 510 * The previous Wi-Fi state. 511 * 512 * @see #EXTRA_WIFI_STATE 513 */ 514 public static final String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state"; 515 516 /** 517 * Wi-Fi is currently being disabled. The state will change to {@link #WIFI_STATE_DISABLED} if 518 * it finishes successfully. 519 * 520 * @see #WIFI_STATE_CHANGED_ACTION 521 * @see #getWifiState() 522 */ 523 public static final int WIFI_STATE_DISABLING = 0; 524 /** 525 * Wi-Fi is disabled. 526 * 527 * @see #WIFI_STATE_CHANGED_ACTION 528 * @see #getWifiState() 529 */ 530 public static final int WIFI_STATE_DISABLED = 1; 531 /** 532 * Wi-Fi is currently being enabled. The state will change to {@link #WIFI_STATE_ENABLED} if 533 * it finishes successfully. 534 * 535 * @see #WIFI_STATE_CHANGED_ACTION 536 * @see #getWifiState() 537 */ 538 public static final int WIFI_STATE_ENABLING = 2; 539 /** 540 * Wi-Fi is enabled. 541 * 542 * @see #WIFI_STATE_CHANGED_ACTION 543 * @see #getWifiState() 544 */ 545 public static final int WIFI_STATE_ENABLED = 3; 546 /** 547 * Wi-Fi is in an unknown state. This state will occur when an error happens while enabling 548 * or disabling. 549 * 550 * @see #WIFI_STATE_CHANGED_ACTION 551 * @see #getWifiState() 552 */ 553 public static final int WIFI_STATE_UNKNOWN = 4; 554 555 /** 556 * Broadcast intent action indicating that Wi-Fi AP has been enabled, disabled, 557 * enabling, disabling, or failed. 558 * 559 * @hide 560 */ 561 @SystemApi 562 public static final String WIFI_AP_STATE_CHANGED_ACTION = 563 "android.net.wifi.WIFI_AP_STATE_CHANGED"; 564 565 /** 566 * The lookup key for an int that indicates whether Wi-Fi AP is enabled, 567 * disabled, enabling, disabling, or failed. Retrieve it with 568 * {@link android.content.Intent#getIntExtra(String,int)}. 569 * 570 * @see #WIFI_AP_STATE_DISABLED 571 * @see #WIFI_AP_STATE_DISABLING 572 * @see #WIFI_AP_STATE_ENABLED 573 * @see #WIFI_AP_STATE_ENABLING 574 * @see #WIFI_AP_STATE_FAILED 575 * 576 * @hide 577 */ 578 @SystemApi 579 public static final String EXTRA_WIFI_AP_STATE = "wifi_state"; 580 581 /** 582 * An extra containing the int error code for Soft AP start failure. 583 * Can be obtained from the {@link #WIFI_AP_STATE_CHANGED_ACTION} using 584 * {@link android.content.Intent#getIntExtra}. 585 * This extra will only be attached if {@link #EXTRA_WIFI_AP_STATE} is 586 * attached and is equal to {@link #WIFI_AP_STATE_FAILED}. 587 * 588 * The error code will be one of: 589 * {@link #SAP_START_FAILURE_GENERAL}, 590 * {@link #SAP_START_FAILURE_NO_CHANNEL}, 591 * {@link #SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION} 592 * 593 * @hide 594 */ 595 @SystemApi 596 public static final String EXTRA_WIFI_AP_FAILURE_REASON = 597 "android.net.wifi.extra.WIFI_AP_FAILURE_REASON"; 598 /** 599 * The previous Wi-Fi state. 600 * 601 * @see #EXTRA_WIFI_AP_STATE 602 * 603 * @hide 604 */ 605 @SystemApi 606 public static final String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state"; 607 /** 608 * The lookup key for a String extra that stores the interface name used for the Soft AP. 609 * This extra is included in the broadcast {@link #WIFI_AP_STATE_CHANGED_ACTION}. 610 * Retrieve its value with {@link android.content.Intent#getStringExtra(String)}. 611 * 612 * @hide 613 */ 614 @SystemApi 615 public static final String EXTRA_WIFI_AP_INTERFACE_NAME = 616 "android.net.wifi.extra.WIFI_AP_INTERFACE_NAME"; 617 /** 618 * The lookup key for an int extra that stores the intended IP mode for this Soft AP. 619 * One of {@link #IFACE_IP_MODE_TETHERED} or {@link #IFACE_IP_MODE_LOCAL_ONLY}. 620 * This extra is included in the broadcast {@link #WIFI_AP_STATE_CHANGED_ACTION}. 621 * Retrieve its value with {@link android.content.Intent#getIntExtra(String, int)}. 622 * 623 * @hide 624 */ 625 @SystemApi 626 public static final String EXTRA_WIFI_AP_MODE = "android.net.wifi.extra.WIFI_AP_MODE"; 627 628 /** @hide */ 629 @IntDef(flag = false, prefix = { "WIFI_AP_STATE_" }, value = { 630 WIFI_AP_STATE_DISABLING, 631 WIFI_AP_STATE_DISABLED, 632 WIFI_AP_STATE_ENABLING, 633 WIFI_AP_STATE_ENABLED, 634 WIFI_AP_STATE_FAILED, 635 }) 636 @Retention(RetentionPolicy.SOURCE) 637 public @interface WifiApState {} 638 639 /** 640 * Wi-Fi AP is currently being disabled. The state will change to 641 * {@link #WIFI_AP_STATE_DISABLED} if it finishes successfully. 642 * 643 * @see #WIFI_AP_STATE_CHANGED_ACTION 644 * @see #getWifiApState() 645 * 646 * @hide 647 */ 648 @SystemApi 649 public static final int WIFI_AP_STATE_DISABLING = 10; 650 /** 651 * Wi-Fi AP is disabled. 652 * 653 * @see #WIFI_AP_STATE_CHANGED_ACTION 654 * @see #getWifiState() 655 * 656 * @hide 657 */ 658 @SystemApi 659 public static final int WIFI_AP_STATE_DISABLED = 11; 660 /** 661 * Wi-Fi AP is currently being enabled. The state will change to 662 * {@link #WIFI_AP_STATE_ENABLED} if it finishes successfully. 663 * 664 * @see #WIFI_AP_STATE_CHANGED_ACTION 665 * @see #getWifiApState() 666 * 667 * @hide 668 */ 669 @SystemApi 670 public static final int WIFI_AP_STATE_ENABLING = 12; 671 /** 672 * Wi-Fi AP is enabled. 673 * 674 * @see #WIFI_AP_STATE_CHANGED_ACTION 675 * @see #getWifiApState() 676 * 677 * @hide 678 */ 679 @SystemApi 680 public static final int WIFI_AP_STATE_ENABLED = 13; 681 /** 682 * Wi-Fi AP is in a failed state. This state will occur when an error occurs during 683 * enabling or disabling 684 * 685 * @see #WIFI_AP_STATE_CHANGED_ACTION 686 * @see #getWifiApState() 687 * 688 * @hide 689 */ 690 @SystemApi 691 public static final int WIFI_AP_STATE_FAILED = 14; 692 693 /** @hide */ 694 @IntDef(flag = false, prefix = { "SAP_START_FAILURE_" }, value = { 695 SAP_START_FAILURE_GENERAL, 696 SAP_START_FAILURE_NO_CHANNEL, 697 SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION, 698 }) 699 @Retention(RetentionPolicy.SOURCE) 700 public @interface SapStartFailure {} 701 702 /** 703 * All other reasons for AP start failure besides {@link #SAP_START_FAILURE_NO_CHANNEL} and 704 * {@link #SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}. 705 * 706 * @hide 707 */ 708 @SystemApi 709 public static final int SAP_START_FAILURE_GENERAL= 0; 710 711 /** 712 * If Wi-Fi AP start failed, this reason code means that no legal channel exists on user 713 * selected band due to regulatory constraints. 714 * 715 * @hide 716 */ 717 @SystemApi 718 public static final int SAP_START_FAILURE_NO_CHANNEL = 1; 719 720 /** 721 * If Wi-Fi AP start failed, this reason code means that the specified configuration 722 * is not supported by the current HAL version. 723 * 724 * @hide 725 */ 726 @SystemApi 727 public static final int SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION = 2; 728 729 730 /** @hide */ 731 @IntDef(flag = false, prefix = { "SAP_CLIENT_BLOCKED_REASON_" }, value = { 732 SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER, 733 SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS, 734 }) 735 @Retention(RetentionPolicy.SOURCE) 736 public @interface SapClientBlockedReason {} 737 738 /** 739 * If Soft Ap client is blocked, this reason code means that client doesn't exist in the 740 * specified configuration {@link SoftApConfiguration.Builder#setBlockedClientList(List)} 741 * and {@link SoftApConfiguration.Builder#setAllowedClientList(List)} 742 * and the {@link SoftApConfiguration.Builder#setClientControlByUserEnabled(boolean)} 743 * is configured as well. 744 * @hide 745 */ 746 @SystemApi 747 public static final int SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER = 0; 748 749 /** 750 * If Soft Ap client is blocked, this reason code means that no more clients can be 751 * associated to this AP since it reached maximum capacity. The maximum capacity is 752 * the minimum of {@link SoftApConfiguration.Builder#setMaxNumberOfClients(int)} and 753 * {@link SoftApCapability#getMaxSupportedClients} which get from 754 * {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)}. 755 * 756 * @hide 757 */ 758 @SystemApi 759 public static final int SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS = 1; 760 761 /** 762 * Client disconnected for unspecified reason. This could for example be because the AP is being 763 * shut down. 764 * @hide 765 */ 766 public static final int SAP_CLIENT_DISCONNECT_REASON_CODE_UNSPECIFIED = 2; 767 768 /** @hide */ 769 @Retention(RetentionPolicy.SOURCE) 770 @IntDef(prefix = {"IFACE_IP_MODE_"}, value = { 771 IFACE_IP_MODE_UNSPECIFIED, 772 IFACE_IP_MODE_CONFIGURATION_ERROR, 773 IFACE_IP_MODE_TETHERED, 774 IFACE_IP_MODE_LOCAL_ONLY}) 775 public @interface IfaceIpMode {} 776 777 /** 778 * Interface IP mode unspecified. 779 * 780 * @see #updateInterfaceIpState(String, int) 781 * 782 * @hide 783 */ 784 @SystemApi 785 public static final int IFACE_IP_MODE_UNSPECIFIED = -1; 786 787 /** 788 * Interface IP mode for configuration error. 789 * 790 * @see #updateInterfaceIpState(String, int) 791 * 792 * @hide 793 */ 794 @SystemApi 795 public static final int IFACE_IP_MODE_CONFIGURATION_ERROR = 0; 796 797 /** 798 * Interface IP mode for tethering. 799 * 800 * @see #updateInterfaceIpState(String, int) 801 * 802 * @hide 803 */ 804 @SystemApi 805 public static final int IFACE_IP_MODE_TETHERED = 1; 806 807 /** 808 * Interface IP mode for Local Only Hotspot. 809 * 810 * @see #updateInterfaceIpState(String, int) 811 * 812 * @hide 813 */ 814 @SystemApi 815 public static final int IFACE_IP_MODE_LOCAL_ONLY = 2; 816 817 /** 818 * Broadcast intent action indicating that the wifi network settings 819 * had been reset. 820 * 821 * Note: This intent is sent as a directed broadcast to each manifest registered receiver. 822 * Intent will not be received by dynamically registered receivers. 823 * @hide 824 */ 825 @SystemApi 826 @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING) 827 public static final String ACTION_NETWORK_SETTINGS_RESET = 828 "android.net.wifi.action.NETWORK_SETTINGS_RESET"; 829 830 /** 831 * Broadcast intent action indicating that a connection to the supplicant has 832 * been established (and it is now possible 833 * to perform Wi-Fi operations) or the connection to the supplicant has been 834 * lost. One extra provides the connection state as a boolean, where {@code true} 835 * means CONNECTED. 836 * @deprecated This is no longer supported. 837 * @see #EXTRA_SUPPLICANT_CONNECTED 838 */ 839 @Deprecated 840 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 841 public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION = 842 "android.net.wifi.supplicant.CONNECTION_CHANGE"; 843 /** 844 * The lookup key for a boolean that indicates whether a connection to 845 * the supplicant daemon has been gained or lost. {@code true} means 846 * a connection now exists. 847 * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}. 848 * @deprecated This is no longer supported. 849 */ 850 @Deprecated 851 public static final String EXTRA_SUPPLICANT_CONNECTED = "connected"; 852 /** 853 * Broadcast intent action indicating that the state of Wi-Fi connectivity 854 * has changed. An extra provides the new state 855 * in the form of a {@link android.net.NetworkInfo} object. No network-related 856 * permissions are required to subscribe to this broadcast. 857 * 858 * <p class="note">This broadcast is not delivered to manifest receivers in 859 * applications that target API version 26 or later. 860 * @see #EXTRA_NETWORK_INFO 861 */ 862 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 863 public static final String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE"; 864 /** 865 * The lookup key for a {@link android.net.NetworkInfo} object associated with the 866 * Wi-Fi network. Retrieve with 867 * {@link android.content.Intent#getParcelableExtra(String)}. 868 */ 869 public static final String EXTRA_NETWORK_INFO = "networkInfo"; 870 /** 871 * The lookup key for a String giving the BSSID of the access point to which 872 * we are connected. No longer used. 873 */ 874 @Deprecated 875 public static final String EXTRA_BSSID = "bssid"; 876 /** 877 * The lookup key for a {@link android.net.wifi.WifiInfo} object giving the 878 * information about the access point to which we are connected. 879 * No longer used. 880 */ 881 @Deprecated 882 public static final String EXTRA_WIFI_INFO = "wifiInfo"; 883 /** 884 * Broadcast intent action indicating that the state of establishing a connection to 885 * an access point has changed.One extra provides the new 886 * {@link SupplicantState}. Note that the supplicant state is Wi-Fi specific, and 887 * is not generally the most useful thing to look at if you are just interested in 888 * the overall state of connectivity. 889 * @see #EXTRA_NEW_STATE 890 * @see #EXTRA_SUPPLICANT_ERROR 891 * @deprecated This is no longer supported. 892 */ 893 @Deprecated 894 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 895 public static final String SUPPLICANT_STATE_CHANGED_ACTION = 896 "android.net.wifi.supplicant.STATE_CHANGE"; 897 /** 898 * The lookup key for a {@link SupplicantState} describing the new state 899 * Retrieve with 900 * {@link android.content.Intent#getParcelableExtra(String)}. 901 * @deprecated This is no longer supported. 902 */ 903 @Deprecated 904 public static final String EXTRA_NEW_STATE = "newState"; 905 906 /** 907 * The lookup key for a {@link SupplicantState} describing the supplicant 908 * error code if any 909 * Retrieve with 910 * {@link android.content.Intent#getIntExtra(String, int)}. 911 * @see #ERROR_AUTHENTICATING 912 * @deprecated This is no longer supported. 913 */ 914 @Deprecated 915 public static final String EXTRA_SUPPLICANT_ERROR = "supplicantError"; 916 917 /** 918 * The lookup key for a {@link SupplicantState} describing the supplicant 919 * error reason if any 920 * Retrieve with 921 * {@link android.content.Intent#getIntExtra(String, int)}. 922 * @see #ERROR_AUTH_FAILURE_#REASON_CODE 923 * @deprecated This is no longer supported. 924 * @hide 925 */ 926 @Deprecated 927 public static final String EXTRA_SUPPLICANT_ERROR_REASON = "supplicantErrorReason"; 928 929 /** 930 * Broadcast intent action indicating that the configured networks changed. 931 * This can be as a result of adding/updating/deleting a network. 932 * <br /> 933 * {@link #EXTRA_CHANGE_REASON} contains whether the configuration was added/changed/removed. 934 * {@link #EXTRA_WIFI_CONFIGURATION} is never set starting in Android 11. 935 * {@link #EXTRA_MULTIPLE_NETWORKS_CHANGED} is set for backwards compatibility reasons, but 936 * its value is always true, even if only a single network changed. 937 * <br /> 938 * The {@link android.Manifest.permission#ACCESS_WIFI_STATE ACCESS_WIFI_STATE} permission is 939 * required to receive this broadcast. 940 * 941 * @hide 942 */ 943 @SystemApi 944 public static final String CONFIGURED_NETWORKS_CHANGED_ACTION = 945 "android.net.wifi.CONFIGURED_NETWORKS_CHANGE"; 946 /** 947 * The lookup key for a {@link android.net.wifi.WifiConfiguration} object representing 948 * the changed Wi-Fi configuration when the {@link #CONFIGURED_NETWORKS_CHANGED_ACTION} 949 * broadcast is sent. 950 * Note: this extra is never set starting in Android 11. 951 * @hide 952 */ 953 @SystemApi 954 public static final String EXTRA_WIFI_CONFIGURATION = "wifiConfiguration"; 955 /** 956 * Multiple network configurations have changed. 957 * @see #CONFIGURED_NETWORKS_CHANGED_ACTION 958 * Note: this extra is always true starting in Android 11. 959 * @hide 960 */ 961 @SystemApi 962 public static final String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges"; 963 /** 964 * The lookup key for an integer indicating the reason a Wi-Fi network configuration 965 * has changed. One of {@link #CHANGE_REASON_ADDED}, {@link #CHANGE_REASON_REMOVED}, 966 * {@link #CHANGE_REASON_CONFIG_CHANGE}. 967 * 968 * @see #CONFIGURED_NETWORKS_CHANGED_ACTION 969 * @hide 970 */ 971 @SystemApi 972 public static final String EXTRA_CHANGE_REASON = "changeReason"; 973 /** 974 * The configuration is new and was added. 975 * @hide 976 */ 977 @SystemApi 978 public static final int CHANGE_REASON_ADDED = 0; 979 /** 980 * The configuration was removed and is no longer present in the system's list of 981 * configured networks. 982 * @hide 983 */ 984 @SystemApi 985 public static final int CHANGE_REASON_REMOVED = 1; 986 /** 987 * The configuration has changed as a result of explicit action or because the system 988 * took an automated action such as disabling a malfunctioning configuration. 989 * @hide 990 */ 991 @SystemApi 992 public static final int CHANGE_REASON_CONFIG_CHANGE = 2; 993 /** 994 * An access point scan has completed, and results are available. 995 * Call {@link #getScanResults()} to obtain the results. 996 * The broadcast intent may contain an extra field with the key {@link #EXTRA_RESULTS_UPDATED} 997 * and a {@code boolean} value indicating if the scan was successful. 998 */ 999 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1000 public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS"; 1001 1002 /** 1003 * Lookup key for a {@code boolean} extra in intent {@link #SCAN_RESULTS_AVAILABLE_ACTION} 1004 * representing if the scan was successful or not. 1005 * Scans may fail for multiple reasons, these may include: 1006 * <ol> 1007 * <li>An app requested too many scans in a certain period of time. 1008 * This may lead to additional scan request rejections via "scan throttling" for both 1009 * foreground and background apps. 1010 * Note: Apps holding android.Manifest.permission.NETWORK_SETTINGS permission are 1011 * exempted from scan throttling. 1012 * </li> 1013 * <li>The device is idle and scanning is disabled.</li> 1014 * <li>Wifi hardware reported a scan failure.</li> 1015 * </ol> 1016 * @return true scan was successful, results are updated 1017 * @return false scan was not successful, results haven't been updated since previous scan 1018 */ 1019 public static final String EXTRA_RESULTS_UPDATED = "resultsUpdated"; 1020 1021 /** 1022 * A batch of access point scans has been completed and the results areavailable. 1023 * Call {@link #getBatchedScanResults()} to obtain the results. 1024 * @deprecated This API is nolonger supported. 1025 * Use {@link android.net.wifi.WifiScanner} API 1026 * @hide 1027 */ 1028 @Deprecated 1029 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1030 public static final String BATCHED_SCAN_RESULTS_AVAILABLE_ACTION = 1031 "android.net.wifi.BATCHED_RESULTS"; 1032 1033 /** 1034 * The RSSI (signal strength) has changed. 1035 * 1036 * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE 1037 * @see #EXTRA_NEW_RSSI 1038 */ 1039 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1040 public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED"; 1041 /** 1042 * The lookup key for an {@code int} giving the new RSSI in dBm. 1043 */ 1044 public static final String EXTRA_NEW_RSSI = "newRssi"; 1045 1046 /** 1047 * @see #ACTION_LINK_CONFIGURATION_CHANGED 1048 * @hide 1049 */ 1050 @UnsupportedAppUsage 1051 public static final String LINK_CONFIGURATION_CHANGED_ACTION = 1052 "android.net.wifi.LINK_CONFIGURATION_CHANGED"; 1053 1054 /** 1055 * Broadcast intent action indicating that the link configuration changed on wifi. 1056 * <br />Included Extras: 1057 * <br />{@link #EXTRA_LINK_PROPERTIES}: {@link android.net.LinkProperties} object associated 1058 * with the Wi-Fi network. 1059 * <br /> No permissions are required to listen to this broadcast. 1060 * @hide 1061 */ 1062 @SystemApi 1063 public static final String ACTION_LINK_CONFIGURATION_CHANGED = 1064 // should be android.net.wifi.action.LINK_CONFIGURATION_CHANGED, but due to 1065 // @UnsupportedAppUsage leaving it as android.net.wifi.LINK_CONFIGURATION_CHANGED. 1066 LINK_CONFIGURATION_CHANGED_ACTION; 1067 1068 /** 1069 * The lookup key for a {@link android.net.LinkProperties} object associated with the 1070 * Wi-Fi network. 1071 * Included in the {@link #ACTION_LINK_CONFIGURATION_CHANGED} broadcast. 1072 * 1073 * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}. 1074 * @hide 1075 */ 1076 @SystemApi 1077 public static final String EXTRA_LINK_PROPERTIES = "android.net.wifi.extra.LINK_PROPERTIES"; 1078 1079 /** 1080 * The lookup key for a {@link android.net.NetworkCapabilities} object associated with the 1081 * Wi-Fi network. Retrieve with 1082 * {@link android.content.Intent#getParcelableExtra(String)}. 1083 * @hide 1084 */ 1085 public static final String EXTRA_NETWORK_CAPABILITIES = "networkCapabilities"; 1086 1087 /** 1088 * The network IDs of the configured networks could have changed. 1089 */ 1090 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1091 public static final String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED"; 1092 1093 /** 1094 * Activity Action: Show a system activity that allows the user to enable 1095 * scans to be available even with Wi-Fi turned off. 1096 * 1097 * <p>Notification of the result of this activity is posted using the 1098 * {@link android.app.Activity#onActivityResult} callback. The 1099 * <code>resultCode</code> 1100 * will be {@link android.app.Activity#RESULT_OK} if scan always mode has 1101 * been turned on or {@link android.app.Activity#RESULT_CANCELED} if the user 1102 * has rejected the request or an error has occurred. 1103 */ 1104 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 1105 public static final String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = 1106 "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE"; 1107 1108 /** 1109 * Activity Action: Pick a Wi-Fi network to connect to. 1110 * <p>Input: Nothing. 1111 * <p>Output: Nothing. 1112 */ 1113 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 1114 public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK"; 1115 1116 /** 1117 * Activity Action: Receiver should show UI to get user approval to enable WiFi. 1118 * <p>Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} string extra with 1119 * the name of the app requesting the action. 1120 * <p>Output: Nothing. 1121 * <p>No permissions are required to send this action. 1122 * @hide 1123 */ 1124 @SystemApi 1125 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 1126 public static final String ACTION_REQUEST_ENABLE = "android.net.wifi.action.REQUEST_ENABLE"; 1127 1128 /** 1129 * Activity Action: Receiver should show UI to get user approval to disable WiFi. 1130 * <p>Input: {@link android.content.Intent#EXTRA_PACKAGE_NAME} string extra with 1131 * the name of the app requesting the action. 1132 * <p>Output: Nothing. 1133 * <p>No permissions are required to send this action. 1134 * @hide 1135 */ 1136 @SystemApi 1137 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 1138 public static final String ACTION_REQUEST_DISABLE = "android.net.wifi.action.REQUEST_DISABLE"; 1139 1140 /** 1141 * Directed broadcast intent action indicating that the device has connected to one of the 1142 * network suggestions provided by the app. This will be sent post connection to a network 1143 * which was created with {@link WifiNetworkSuggestion.Builder#setIsAppInteractionRequired( 1144 * boolean)} 1145 * flag set. 1146 * <p> 1147 * Note: The broadcast is sent to the app only if it holds 1148 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission. 1149 * 1150 * @see #EXTRA_NETWORK_SUGGESTION 1151 */ 1152 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1153 public static final String ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION = 1154 "android.net.wifi.action.WIFI_NETWORK_SUGGESTION_POST_CONNECTION"; 1155 /** 1156 * Sent as as a part of {@link #ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION} that holds 1157 * an instance of {@link WifiNetworkSuggestion} corresponding to the connected network. 1158 */ 1159 public static final String EXTRA_NETWORK_SUGGESTION = 1160 "android.net.wifi.extra.NETWORK_SUGGESTION"; 1161 1162 /** 1163 * Internally used Wi-Fi lock mode representing the case were no locks are held. 1164 * @hide 1165 */ 1166 public static final int WIFI_MODE_NO_LOCKS_HELD = 0; 1167 1168 /** 1169 * In this Wi-Fi lock mode, Wi-Fi will be kept active, 1170 * and will behave normally, i.e., it will attempt to automatically 1171 * establish a connection to a remembered access point that is 1172 * within range, and will do periodic scans if there are remembered 1173 * access points but none are in range. 1174 * 1175 * @deprecated This API is non-functional and will have no impact. 1176 */ 1177 @Deprecated 1178 public static final int WIFI_MODE_FULL = 1; 1179 1180 /** 1181 * In this Wi-Fi lock mode, Wi-Fi will be kept active, 1182 * but the only operation that will be supported is initiation of 1183 * scans, and the subsequent reporting of scan results. No attempts 1184 * will be made to automatically connect to remembered access points, 1185 * nor will periodic scans be automatically performed looking for 1186 * remembered access points. Scans must be explicitly requested by 1187 * an application in this mode. 1188 * 1189 * @deprecated This API is non-functional and will have no impact. 1190 */ 1191 @Deprecated 1192 public static final int WIFI_MODE_SCAN_ONLY = 2; 1193 1194 /** 1195 * In this Wi-Fi lock mode, Wi-Fi will not go to power save. 1196 * This results in operating with low packet latency. 1197 * The lock is only active when the device is connected to an access point. 1198 * The lock is active even when the device screen is off or the acquiring application is 1199 * running in the background. 1200 * This mode will consume more power and hence should be used only 1201 * when there is a need for this tradeoff. 1202 * <p> 1203 * An example use case is when a voice connection needs to be 1204 * kept active even after the device screen goes off. 1205 * Holding a {@link #WIFI_MODE_FULL_HIGH_PERF} lock for the 1206 * duration of the voice call may improve the call quality. 1207 * <p> 1208 * When there is no support from the hardware, the {@link #WIFI_MODE_FULL_HIGH_PERF} 1209 * lock will have no impact. 1210 */ 1211 public static final int WIFI_MODE_FULL_HIGH_PERF = 3; 1212 1213 /** 1214 * In this Wi-Fi lock mode, Wi-Fi will operate with a priority to achieve low latency. 1215 * {@link #WIFI_MODE_FULL_LOW_LATENCY} lock has the following limitations: 1216 * <ol> 1217 * <li>The lock is only active when the device is connected to an access point.</li> 1218 * <li>The lock is only active when the screen is on.</li> 1219 * <li>The lock is only active when the acquiring app is running in the foreground.</li> 1220 * </ol> 1221 * Low latency mode optimizes for reduced packet latency, 1222 * and as a result other performance measures may suffer when there are trade-offs to make: 1223 * <ol> 1224 * <li>Battery life may be reduced.</li> 1225 * <li>Throughput may be reduced.</li> 1226 * <li>Frequency of Wi-Fi scanning may be reduced. This may result in: </li> 1227 * <ul> 1228 * <li>The device may not roam or switch to the AP with highest signal quality.</li> 1229 * <li>Location accuracy may be reduced.</li> 1230 * </ul> 1231 * </ol> 1232 * <p> 1233 * Example use cases are real time gaming or virtual reality applications where 1234 * low latency is a key factor for user experience. 1235 * <p> 1236 * Note: For an app which acquires both {@link #WIFI_MODE_FULL_LOW_LATENCY} and 1237 * {@link #WIFI_MODE_FULL_HIGH_PERF} locks, {@link #WIFI_MODE_FULL_LOW_LATENCY} 1238 * lock will be effective when app is running in foreground and screen is on, 1239 * while the {@link #WIFI_MODE_FULL_HIGH_PERF} lock will take effect otherwise. 1240 */ 1241 public static final int WIFI_MODE_FULL_LOW_LATENCY = 4; 1242 1243 1244 /** Anything worse than or equal to this will show 0 bars. */ 1245 @UnsupportedAppUsage 1246 private static final int MIN_RSSI = -100; 1247 1248 /** Anything better than or equal to this will show the max bars. */ 1249 @UnsupportedAppUsage 1250 private static final int MAX_RSSI = -55; 1251 1252 /** 1253 * Number of RSSI levels used in the framework to initiate {@link #RSSI_CHANGED_ACTION} 1254 * broadcast, where each level corresponds to a range of RSSI values. 1255 * The {@link #RSSI_CHANGED_ACTION} broadcast will only fire if the RSSI 1256 * change is significant enough to change the RSSI signal level. 1257 * @hide 1258 */ 1259 @UnsupportedAppUsage 1260 public static final int RSSI_LEVELS = 5; 1261 1262 //TODO (b/146346676): This needs to be removed, not used in the code. 1263 /** 1264 * Auto settings in the driver. The driver could choose to operate on both 1265 * 2.4 GHz and 5 GHz or make a dynamic decision on selecting the band. 1266 * @hide 1267 */ 1268 @UnsupportedAppUsage 1269 public static final int WIFI_FREQUENCY_BAND_AUTO = 0; 1270 1271 /** 1272 * Operation on 5 GHz alone 1273 * @hide 1274 */ 1275 @UnsupportedAppUsage 1276 public static final int WIFI_FREQUENCY_BAND_5GHZ = 1; 1277 1278 /** 1279 * Operation on 2.4 GHz alone 1280 * @hide 1281 */ 1282 @UnsupportedAppUsage 1283 public static final int WIFI_FREQUENCY_BAND_2GHZ = 2; 1284 1285 /** @hide */ 1286 public static final boolean DEFAULT_POOR_NETWORK_AVOIDANCE_ENABLED = false; 1287 1288 /** 1289 * Maximum number of active locks we allow. 1290 * This limit was added to prevent apps from creating a ridiculous number 1291 * of locks and crashing the system by overflowing the global ref table. 1292 */ 1293 private static final int MAX_ACTIVE_LOCKS = 50; 1294 1295 /** Indicates an invalid SSID. */ 1296 public static final String UNKNOWN_SSID = "<unknown ssid>"; 1297 1298 /** @hide */ 1299 public static final MacAddress ALL_ZEROS_MAC_ADDRESS = 1300 MacAddress.fromString("00:00:00:00:00:00"); 1301 1302 /* Number of currently active WifiLocks and MulticastLocks */ 1303 @UnsupportedAppUsage 1304 private int mActiveLockCount; 1305 1306 private Context mContext; 1307 @UnsupportedAppUsage 1308 IWifiManager mService; 1309 private final int mTargetSdkVersion; 1310 1311 private Looper mLooper; 1312 private boolean mVerboseLoggingEnabled = false; 1313 1314 private final Object mLock = new Object(); // lock guarding access to the following vars 1315 @GuardedBy("mLock") 1316 private LocalOnlyHotspotCallbackProxy mLOHSCallbackProxy; 1317 @GuardedBy("mLock") 1318 private LocalOnlyHotspotObserverProxy mLOHSObserverProxy; 1319 1320 /** 1321 * Create a new WifiManager instance. 1322 * Applications will almost always want to use 1323 * {@link android.content.Context#getSystemService Context.getSystemService} to retrieve 1324 * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}. 1325 * 1326 * @param context the application context 1327 * @param service the Binder interface 1328 * @param looper the Looper used to deliver callbacks 1329 * @hide - hide this because it takes in a parameter of type IWifiManager, which 1330 * is a system private class. 1331 */ WifiManager(@onNull Context context, @NonNull IWifiManager service, @NonNull Looper looper)1332 public WifiManager(@NonNull Context context, @NonNull IWifiManager service, 1333 @NonNull Looper looper) { 1334 mContext = context; 1335 mService = service; 1336 mLooper = looper; 1337 mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion; 1338 updateVerboseLoggingEnabledFromService(); 1339 } 1340 1341 /** 1342 * Return a list of all the networks configured for the current foreground 1343 * user. 1344 * 1345 * Not all fields of WifiConfiguration are returned. Only the following 1346 * fields are filled in: 1347 * <ul> 1348 * <li>networkId</li> 1349 * <li>SSID</li> 1350 * <li>BSSID</li> 1351 * <li>priority</li> 1352 * <li>allowedProtocols</li> 1353 * <li>allowedKeyManagement</li> 1354 * <li>allowedAuthAlgorithms</li> 1355 * <li>allowedPairwiseCiphers</li> 1356 * <li>allowedGroupCiphers</li> 1357 * <li>status</li> 1358 * </ul> 1359 * @return a list of network configurations in the form of a list 1360 * of {@link WifiConfiguration} objects. 1361 * 1362 * @deprecated 1363 * a) See {@link WifiNetworkSpecifier.Builder#build()} for new 1364 * mechanism to trigger connection to a Wi-Fi network. 1365 * b) See {@link #addNetworkSuggestions(List)}, 1366 * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration 1367 * when auto-connecting to wifi. 1368 * <b>Compatibility Note:</b> For applications targeting 1369 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return an 1370 * empty list. 1371 * <p> 1372 * Deprecation Exemptions: 1373 * <ul> 1374 * <li>Device Owner (DO), Profile Owner (PO) and system apps will have access to the full list. 1375 * <li>Callers with Carrier privilege will receive a restricted list only containing 1376 * configurations which they created. 1377 * </ul> 1378 */ 1379 @Deprecated 1380 @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE}) getConfiguredNetworks()1381 public List<WifiConfiguration> getConfiguredNetworks() { 1382 try { 1383 ParceledListSlice<WifiConfiguration> parceledList = 1384 mService.getConfiguredNetworks(mContext.getOpPackageName(), 1385 mContext.getAttributionTag()); 1386 if (parceledList == null) { 1387 return Collections.emptyList(); 1388 } 1389 return parceledList.getList(); 1390 } catch (RemoteException e) { 1391 throw e.rethrowFromSystemServer(); 1392 } 1393 } 1394 1395 /** @hide */ 1396 @SystemApi 1397 @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE, READ_WIFI_CREDENTIAL}) getPrivilegedConfiguredNetworks()1398 public List<WifiConfiguration> getPrivilegedConfiguredNetworks() { 1399 try { 1400 ParceledListSlice<WifiConfiguration> parceledList = 1401 mService.getPrivilegedConfiguredNetworks(mContext.getOpPackageName(), 1402 mContext.getAttributionTag()); 1403 if (parceledList == null) { 1404 return Collections.emptyList(); 1405 } 1406 return parceledList.getList(); 1407 } catch (RemoteException e) { 1408 throw e.rethrowFromSystemServer(); 1409 } 1410 } 1411 1412 /** 1413 * Returns a list of all matching WifiConfigurations for a given list of ScanResult. 1414 * 1415 * An empty list will be returned when no configurations are installed or if no configurations 1416 * match the ScanResult. 1417 * 1418 * @param scanResults a list of scanResult that represents the BSSID 1419 * @return List that consists of {@link WifiConfiguration} and corresponding scanResults per 1420 * network type({@link #PASSPOINT_HOME_NETWORK} and {@link #PASSPOINT_ROAMING_NETWORK}). 1421 * @hide 1422 */ 1423 @SystemApi 1424 @RequiresPermission(anyOf = { 1425 android.Manifest.permission.NETWORK_SETTINGS, 1426 android.Manifest.permission.NETWORK_SETUP_WIZARD 1427 }) 1428 @NonNull getAllMatchingWifiConfigs( @onNull List<ScanResult> scanResults)1429 public List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> getAllMatchingWifiConfigs( 1430 @NonNull List<ScanResult> scanResults) { 1431 List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> configs = new ArrayList<>(); 1432 try { 1433 Map<String, Map<Integer, List<ScanResult>>> results = 1434 mService.getAllMatchingPasspointProfilesForScanResults(scanResults); 1435 if (results.isEmpty()) { 1436 return configs; 1437 } 1438 List<WifiConfiguration> wifiConfigurations = 1439 mService.getWifiConfigsForPasspointProfiles( 1440 new ArrayList<>(results.keySet())); 1441 for (WifiConfiguration configuration : wifiConfigurations) { 1442 Map<Integer, List<ScanResult>> scanResultsPerNetworkType = 1443 results.get(configuration.getKey()); 1444 if (scanResultsPerNetworkType != null) { 1445 configs.add(Pair.create(configuration, scanResultsPerNetworkType)); 1446 } 1447 } 1448 } catch (RemoteException e) { 1449 throw e.rethrowFromSystemServer(); 1450 } 1451 1452 return configs; 1453 } 1454 1455 /** 1456 * Retrieve a list of {@link WifiConfiguration} for available {@link WifiNetworkSuggestion} 1457 * matching the given list of {@link ScanResult}. 1458 * 1459 * An available {@link WifiNetworkSuggestion} must satisfy: 1460 * <ul> 1461 * <li> Matching one of the {@link ScanResult} from the given list. 1462 * <li> and {@link WifiNetworkSuggestion.Builder#setIsUserAllowedToManuallyConnect(boolean)} set 1463 * to true. 1464 * </ul> 1465 * 1466 * @param scanResults a list of scanResult. 1467 * @return a list of @link WifiConfiguration} for available {@link WifiNetworkSuggestion} 1468 * @hide 1469 */ 1470 @SystemApi 1471 @RequiresPermission(anyOf = { 1472 android.Manifest.permission.NETWORK_SETTINGS, 1473 android.Manifest.permission.NETWORK_SETUP_WIZARD 1474 }) 1475 @NonNull getWifiConfigForMatchedNetworkSuggestionsSharedWithUser( @onNull List<ScanResult> scanResults)1476 public List<WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser( 1477 @NonNull List<ScanResult> scanResults) { 1478 try { 1479 return mService.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(scanResults); 1480 } catch (RemoteException e) { 1481 throw e.rethrowAsRuntimeException(); 1482 } 1483 } 1484 1485 /** 1486 * Returns a list of unique Hotspot 2.0 OSU (Online Sign-Up) providers associated with a given 1487 * list of ScanResult. 1488 * 1489 * An empty list will be returned if no match is found. 1490 * 1491 * @param scanResults a list of ScanResult 1492 * @return Map that consists {@link OsuProvider} and a list of matching {@link ScanResult} 1493 * @hide 1494 */ 1495 @SystemApi 1496 @RequiresPermission(anyOf = { 1497 android.Manifest.permission.NETWORK_SETTINGS, 1498 android.Manifest.permission.NETWORK_SETUP_WIZARD 1499 }) 1500 @NonNull getMatchingOsuProviders( @ullable List<ScanResult> scanResults)1501 public Map<OsuProvider, List<ScanResult>> getMatchingOsuProviders( 1502 @Nullable List<ScanResult> scanResults) { 1503 if (scanResults == null) { 1504 return new HashMap<>(); 1505 } 1506 try { 1507 return mService.getMatchingOsuProviders(scanResults); 1508 } catch (RemoteException e) { 1509 throw e.rethrowFromSystemServer(); 1510 } 1511 } 1512 1513 /** 1514 * Returns the matching Passpoint R2 configurations for given OSU (Online Sign-Up) providers. 1515 * 1516 * Given a list of OSU providers, this only returns OSU providers that already have Passpoint R2 1517 * configurations in the device. 1518 * An empty map will be returned when there is no matching Passpoint R2 configuration for the 1519 * given OsuProviders. 1520 * 1521 * @param osuProviders a set of {@link OsuProvider} 1522 * @return Map that consists of {@link OsuProvider} and matching {@link PasspointConfiguration}. 1523 * @hide 1524 */ 1525 @SystemApi 1526 @RequiresPermission(anyOf = { 1527 android.Manifest.permission.NETWORK_SETTINGS, 1528 android.Manifest.permission.NETWORK_SETUP_WIZARD 1529 }) 1530 @NonNull getMatchingPasspointConfigsForOsuProviders( @onNull Set<OsuProvider> osuProviders)1531 public Map<OsuProvider, PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders( 1532 @NonNull Set<OsuProvider> osuProviders) { 1533 try { 1534 return mService.getMatchingPasspointConfigsForOsuProviders( 1535 new ArrayList<>(osuProviders)); 1536 } catch (RemoteException e) { 1537 throw e.rethrowFromSystemServer(); 1538 } 1539 } 1540 1541 /** 1542 * Add a new network description to the set of configured networks. 1543 * The {@code networkId} field of the supplied configuration object 1544 * is ignored. 1545 * <p/> 1546 * The new network will be marked DISABLED by default. To enable it, 1547 * called {@link #enableNetwork}. 1548 * 1549 * @param config the set of variables that describe the configuration, 1550 * contained in a {@link WifiConfiguration} object. 1551 * If the {@link WifiConfiguration} has an Http Proxy set 1552 * the calling app must be System, or be provisioned as the Profile or Device Owner. 1553 * @return the ID of the newly created network description. This is used in 1554 * other operations to specified the network to be acted upon. 1555 * Returns {@code -1} on failure. 1556 * 1557 * @deprecated 1558 * a) See {@link WifiNetworkSpecifier.Builder#build()} for new 1559 * mechanism to trigger connection to a Wi-Fi network. 1560 * b) See {@link #addNetworkSuggestions(List)}, 1561 * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration 1562 * when auto-connecting to wifi. 1563 * <b>Compatibility Note:</b> For applications targeting 1564 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return 1565 * {@code -1}. 1566 * <p> 1567 * Deprecation Exemptions: 1568 * <ul> 1569 * <li>Device Owner (DO), Profile Owner (PO) and system apps. 1570 * </ul> 1571 */ 1572 @Deprecated addNetwork(WifiConfiguration config)1573 public int addNetwork(WifiConfiguration config) { 1574 if (config == null) { 1575 return -1; 1576 } 1577 config.networkId = -1; 1578 return addOrUpdateNetwork(config); 1579 } 1580 1581 /** 1582 * Update the network description of an existing configured network. 1583 * 1584 * @param config the set of variables that describe the configuration, 1585 * contained in a {@link WifiConfiguration} object. It may 1586 * be sparse, so that only the items that are being changed 1587 * are non-<code>null</code>. The {@code networkId} field 1588 * must be set to the ID of the existing network being updated. 1589 * If the {@link WifiConfiguration} has an Http Proxy set 1590 * the calling app must be System, or be provisioned as the Profile or Device Owner. 1591 * @return Returns the {@code networkId} of the supplied 1592 * {@code WifiConfiguration} on success. 1593 * <br/> 1594 * Returns {@code -1} on failure, including when the {@code networkId} 1595 * field of the {@code WifiConfiguration} does not refer to an 1596 * existing network. 1597 * 1598 * @deprecated 1599 * a) See {@link WifiNetworkSpecifier.Builder#build()} for new 1600 * mechanism to trigger connection to a Wi-Fi network. 1601 * b) See {@link #addNetworkSuggestions(List)}, 1602 * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration 1603 * when auto-connecting to wifi. 1604 * <b>Compatibility Note:</b> For applications targeting 1605 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return 1606 * {@code -1}. 1607 * <p> 1608 * Deprecation Exemptions: 1609 * <ul> 1610 * <li>Device Owner (DO), Profile Owner (PO) and system apps. 1611 * </ul> 1612 */ 1613 @Deprecated updateNetwork(WifiConfiguration config)1614 public int updateNetwork(WifiConfiguration config) { 1615 if (config == null || config.networkId < 0) { 1616 return -1; 1617 } 1618 return addOrUpdateNetwork(config); 1619 } 1620 1621 /** 1622 * Internal method for doing the RPC that creates a new network description 1623 * or updates an existing one. 1624 * 1625 * @param config The possibly sparse object containing the variables that 1626 * are to set or updated in the network description. 1627 * @return the ID of the network on success, {@code -1} on failure. 1628 */ addOrUpdateNetwork(WifiConfiguration config)1629 private int addOrUpdateNetwork(WifiConfiguration config) { 1630 try { 1631 return mService.addOrUpdateNetwork(config, mContext.getOpPackageName()); 1632 } catch (RemoteException e) { 1633 throw e.rethrowFromSystemServer(); 1634 } 1635 } 1636 1637 /** 1638 * Interface for indicating user selection from the list of networks presented in the 1639 * {@link NetworkRequestMatchCallback#onMatch(List)}. 1640 * 1641 * The platform will implement this callback and pass it along with the 1642 * {@link NetworkRequestMatchCallback#onUserSelectionCallbackRegistration( 1643 * NetworkRequestUserSelectionCallback)}. The UI component handling 1644 * {@link NetworkRequestMatchCallback} will invoke {@link #select(WifiConfiguration)} or 1645 * {@link #reject()} to return the user's selection back to the platform via this callback. 1646 * @hide 1647 */ 1648 @SystemApi 1649 public interface NetworkRequestUserSelectionCallback { 1650 /** 1651 * User selected this network to connect to. 1652 * @param wifiConfiguration WifiConfiguration object corresponding to the network 1653 * user selected. 1654 */ 1655 @SuppressLint("CallbackMethodName") select(@onNull WifiConfiguration wifiConfiguration)1656 default void select(@NonNull WifiConfiguration wifiConfiguration) {} 1657 1658 /** 1659 * User rejected the app's request. 1660 */ 1661 @SuppressLint("CallbackMethodName") reject()1662 default void reject() {} 1663 } 1664 1665 /** 1666 * Interface for network request callback. Should be implemented by applications and passed when 1667 * calling {@link #registerNetworkRequestMatchCallback(Executor, 1668 * WifiManager.NetworkRequestMatchCallback)}. 1669 * 1670 * This is meant to be implemented by a UI component to present the user with a list of networks 1671 * matching the app's request. The user is allowed to pick one of these networks to connect to 1672 * or reject the request by the app. 1673 * @hide 1674 */ 1675 @SystemApi 1676 public interface NetworkRequestMatchCallback { 1677 /** 1678 * Invoked to register a callback to be invoked to convey user selection. The callback 1679 * object passed in this method is to be invoked by the UI component after the service sends 1680 * a list of matching scan networks using {@link #onMatch(List)} and user picks a network 1681 * from that list. 1682 * 1683 * @param userSelectionCallback Callback object to send back the user selection. 1684 */ onUserSelectionCallbackRegistration( @onNull NetworkRequestUserSelectionCallback userSelectionCallback)1685 default void onUserSelectionCallbackRegistration( 1686 @NonNull NetworkRequestUserSelectionCallback userSelectionCallback) {} 1687 1688 /** 1689 * Invoked when the active network request is aborted, either because 1690 * <li> The app released the request, OR</li> 1691 * <li> Request was overridden by a new request</li> 1692 * This signals the end of processing for the current request and should stop the UI 1693 * component. No subsequent calls from the UI component will be handled by the platform. 1694 */ onAbort()1695 default void onAbort() {} 1696 1697 /** 1698 * Invoked when a network request initiated by an app matches some networks in scan results. 1699 * This may be invoked multiple times for a single network request as the platform finds new 1700 * matching networks in scan results. 1701 * 1702 * @param scanResults List of {@link ScanResult} objects corresponding to the networks 1703 * matching the request. 1704 */ onMatch(@onNull List<ScanResult> scanResults)1705 default void onMatch(@NonNull List<ScanResult> scanResults) {} 1706 1707 /** 1708 * Invoked on a successful connection with the network that the user selected 1709 * via {@link NetworkRequestUserSelectionCallback}. 1710 * 1711 * @param wifiConfiguration WifiConfiguration object corresponding to the network that the 1712 * user selected. 1713 */ onUserSelectionConnectSuccess(@onNull WifiConfiguration wifiConfiguration)1714 default void onUserSelectionConnectSuccess(@NonNull WifiConfiguration wifiConfiguration) {} 1715 1716 /** 1717 * Invoked on failure to establish connection with the network that the user selected 1718 * via {@link NetworkRequestUserSelectionCallback}. 1719 * 1720 * @param wifiConfiguration WifiConfiguration object corresponding to the network 1721 * user selected. 1722 */ onUserSelectionConnectFailure(@onNull WifiConfiguration wifiConfiguration)1723 default void onUserSelectionConnectFailure(@NonNull WifiConfiguration wifiConfiguration) {} 1724 } 1725 1726 /** 1727 * Callback proxy for NetworkRequestUserSelectionCallback objects. 1728 * @hide 1729 */ 1730 private class NetworkRequestUserSelectionCallbackProxy implements 1731 NetworkRequestUserSelectionCallback { 1732 private final INetworkRequestUserSelectionCallback mCallback; 1733 NetworkRequestUserSelectionCallbackProxy( INetworkRequestUserSelectionCallback callback)1734 NetworkRequestUserSelectionCallbackProxy( 1735 INetworkRequestUserSelectionCallback callback) { 1736 mCallback = callback; 1737 } 1738 1739 @Override select(@onNull WifiConfiguration wifiConfiguration)1740 public void select(@NonNull WifiConfiguration wifiConfiguration) { 1741 if (mVerboseLoggingEnabled) { 1742 Log.v(TAG, "NetworkRequestUserSelectionCallbackProxy: select " 1743 + "wificonfiguration: " + wifiConfiguration); 1744 } 1745 try { 1746 mCallback.select(wifiConfiguration); 1747 } catch (RemoteException e) { 1748 Log.e(TAG, "Failed to invoke onSelected", e); 1749 throw e.rethrowFromSystemServer(); 1750 } 1751 } 1752 1753 @Override reject()1754 public void reject() { 1755 if (mVerboseLoggingEnabled) { 1756 Log.v(TAG, "NetworkRequestUserSelectionCallbackProxy: reject"); 1757 } 1758 try { 1759 mCallback.reject(); 1760 } catch (RemoteException e) { 1761 Log.e(TAG, "Failed to invoke onRejected", e); 1762 throw e.rethrowFromSystemServer(); 1763 } 1764 } 1765 } 1766 1767 /** 1768 * Callback proxy for NetworkRequestMatchCallback objects. 1769 * @hide 1770 */ 1771 private class NetworkRequestMatchCallbackProxy extends INetworkRequestMatchCallback.Stub { 1772 private final Executor mExecutor; 1773 private final NetworkRequestMatchCallback mCallback; 1774 NetworkRequestMatchCallbackProxy(Executor executor, NetworkRequestMatchCallback callback)1775 NetworkRequestMatchCallbackProxy(Executor executor, NetworkRequestMatchCallback callback) { 1776 mExecutor = executor; 1777 mCallback = callback; 1778 } 1779 1780 @Override onUserSelectionCallbackRegistration( INetworkRequestUserSelectionCallback userSelectionCallback)1781 public void onUserSelectionCallbackRegistration( 1782 INetworkRequestUserSelectionCallback userSelectionCallback) { 1783 if (mVerboseLoggingEnabled) { 1784 Log.v(TAG, "NetworkRequestMatchCallbackProxy: " 1785 + "onUserSelectionCallbackRegistration callback: " + userSelectionCallback); 1786 } 1787 Binder.clearCallingIdentity(); 1788 mExecutor.execute(() -> { 1789 mCallback.onUserSelectionCallbackRegistration( 1790 new NetworkRequestUserSelectionCallbackProxy(userSelectionCallback)); 1791 }); 1792 } 1793 1794 @Override onAbort()1795 public void onAbort() { 1796 if (mVerboseLoggingEnabled) { 1797 Log.v(TAG, "NetworkRequestMatchCallbackProxy: onAbort"); 1798 } 1799 Binder.clearCallingIdentity(); 1800 mExecutor.execute(() -> { 1801 mCallback.onAbort(); 1802 }); 1803 } 1804 1805 @Override onMatch(List<ScanResult> scanResults)1806 public void onMatch(List<ScanResult> scanResults) { 1807 if (mVerboseLoggingEnabled) { 1808 Log.v(TAG, "NetworkRequestMatchCallbackProxy: onMatch scanResults: " 1809 + scanResults); 1810 } 1811 Binder.clearCallingIdentity(); 1812 mExecutor.execute(() -> { 1813 mCallback.onMatch(scanResults); 1814 }); 1815 } 1816 1817 @Override onUserSelectionConnectSuccess(WifiConfiguration wifiConfiguration)1818 public void onUserSelectionConnectSuccess(WifiConfiguration wifiConfiguration) { 1819 if (mVerboseLoggingEnabled) { 1820 Log.v(TAG, "NetworkRequestMatchCallbackProxy: onUserSelectionConnectSuccess " 1821 + " wificonfiguration: " + wifiConfiguration); 1822 } 1823 Binder.clearCallingIdentity(); 1824 mExecutor.execute(() -> { 1825 mCallback.onUserSelectionConnectSuccess(wifiConfiguration); 1826 }); 1827 } 1828 1829 @Override onUserSelectionConnectFailure(WifiConfiguration wifiConfiguration)1830 public void onUserSelectionConnectFailure(WifiConfiguration wifiConfiguration) { 1831 if (mVerboseLoggingEnabled) { 1832 Log.v(TAG, "NetworkRequestMatchCallbackProxy: onUserSelectionConnectFailure" 1833 + " wificonfiguration: " + wifiConfiguration); 1834 } 1835 Binder.clearCallingIdentity(); 1836 mExecutor.execute(() -> { 1837 mCallback.onUserSelectionConnectFailure(wifiConfiguration); 1838 }); 1839 } 1840 } 1841 1842 /** 1843 * Registers a callback for NetworkRequest matches. See {@link NetworkRequestMatchCallback}. 1844 * Caller can unregister a previously registered callback using 1845 * {@link #unregisterNetworkRequestMatchCallback(NetworkRequestMatchCallback)} 1846 * <p> 1847 * Applications should have the 1848 * {@link android.Manifest.permission#NETWORK_SETTINGS} permission. Callers 1849 * without the permission will trigger a {@link java.lang.SecurityException}. 1850 * <p> 1851 * 1852 * @param executor The Executor on whose thread to execute the callbacks of the {@code callback} 1853 * object. 1854 * @param callback Callback for network match events to register. 1855 * @hide 1856 */ 1857 @SystemApi 1858 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) registerNetworkRequestMatchCallback(@onNull @allbackExecutor Executor executor, @NonNull NetworkRequestMatchCallback callback)1859 public void registerNetworkRequestMatchCallback(@NonNull @CallbackExecutor Executor executor, 1860 @NonNull NetworkRequestMatchCallback callback) { 1861 if (executor == null) throw new IllegalArgumentException("executor cannot be null"); 1862 if (callback == null) throw new IllegalArgumentException("callback cannot be null"); 1863 Log.v(TAG, "registerNetworkRequestMatchCallback: callback=" + callback 1864 + ", executor=" + executor); 1865 1866 Binder binder = new Binder(); 1867 try { 1868 mService.registerNetworkRequestMatchCallback( 1869 binder, new NetworkRequestMatchCallbackProxy(executor, callback), 1870 callback.hashCode()); 1871 } catch (RemoteException e) { 1872 throw e.rethrowFromSystemServer(); 1873 } 1874 } 1875 1876 /** 1877 * Unregisters a callback for NetworkRequest matches. See {@link NetworkRequestMatchCallback}. 1878 * <p> 1879 * Applications should have the 1880 * {@link android.Manifest.permission#NETWORK_SETTINGS} permission. Callers 1881 * without the permission will trigger a {@link java.lang.SecurityException}. 1882 * <p> 1883 * 1884 * @param callback Callback for network match events to unregister. 1885 * @hide 1886 */ 1887 @SystemApi 1888 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) unregisterNetworkRequestMatchCallback( @onNull NetworkRequestMatchCallback callback)1889 public void unregisterNetworkRequestMatchCallback( 1890 @NonNull NetworkRequestMatchCallback callback) { 1891 if (callback == null) throw new IllegalArgumentException("callback cannot be null"); 1892 Log.v(TAG, "unregisterNetworkRequestMatchCallback: callback=" + callback); 1893 1894 try { 1895 mService.unregisterNetworkRequestMatchCallback(callback.hashCode()); 1896 } catch (RemoteException e) { 1897 throw e.rethrowFromSystemServer(); 1898 } 1899 } 1900 1901 /** 1902 * Provide a list of network suggestions to the device. See {@link WifiNetworkSuggestion} 1903 * for a detailed explanation of the parameters. 1904 * When the device decides to connect to one of the provided network suggestions, platform sends 1905 * a directed broadcast {@link #ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION} to the app if 1906 * the network was created with 1907 * {@link WifiNetworkSuggestion.Builder#setIsAppInteractionRequired(boolean)} flag set and the 1908 * app holds {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} 1909 * permission. 1910 *<p> 1911 * NOTE: 1912 * <li> These networks are just a suggestion to the platform. The platform will ultimately 1913 * decide on which network the device connects to. </li> 1914 * <li> When an app is uninstalled or disabled, all its suggested networks are discarded. 1915 * If the device is currently connected to a suggested network which is being removed then the 1916 * device will disconnect from that network.</li> 1917 * <li> If user reset network settings, all added suggestions will be discarded. Apps can use 1918 * {@link #getNetworkSuggestions()} to check if their suggestions are in the device.</li> 1919 * <li> In-place modification of existing suggestions are allowed. 1920 * <li> If the provided suggestions include any previously provided suggestions by the app, 1921 * previous suggestions will be updated.</li> 1922 * <li>If one of the provided suggestions marks a previously unmetered suggestion as metered and 1923 * the device is currently connected to that suggested network, then the device will disconnect 1924 * from that network. The system will immediately re-evaluate all the network candidates 1925 * and possibly reconnect back to the same suggestion. This disconnect is to make sure that any 1926 * traffic flowing over unmetered networks isn't accidentally continued over a metered network. 1927 * </li> 1928 * </li> 1929 * 1930 * @param networkSuggestions List of network suggestions provided by the app. 1931 * @return Status code for the operation. One of the STATUS_NETWORK_SUGGESTIONS_ values. 1932 * @throws {@link SecurityException} if the caller is missing required permissions. 1933 * @see WifiNetworkSuggestion#equals(Object) 1934 */ 1935 @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) addNetworkSuggestions( @onNull List<WifiNetworkSuggestion> networkSuggestions)1936 public @NetworkSuggestionsStatusCode int addNetworkSuggestions( 1937 @NonNull List<WifiNetworkSuggestion> networkSuggestions) { 1938 try { 1939 return mService.addNetworkSuggestions( 1940 networkSuggestions, mContext.getOpPackageName(), mContext.getAttributionTag()); 1941 } catch (RemoteException e) { 1942 throw e.rethrowFromSystemServer(); 1943 } 1944 } 1945 1946 /** 1947 * Remove some or all of the network suggestions that were previously provided by the app. 1948 * If one of the suggestions being removed was used to establish connection to the current 1949 * network, then the device will immediately disconnect from that network. 1950 * 1951 * See {@link WifiNetworkSuggestion} for a detailed explanation of the parameters. 1952 * See {@link WifiNetworkSuggestion#equals(Object)} for the equivalence evaluation used. 1953 * 1954 * @param networkSuggestions List of network suggestions to be removed. Pass an empty list 1955 * to remove all the previous suggestions provided by the app. 1956 * @return Status code for the operation. One of the STATUS_NETWORK_SUGGESTIONS_ values. 1957 * Any matching suggestions are removed from the device and will not be considered for any 1958 * further connection attempts. 1959 */ 1960 @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) removeNetworkSuggestions( @onNull List<WifiNetworkSuggestion> networkSuggestions)1961 public @NetworkSuggestionsStatusCode int removeNetworkSuggestions( 1962 @NonNull List<WifiNetworkSuggestion> networkSuggestions) { 1963 try { 1964 return mService.removeNetworkSuggestions( 1965 networkSuggestions, mContext.getOpPackageName()); 1966 } catch (RemoteException e) { 1967 throw e.rethrowFromSystemServer(); 1968 } 1969 } 1970 1971 /** 1972 * Get all network suggestions provided by the calling app. 1973 * See {@link #addNetworkSuggestions(List)} 1974 * See {@link #removeNetworkSuggestions(List)} 1975 * @return a list of {@link WifiNetworkSuggestion} 1976 */ 1977 @RequiresPermission(ACCESS_WIFI_STATE) getNetworkSuggestions()1978 public @NonNull List<WifiNetworkSuggestion> getNetworkSuggestions() { 1979 try { 1980 return mService.getNetworkSuggestions(mContext.getOpPackageName()); 1981 } catch (RemoteException e) { 1982 throw e.rethrowAsRuntimeException(); 1983 } 1984 } 1985 1986 /** 1987 * Returns the max number of network suggestions that are allowed per app on the device. 1988 * @see #addNetworkSuggestions(List) 1989 * @see #removeNetworkSuggestions(List) 1990 */ getMaxNumberOfNetworkSuggestionsPerApp()1991 public int getMaxNumberOfNetworkSuggestionsPerApp() { 1992 return getMaxNumberOfNetworkSuggestionsPerApp( 1993 mContext.getSystemService(ActivityManager.class).isLowRamDevice()); 1994 } 1995 1996 /** @hide */ getMaxNumberOfNetworkSuggestionsPerApp(boolean isLowRamDevice)1997 public static int getMaxNumberOfNetworkSuggestionsPerApp(boolean isLowRamDevice) { 1998 return isLowRamDevice 1999 ? NETWORK_SUGGESTIONS_MAX_PER_APP_LOW_RAM 2000 : NETWORK_SUGGESTIONS_MAX_PER_APP_HIGH_RAM; 2001 } 2002 2003 /** 2004 * Add or update a Passpoint configuration. The configuration provides a credential 2005 * for connecting to Passpoint networks that are operated by the Passpoint 2006 * service provider specified in the configuration. 2007 * 2008 * Each configuration is uniquely identified by a unique key which depends on the contents of 2009 * the configuration. This allows the caller to install multiple profiles with the same FQDN 2010 * (Fully qualified domain name). Therefore, in order to update an existing profile, it is 2011 * first required to remove it using {@link WifiManager#removePasspointConfiguration(String)}. 2012 * Otherwise, a new profile will be added with both configuration. 2013 * 2014 * @param config The Passpoint configuration to be added 2015 * @throws IllegalArgumentException if configuration is invalid or Passpoint is not enabled on 2016 * the device. 2017 * 2018 * Deprecated for general app usage - except DO/PO apps. 2019 * See {@link WifiNetworkSuggestion.Builder#setPasspointConfig(PasspointConfiguration)} to 2020 * create a passpoint suggestion. 2021 * See {@link #addNetworkSuggestions(List)}, {@link #removeNetworkSuggestions(List)} for new 2022 * API to add Wi-Fi networks for consideration when auto-connecting to wifi. 2023 * <b>Compatibility Note:</b> For applications targeting 2024 * {@link android.os.Build.VERSION_CODES#R} or above, this API will always fail and throw 2025 * {@link IllegalArgumentException}. 2026 * <p> 2027 * Deprecation Exemptions: 2028 * <ul> 2029 * <li>Device Owner (DO), Profile Owner (PO) and system apps. 2030 * </ul> 2031 */ addOrUpdatePasspointConfiguration(PasspointConfiguration config)2032 public void addOrUpdatePasspointConfiguration(PasspointConfiguration config) { 2033 try { 2034 if (!mService.addOrUpdatePasspointConfiguration(config, mContext.getOpPackageName())) { 2035 throw new IllegalArgumentException(); 2036 } 2037 } catch (RemoteException e) { 2038 throw e.rethrowFromSystemServer(); 2039 } 2040 } 2041 2042 /** 2043 * Remove the Passpoint configuration identified by its FQDN (Fully Qualified Domain Name) added 2044 * by the caller. 2045 * 2046 * @param fqdn The FQDN of the Passpoint configuration added by the caller to be removed 2047 * @throws IllegalArgumentException if no configuration is associated with the given FQDN or 2048 * Passpoint is not enabled on the device. 2049 * @deprecated This will be non-functional in a future release. 2050 */ 2051 @Deprecated 2052 @RequiresPermission(anyOf = { 2053 android.Manifest.permission.NETWORK_SETTINGS, 2054 android.Manifest.permission.NETWORK_CARRIER_PROVISIONING 2055 }) removePasspointConfiguration(String fqdn)2056 public void removePasspointConfiguration(String fqdn) { 2057 try { 2058 if (!mService.removePasspointConfiguration(fqdn, mContext.getOpPackageName())) { 2059 throw new IllegalArgumentException(); 2060 } 2061 } catch (RemoteException e) { 2062 throw e.rethrowFromSystemServer(); 2063 } 2064 } 2065 2066 /** 2067 * Return the list of installed Passpoint configurations added by the caller. 2068 * 2069 * An empty list will be returned when no configurations are installed. 2070 * 2071 * @return A list of {@link PasspointConfiguration} added by the caller 2072 * @deprecated This will be non-functional in a future release. 2073 */ 2074 @Deprecated 2075 @RequiresPermission(anyOf = { 2076 android.Manifest.permission.NETWORK_SETTINGS, 2077 android.Manifest.permission.NETWORK_SETUP_WIZARD 2078 }) getPasspointConfigurations()2079 public List<PasspointConfiguration> getPasspointConfigurations() { 2080 try { 2081 return mService.getPasspointConfigurations(mContext.getOpPackageName()); 2082 } catch (RemoteException e) { 2083 throw e.rethrowFromSystemServer(); 2084 } 2085 } 2086 2087 /** 2088 * Query for a Hotspot 2.0 release 2 OSU icon file. An {@link #ACTION_PASSPOINT_ICON} intent 2089 * will be broadcasted once the request is completed. The presence of the intent extra 2090 * {@link #EXTRA_ICON} will indicate the result of the request. 2091 * A missing intent extra {@link #EXTRA_ICON} will indicate a failure. 2092 * 2093 * @param bssid The BSSID of the AP 2094 * @param fileName Name of the icon file (remote file) to query from the AP 2095 * 2096 * @throws UnsupportedOperationException if Passpoint is not enabled on the device. 2097 * @hide 2098 */ queryPasspointIcon(long bssid, String fileName)2099 public void queryPasspointIcon(long bssid, String fileName) { 2100 try { 2101 mService.queryPasspointIcon(bssid, fileName); 2102 } catch (RemoteException e) { 2103 throw e.rethrowFromSystemServer(); 2104 } 2105 } 2106 2107 /** 2108 * Match the currently associated network against the SP matching the given FQDN 2109 * @param fqdn FQDN of the SP 2110 * @return ordinal [HomeProvider, RoamingProvider, Incomplete, None, Declined] 2111 * @hide 2112 */ matchProviderWithCurrentNetwork(String fqdn)2113 public int matchProviderWithCurrentNetwork(String fqdn) { 2114 try { 2115 return mService.matchProviderWithCurrentNetwork(fqdn); 2116 } catch (RemoteException e) { 2117 throw e.rethrowFromSystemServer(); 2118 } 2119 } 2120 2121 /** 2122 * Deauthenticate and set the re-authentication hold off time for the current network 2123 * @param holdoff hold off time in milliseconds 2124 * @param ess set if the hold off pertains to an ESS rather than a BSS 2125 * @hide 2126 * 2127 * TODO (140167680): This needs to be removed, the implementation is empty! 2128 */ deauthenticateNetwork(long holdoff, boolean ess)2129 public void deauthenticateNetwork(long holdoff, boolean ess) { 2130 try { 2131 mService.deauthenticateNetwork(holdoff, ess); 2132 } catch (RemoteException e) { 2133 throw e.rethrowFromSystemServer(); 2134 } 2135 } 2136 2137 /** 2138 * Remove the specified network from the list of configured networks. 2139 * This may result in the asynchronous delivery of state change 2140 * events. 2141 * 2142 * Applications are not allowed to remove networks created by other 2143 * applications. 2144 * 2145 * @param netId the ID of the network as returned by {@link #addNetwork} or {@link 2146 * #getConfiguredNetworks}. 2147 * @return {@code true} if the operation succeeded 2148 * 2149 * @deprecated 2150 * a) See {@link WifiNetworkSpecifier.Builder#build()} for new 2151 * mechanism to trigger connection to a Wi-Fi network. 2152 * b) See {@link #addNetworkSuggestions(List)}, 2153 * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration 2154 * when auto-connecting to wifi. 2155 * <b>Compatibility Note:</b> For applications targeting 2156 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return 2157 * {@code false}. 2158 * <p> 2159 * Deprecation Exemptions: 2160 * <ul> 2161 * <li>Device Owner (DO), Profile Owner (PO) and system apps. 2162 * </ul> 2163 */ 2164 @Deprecated removeNetwork(int netId)2165 public boolean removeNetwork(int netId) { 2166 try { 2167 return mService.removeNetwork(netId, mContext.getOpPackageName()); 2168 } catch (RemoteException e) { 2169 throw e.rethrowFromSystemServer(); 2170 } 2171 } 2172 2173 /** 2174 * Allow a previously configured network to be associated with. If 2175 * <code>attemptConnect</code> is true, an attempt to connect to the selected 2176 * network is initiated. This may result in the asynchronous delivery 2177 * of state change events. 2178 * <p> 2179 * <b>Note:</b> Network communication may not use Wi-Fi even if Wi-Fi is connected; 2180 * traffic may instead be sent through another network, such as cellular data, 2181 * Bluetooth tethering, or Ethernet. For example, traffic will never use a 2182 * Wi-Fi network that does not provide Internet access (e.g. a wireless 2183 * printer), if another network that does offer Internet access (e.g. 2184 * cellular data) is available. Applications that need to ensure that their 2185 * network traffic uses Wi-Fi should use APIs such as 2186 * {@link Network#bindSocket(java.net.Socket)}, 2187 * {@link Network#openConnection(java.net.URL)}, or 2188 * {@link ConnectivityManager#bindProcessToNetwork} to do so. 2189 * 2190 * Applications are not allowed to enable networks created by other 2191 * applications. 2192 * 2193 * @param netId the ID of the network as returned by {@link #addNetwork} or {@link 2194 * #getConfiguredNetworks}. 2195 * @param attemptConnect The way to select a particular network to connect to is specify 2196 * {@code true} for this parameter. 2197 * @return {@code true} if the operation succeeded 2198 * 2199 * @deprecated 2200 * a) See {@link WifiNetworkSpecifier.Builder#build()} for new 2201 * mechanism to trigger connection to a Wi-Fi network. 2202 * b) See {@link #addNetworkSuggestions(List)}, 2203 * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration 2204 * when auto-connecting to wifi. 2205 * <b>Compatibility Note:</b> For applications targeting 2206 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return 2207 * {@code false}. 2208 * Deprecation Exemptions: 2209 * <ul> 2210 * <li>Device Owner (DO), Profile Owner (PO) and system apps. 2211 * </ul> 2212 */ 2213 @Deprecated enableNetwork(int netId, boolean attemptConnect)2214 public boolean enableNetwork(int netId, boolean attemptConnect) { 2215 try { 2216 return mService.enableNetwork(netId, attemptConnect, mContext.getOpPackageName()); 2217 } catch (RemoteException e) { 2218 throw e.rethrowFromSystemServer(); 2219 } 2220 } 2221 2222 /** 2223 * Disable a configured network. The specified network will not be 2224 * a candidate for associating. This may result in the asynchronous 2225 * delivery of state change events. 2226 * 2227 * Applications are not allowed to disable networks created by other 2228 * applications. 2229 * 2230 * @param netId the ID of the network as returned by {@link #addNetwork} or {@link 2231 * #getConfiguredNetworks}. 2232 * @return {@code true} if the operation succeeded 2233 * 2234 * @deprecated 2235 * a) See {@link WifiNetworkSpecifier.Builder#build()} for new 2236 * mechanism to trigger connection to a Wi-Fi network. 2237 * b) See {@link #addNetworkSuggestions(List)}, 2238 * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration 2239 * when auto-connecting to wifi. 2240 * <b>Compatibility Note:</b> For applications targeting 2241 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return 2242 * {@code false}. 2243 * <p> 2244 * Deprecation Exemptions: 2245 * <ul> 2246 * <li>Device Owner (DO), Profile Owner (PO) and system apps. 2247 * </ul> 2248 */ 2249 @Deprecated disableNetwork(int netId)2250 public boolean disableNetwork(int netId) { 2251 try { 2252 return mService.disableNetwork(netId, mContext.getOpPackageName()); 2253 } catch (RemoteException e) { 2254 throw e.rethrowFromSystemServer(); 2255 } 2256 } 2257 2258 /** 2259 * Disassociate from the currently active access point. This may result 2260 * in the asynchronous delivery of state change events. 2261 * @return {@code true} if the operation succeeded 2262 * 2263 * @deprecated 2264 * a) See {@link WifiNetworkSpecifier.Builder#build()} for new 2265 * mechanism to trigger connection to a Wi-Fi network. 2266 * b) See {@link #addNetworkSuggestions(List)}, 2267 * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration 2268 * when auto-connecting to wifi. 2269 * <b>Compatibility Note:</b> For applications targeting 2270 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return 2271 * {@code false}. 2272 * <p> 2273 * Deprecation Exemptions: 2274 * <ul> 2275 * <li>Device Owner (DO), Profile Owner (PO) and system apps. 2276 * </ul> 2277 */ 2278 @Deprecated disconnect()2279 public boolean disconnect() { 2280 try { 2281 return mService.disconnect(mContext.getOpPackageName()); 2282 } catch (RemoteException e) { 2283 throw e.rethrowFromSystemServer(); 2284 } 2285 } 2286 2287 /** 2288 * Reconnect to the currently active access point, if we are currently 2289 * disconnected. This may result in the asynchronous delivery of state 2290 * change events. 2291 * @return {@code true} if the operation succeeded 2292 * 2293 * @deprecated 2294 * a) See {@link WifiNetworkSpecifier.Builder#build()} for new 2295 * mechanism to trigger connection to a Wi-Fi network. 2296 * b) See {@link #addNetworkSuggestions(List)}, 2297 * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration 2298 * when auto-connecting to wifi. 2299 * <b>Compatibility Note:</b> For applications targeting 2300 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return 2301 * {@code false}. 2302 * <p> 2303 * Deprecation Exemptions: 2304 * <ul> 2305 * <li>Device Owner (DO), Profile Owner (PO) and system apps. 2306 * </ul> 2307 */ 2308 @Deprecated reconnect()2309 public boolean reconnect() { 2310 try { 2311 return mService.reconnect(mContext.getOpPackageName()); 2312 } catch (RemoteException e) { 2313 throw e.rethrowFromSystemServer(); 2314 } 2315 } 2316 2317 /** 2318 * Reconnect to the currently active access point, even if we are already 2319 * connected. This may result in the asynchronous delivery of state 2320 * change events. 2321 * @return {@code true} if the operation succeeded 2322 * 2323 * @deprecated 2324 * a) See {@link WifiNetworkSpecifier.Builder#build()} for new 2325 * mechanism to trigger connection to a Wi-Fi network. 2326 * b) See {@link #addNetworkSuggestions(List)}, 2327 * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration 2328 * when auto-connecting to wifi. 2329 * <b>Compatibility Note:</b> For applications targeting 2330 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false. 2331 */ 2332 @Deprecated reassociate()2333 public boolean reassociate() { 2334 try { 2335 return mService.reassociate(mContext.getOpPackageName()); 2336 } catch (RemoteException e) { 2337 throw e.rethrowFromSystemServer(); 2338 } 2339 } 2340 2341 /** 2342 * Check that the supplicant daemon is responding to requests. 2343 * @return {@code true} if we were able to communicate with the supplicant and 2344 * it returned the expected response to the PING message. 2345 * @deprecated Will return the output of {@link #isWifiEnabled()} instead. 2346 */ 2347 @Deprecated pingSupplicant()2348 public boolean pingSupplicant() { 2349 return isWifiEnabled(); 2350 } 2351 2352 /** @hide */ 2353 public static final long WIFI_FEATURE_INFRA = 0x0001L; // Basic infrastructure mode 2354 /** @hide */ 2355 public static final long WIFI_FEATURE_PASSPOINT = 0x0004L; // Support for GAS/ANQP 2356 /** @hide */ 2357 public static final long WIFI_FEATURE_P2P = 0x0008L; // Wifi-Direct 2358 /** @hide */ 2359 public static final long WIFI_FEATURE_MOBILE_HOTSPOT = 0x0010L; // Soft AP 2360 /** @hide */ 2361 public static final long WIFI_FEATURE_SCANNER = 0x0020L; // WifiScanner APIs 2362 /** @hide */ 2363 public static final long WIFI_FEATURE_AWARE = 0x0040L; // Wi-Fi AWare networking 2364 /** @hide */ 2365 public static final long WIFI_FEATURE_D2D_RTT = 0x0080L; // Device-to-device RTT 2366 /** @hide */ 2367 public static final long WIFI_FEATURE_D2AP_RTT = 0x0100L; // Device-to-AP RTT 2368 /** @hide */ 2369 public static final long WIFI_FEATURE_BATCH_SCAN = 0x0200L; // Batched Scan (deprecated) 2370 /** @hide */ 2371 public static final long WIFI_FEATURE_PNO = 0x0400L; // Preferred network offload 2372 /** @hide */ 2373 public static final long WIFI_FEATURE_ADDITIONAL_STA = 0x0800L; // Support for two STAs 2374 /** @hide */ 2375 public static final long WIFI_FEATURE_TDLS = 0x1000L; // Tunnel directed link setup 2376 /** @hide */ 2377 public static final long WIFI_FEATURE_TDLS_OFFCHANNEL = 0x2000L; // TDLS off channel 2378 /** @hide */ 2379 public static final long WIFI_FEATURE_EPR = 0x4000L; // Enhanced power reporting 2380 /** @hide */ 2381 public static final long WIFI_FEATURE_AP_STA = 0x8000L; // AP STA Concurrency 2382 /** @hide */ 2383 public static final long WIFI_FEATURE_LINK_LAYER_STATS = 0x10000L; // Link layer stats 2384 /** @hide */ 2385 public static final long WIFI_FEATURE_LOGGER = 0x20000L; // WiFi Logger 2386 /** @hide */ 2387 public static final long WIFI_FEATURE_HAL_EPNO = 0x40000L; // Enhanced PNO 2388 /** @hide */ 2389 public static final long WIFI_FEATURE_RSSI_MONITOR = 0x80000L; // RSSI Monitor 2390 /** @hide */ 2391 public static final long WIFI_FEATURE_MKEEP_ALIVE = 0x100000L; // mkeep_alive 2392 /** @hide */ 2393 public static final long WIFI_FEATURE_CONFIG_NDO = 0x200000L; // ND offload 2394 /** @hide */ 2395 public static final long WIFI_FEATURE_TRANSMIT_POWER = 0x400000L; // Capture transmit power 2396 /** @hide */ 2397 public static final long WIFI_FEATURE_CONTROL_ROAMING = 0x800000L; // Control firmware roaming 2398 /** @hide */ 2399 public static final long WIFI_FEATURE_IE_WHITELIST = 0x1000000L; // Probe IE white listing 2400 /** @hide */ 2401 public static final long WIFI_FEATURE_SCAN_RAND = 0x2000000L; // Random MAC & Probe seq 2402 /** @hide */ 2403 public static final long WIFI_FEATURE_TX_POWER_LIMIT = 0x4000000L; // Set Tx power limit 2404 /** @hide */ 2405 public static final long WIFI_FEATURE_WPA3_SAE = 0x8000000L; // WPA3-Personal SAE 2406 /** @hide */ 2407 public static final long WIFI_FEATURE_WPA3_SUITE_B = 0x10000000L; // WPA3-Enterprise Suite-B 2408 /** @hide */ 2409 public static final long WIFI_FEATURE_OWE = 0x20000000L; // Enhanced Open 2410 /** @hide */ 2411 public static final long WIFI_FEATURE_LOW_LATENCY = 0x40000000L; // Low Latency modes 2412 /** @hide */ 2413 public static final long WIFI_FEATURE_DPP = 0x80000000L; // DPP (Easy-Connect) 2414 /** @hide */ 2415 public static final long WIFI_FEATURE_P2P_RAND_MAC = 0x100000000L; // Random P2P MAC 2416 /** @hide */ 2417 public static final long WIFI_FEATURE_CONNECTED_RAND_MAC = 0x200000000L; // Random STA MAC 2418 /** @hide */ 2419 public static final long WIFI_FEATURE_AP_RAND_MAC = 0x400000000L; // Random AP MAC 2420 /** @hide */ 2421 public static final long WIFI_FEATURE_MBO = 0x800000000L; // MBO Support 2422 /** @hide */ 2423 public static final long WIFI_FEATURE_OCE = 0x1000000000L; // OCE Support 2424 /** @hide */ 2425 public static final long WIFI_FEATURE_WAPI = 0x2000000000L; // WAPI 2426 2427 /** @hide */ 2428 public static final long WIFI_FEATURE_FILS_SHA256 = 0x4000000000L; // FILS-SHA256 2429 2430 /** @hide */ 2431 public static final long WIFI_FEATURE_FILS_SHA384 = 0x8000000000L; // FILS-SHA384 2432 getSupportedFeatures()2433 private long getSupportedFeatures() { 2434 try { 2435 return mService.getSupportedFeatures(); 2436 } catch (RemoteException e) { 2437 throw e.rethrowFromSystemServer(); 2438 } 2439 } 2440 isFeatureSupported(long feature)2441 private boolean isFeatureSupported(long feature) { 2442 return (getSupportedFeatures() & feature) == feature; 2443 } 2444 2445 /** 2446 * @return true if this adapter supports Passpoint 2447 * @hide 2448 */ isPasspointSupported()2449 public boolean isPasspointSupported() { 2450 return isFeatureSupported(WIFI_FEATURE_PASSPOINT); 2451 } 2452 2453 /** 2454 * @return true if this adapter supports WifiP2pManager (Wi-Fi Direct) 2455 */ isP2pSupported()2456 public boolean isP2pSupported() { 2457 return isFeatureSupported(WIFI_FEATURE_P2P); 2458 } 2459 2460 /** 2461 * @return true if this adapter supports portable Wi-Fi hotspot 2462 * @hide 2463 */ 2464 @SystemApi isPortableHotspotSupported()2465 public boolean isPortableHotspotSupported() { 2466 return isFeatureSupported(WIFI_FEATURE_MOBILE_HOTSPOT); 2467 } 2468 2469 /** 2470 * @return true if this adapter supports WifiScanner APIs 2471 * @hide 2472 */ 2473 @SystemApi isWifiScannerSupported()2474 public boolean isWifiScannerSupported() { 2475 return isFeatureSupported(WIFI_FEATURE_SCANNER); 2476 } 2477 2478 /** 2479 * @return true if this adapter supports Neighbour Awareness Network APIs 2480 * @hide 2481 */ isWifiAwareSupported()2482 public boolean isWifiAwareSupported() { 2483 return isFeatureSupported(WIFI_FEATURE_AWARE); 2484 } 2485 2486 /** 2487 * Query whether the device supports Station (STA) + Access point (AP) concurrency or not. 2488 * 2489 * @return true if this device supports STA + AP concurrency, false otherwise. 2490 */ isStaApConcurrencySupported()2491 public boolean isStaApConcurrencySupported() { 2492 return isFeatureSupported(WIFI_FEATURE_AP_STA); 2493 } 2494 2495 /** 2496 * @deprecated Please use {@link android.content.pm.PackageManager#hasSystemFeature(String)} 2497 * with {@link android.content.pm.PackageManager#FEATURE_WIFI_RTT} and 2498 * {@link android.content.pm.PackageManager#FEATURE_WIFI_AWARE}. 2499 * 2500 * @return true if this adapter supports Device-to-device RTT 2501 * @hide 2502 */ 2503 @Deprecated 2504 @SystemApi isDeviceToDeviceRttSupported()2505 public boolean isDeviceToDeviceRttSupported() { 2506 return isFeatureSupported(WIFI_FEATURE_D2D_RTT); 2507 } 2508 2509 /** 2510 * @deprecated Please use {@link android.content.pm.PackageManager#hasSystemFeature(String)} 2511 * with {@link android.content.pm.PackageManager#FEATURE_WIFI_RTT}. 2512 * 2513 * @return true if this adapter supports Device-to-AP RTT 2514 */ 2515 @Deprecated isDeviceToApRttSupported()2516 public boolean isDeviceToApRttSupported() { 2517 return isFeatureSupported(WIFI_FEATURE_D2AP_RTT); 2518 } 2519 2520 /** 2521 * @return true if this adapter supports offloaded connectivity scan 2522 */ isPreferredNetworkOffloadSupported()2523 public boolean isPreferredNetworkOffloadSupported() { 2524 return isFeatureSupported(WIFI_FEATURE_PNO); 2525 } 2526 2527 /** 2528 * @return true if this adapter supports multiple simultaneous connections 2529 * @hide 2530 */ isAdditionalStaSupported()2531 public boolean isAdditionalStaSupported() { 2532 return isFeatureSupported(WIFI_FEATURE_ADDITIONAL_STA); 2533 } 2534 2535 /** 2536 * @return true if this adapter supports Tunnel Directed Link Setup 2537 */ isTdlsSupported()2538 public boolean isTdlsSupported() { 2539 return isFeatureSupported(WIFI_FEATURE_TDLS); 2540 } 2541 2542 /** 2543 * @return true if this adapter supports Off Channel Tunnel Directed Link Setup 2544 * @hide 2545 */ isOffChannelTdlsSupported()2546 public boolean isOffChannelTdlsSupported() { 2547 return isFeatureSupported(WIFI_FEATURE_TDLS_OFFCHANNEL); 2548 } 2549 2550 /** 2551 * @return true if this adapter supports advanced power/performance counters 2552 */ isEnhancedPowerReportingSupported()2553 public boolean isEnhancedPowerReportingSupported() { 2554 return isFeatureSupported(WIFI_FEATURE_LINK_LAYER_STATS); 2555 } 2556 2557 /** 2558 * @return true if this device supports connected MAC randomization. 2559 * @hide 2560 */ 2561 @SystemApi isConnectedMacRandomizationSupported()2562 public boolean isConnectedMacRandomizationSupported() { 2563 return isFeatureSupported(WIFI_FEATURE_CONNECTED_RAND_MAC); 2564 } 2565 2566 /** 2567 * @return true if this device supports connected MAC randomization. 2568 * @hide 2569 */ 2570 @SystemApi isApMacRandomizationSupported()2571 public boolean isApMacRandomizationSupported() { 2572 return isFeatureSupported(WIFI_FEATURE_AP_RAND_MAC); 2573 } 2574 2575 /** 2576 * Check if the chipset supports 5GHz band. 2577 * @return {@code true} if supported, {@code false} otherwise. 2578 */ is5GHzBandSupported()2579 public boolean is5GHzBandSupported() { 2580 try { 2581 return mService.is5GHzBandSupported(); 2582 } catch (RemoteException e) { 2583 throw e.rethrowFromSystemServer(); 2584 } 2585 } 2586 2587 /** 2588 * Check if the chipset supports 6GHz band. 2589 * @return {@code true} if supported, {@code false} otherwise. 2590 */ is6GHzBandSupported()2591 public boolean is6GHzBandSupported() { 2592 try { 2593 return mService.is6GHzBandSupported(); 2594 } catch (RemoteException e) { 2595 throw e.rethrowFromSystemServer(); 2596 } 2597 } 2598 2599 /** 2600 * Check if the chipset supports a certain Wi-Fi standard. 2601 * @param standard the IEEE 802.11 standard to check on. 2602 * valid values from {@link ScanResult}'s {@code WIFI_STANDARD_} 2603 * @return {@code true} if supported, {@code false} otherwise. 2604 */ isWifiStandardSupported(@ifiAnnotations.WifiStandard int standard)2605 public boolean isWifiStandardSupported(@WifiAnnotations.WifiStandard int standard) { 2606 try { 2607 return mService.isWifiStandardSupported(standard); 2608 } catch (RemoteException e) { 2609 throw e.rethrowFromSystemServer(); 2610 } 2611 } 2612 2613 /** 2614 * Interface for Wi-Fi activity energy info listener. Should be implemented by applications and 2615 * set when calling {@link WifiManager#getWifiActivityEnergyInfoAsync}. 2616 * 2617 * @hide 2618 */ 2619 @SystemApi 2620 public interface OnWifiActivityEnergyInfoListener { 2621 /** 2622 * Called when Wi-Fi activity energy info is available. 2623 * Note: this listener is triggered at most once for each call to 2624 * {@link #getWifiActivityEnergyInfoAsync}. 2625 * 2626 * @param info the latest {@link WifiActivityEnergyInfo}, or null if unavailable. 2627 */ onWifiActivityEnergyInfo(@ullable WifiActivityEnergyInfo info)2628 void onWifiActivityEnergyInfo(@Nullable WifiActivityEnergyInfo info); 2629 } 2630 2631 private static class OnWifiActivityEnergyInfoProxy 2632 extends IOnWifiActivityEnergyInfoListener.Stub { 2633 private final Object mLock = new Object(); 2634 @Nullable @GuardedBy("mLock") private Executor mExecutor; 2635 @Nullable @GuardedBy("mLock") private OnWifiActivityEnergyInfoListener mListener; 2636 OnWifiActivityEnergyInfoProxy(Executor executor, OnWifiActivityEnergyInfoListener listener)2637 OnWifiActivityEnergyInfoProxy(Executor executor, 2638 OnWifiActivityEnergyInfoListener listener) { 2639 mExecutor = executor; 2640 mListener = listener; 2641 } 2642 2643 @Override onWifiActivityEnergyInfo(WifiActivityEnergyInfo info)2644 public void onWifiActivityEnergyInfo(WifiActivityEnergyInfo info) { 2645 Executor executor; 2646 OnWifiActivityEnergyInfoListener listener; 2647 synchronized (mLock) { 2648 if (mExecutor == null || mListener == null) { 2649 return; 2650 } 2651 executor = mExecutor; 2652 listener = mListener; 2653 // null out to allow garbage collection, prevent triggering listener more than once 2654 mExecutor = null; 2655 mListener = null; 2656 } 2657 Binder.clearCallingIdentity(); 2658 executor.execute(() -> listener.onWifiActivityEnergyInfo(info)); 2659 } 2660 } 2661 2662 /** 2663 * Request to get the current {@link WifiActivityEnergyInfo} asynchronously. 2664 * Note: This method will return null if {@link #isEnhancedPowerReportingSupported()} returns 2665 * false. 2666 * 2667 * @param executor the executor that the listener will be invoked on 2668 * @param listener the listener that will receive the {@link WifiActivityEnergyInfo} object 2669 * when it becomes available. The listener will be triggered at most once for 2670 * each call to this method. 2671 * 2672 * @hide 2673 */ 2674 @SystemApi 2675 @RequiresPermission(ACCESS_WIFI_STATE) getWifiActivityEnergyInfoAsync( @onNull @allbackExecutor Executor executor, @NonNull OnWifiActivityEnergyInfoListener listener)2676 public void getWifiActivityEnergyInfoAsync( 2677 @NonNull @CallbackExecutor Executor executor, 2678 @NonNull OnWifiActivityEnergyInfoListener listener) { 2679 Objects.requireNonNull(executor, "executor cannot be null"); 2680 Objects.requireNonNull(listener, "listener cannot be null"); 2681 try { 2682 mService.getWifiActivityEnergyInfoAsync( 2683 new OnWifiActivityEnergyInfoProxy(executor, listener)); 2684 } catch (RemoteException e) { 2685 throw e.rethrowFromSystemServer(); 2686 } 2687 } 2688 2689 /** 2690 * Request a scan for access points. Returns immediately. The availability 2691 * of the results is made known later by means of an asynchronous event sent 2692 * on completion of the scan. 2693 * <p> 2694 * To initiate a Wi-Fi scan, declare the 2695 * {@link android.Manifest.permission#CHANGE_WIFI_STATE} 2696 * permission in the manifest, and perform these steps: 2697 * </p> 2698 * <ol style="1"> 2699 * <li>Invoke the following method: 2700 * {@code ((WifiManager) getSystemService(WIFI_SERVICE)).startScan()}</li> 2701 * <li> 2702 * Register a BroadcastReceiver to listen to 2703 * {@code SCAN_RESULTS_AVAILABLE_ACTION}.</li> 2704 * <li>When a broadcast is received, call: 2705 * {@code ((WifiManager) getSystemService(WIFI_SERVICE)).getScanResults()}</li> 2706 * </ol> 2707 * @return {@code true} if the operation succeeded, i.e., the scan was initiated. 2708 * @deprecated The ability for apps to trigger scan requests will be removed in a future 2709 * release. 2710 */ 2711 @Deprecated startScan()2712 public boolean startScan() { 2713 return startScan(null); 2714 } 2715 2716 /** @hide */ 2717 @SystemApi 2718 @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) startScan(WorkSource workSource)2719 public boolean startScan(WorkSource workSource) { 2720 try { 2721 String packageName = mContext.getOpPackageName(); 2722 String attributionTag = mContext.getAttributionTag(); 2723 return mService.startScan(packageName, attributionTag); 2724 } catch (RemoteException e) { 2725 throw e.rethrowFromSystemServer(); 2726 } 2727 } 2728 2729 /** 2730 * WPS has been deprecated from Client mode operation. 2731 * 2732 * @return null 2733 * @hide 2734 * @deprecated This API is deprecated 2735 */ getCurrentNetworkWpsNfcConfigurationToken()2736 public String getCurrentNetworkWpsNfcConfigurationToken() { 2737 return null; 2738 } 2739 2740 /** 2741 * Return dynamic information about the current Wi-Fi connection, if any is active. 2742 * <p> 2743 * In the connected state, access to the SSID and BSSID requires 2744 * the same permissions as {@link #getScanResults}. If such access is not allowed, 2745 * {@link WifiInfo#getSSID} will return {@link #UNKNOWN_SSID} and 2746 * {@link WifiInfo#getBSSID} will return {@code "02:00:00:00:00:00"}. 2747 * {@link WifiInfo#getPasspointFqdn()} will return null. 2748 * {@link WifiInfo#getPasspointProviderFriendlyName()} will return null. 2749 * 2750 * @return the Wi-Fi information, contained in {@link WifiInfo}. 2751 */ getConnectionInfo()2752 public WifiInfo getConnectionInfo() { 2753 try { 2754 return mService.getConnectionInfo(mContext.getOpPackageName(), 2755 mContext.getAttributionTag()); 2756 } catch (RemoteException e) { 2757 throw e.rethrowFromSystemServer(); 2758 } 2759 } 2760 2761 /** 2762 * Return the results of the latest access point scan. 2763 * @return the list of access points found in the most recent scan. An app must hold 2764 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission 2765 * in order to get valid results. 2766 */ getScanResults()2767 public List<ScanResult> getScanResults() { 2768 try { 2769 return mService.getScanResults(mContext.getOpPackageName(), 2770 mContext.getAttributionTag()); 2771 } catch (RemoteException e) { 2772 throw e.rethrowFromSystemServer(); 2773 } 2774 } 2775 2776 /** 2777 * Get the filtered ScanResults which match the network configurations specified by the 2778 * {@code networkSuggestionsToMatch}. Suggestions which use {@link WifiConfiguration} use 2779 * SSID and the security type to match. Suggestions which use {@link PasspointConfigration} 2780 * use the matching rules of Hotspot 2.0. 2781 * @param networkSuggestionsToMatch The list of {@link WifiNetworkSuggestion} to match against. 2782 * These may or may not be suggestions which are installed on the device. 2783 * @param scanResults The scan results to be filtered. Optional - if not provided(empty list), 2784 * the Wi-Fi service will use the most recent scan results which the system has. 2785 * @return The map of {@link WifiNetworkSuggestion} to the list of {@link ScanResult} 2786 * corresponding to networks which match them. 2787 * @hide 2788 */ 2789 @SystemApi 2790 @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE}) 2791 @NonNull getMatchingScanResults( @onNull List<WifiNetworkSuggestion> networkSuggestionsToMatch, @Nullable List<ScanResult> scanResults)2792 public Map<WifiNetworkSuggestion, List<ScanResult>> getMatchingScanResults( 2793 @NonNull List<WifiNetworkSuggestion> networkSuggestionsToMatch, 2794 @Nullable List<ScanResult> scanResults) { 2795 if (networkSuggestionsToMatch == null) { 2796 throw new IllegalArgumentException("networkSuggestions must not be null."); 2797 } 2798 try { 2799 return mService.getMatchingScanResults( 2800 networkSuggestionsToMatch, scanResults, 2801 mContext.getOpPackageName(), mContext.getAttributionTag()); 2802 } catch (RemoteException e) { 2803 throw e.rethrowFromSystemServer(); 2804 } 2805 } 2806 2807 /** 2808 * Set if scanning is always available. 2809 * 2810 * If set to {@code true}, apps can issue {@link #startScan} and fetch scan results 2811 * even when Wi-Fi is turned off. 2812 * 2813 * @param isAvailable true to enable, false to disable. 2814 * @hide 2815 * @see #isScanAlwaysAvailable() 2816 */ 2817 @SystemApi 2818 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) setScanAlwaysAvailable(boolean isAvailable)2819 public void setScanAlwaysAvailable(boolean isAvailable) { 2820 try { 2821 mService.setScanAlwaysAvailable(isAvailable); 2822 } catch (RemoteException e) { 2823 throw e.rethrowFromSystemServer(); 2824 } 2825 } 2826 2827 /** 2828 * Check if scanning is always available. 2829 * 2830 * If this return {@code true}, apps can issue {@link #startScan} and fetch scan results 2831 * even when Wi-Fi is turned off. 2832 * 2833 * To change this setting, see {@link #ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE}. 2834 * @deprecated The ability for apps to trigger scan requests will be removed in a future 2835 * release. 2836 */ 2837 @Deprecated isScanAlwaysAvailable()2838 public boolean isScanAlwaysAvailable() { 2839 try { 2840 return mService.isScanAlwaysAvailable(); 2841 } catch (RemoteException e) { 2842 throw e.rethrowFromSystemServer(); 2843 } 2844 } 2845 2846 /** 2847 * Tell the device to persist the current list of configured networks. 2848 * <p> 2849 * Note: It is possible for this method to change the network IDs of 2850 * existing networks. You should assume the network IDs can be different 2851 * after calling this method. 2852 * 2853 * @return {@code false}. 2854 * @deprecated There is no need to call this method - 2855 * {@link #addNetwork(WifiConfiguration)}, {@link #updateNetwork(WifiConfiguration)} 2856 * and {@link #removeNetwork(int)} already persist the configurations automatically. 2857 */ 2858 @Deprecated saveConfiguration()2859 public boolean saveConfiguration() { 2860 return false; 2861 } 2862 2863 /** 2864 * Get the country code. 2865 * @return the country code in ISO 3166 alpha-2 (2-letter) uppercase format, or null if 2866 * there is no country code configured. 2867 * @hide 2868 */ 2869 @Nullable 2870 @SystemApi 2871 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) getCountryCode()2872 public String getCountryCode() { 2873 try { 2874 return mService.getCountryCode(); 2875 } catch (RemoteException e) { 2876 throw e.rethrowFromSystemServer(); 2877 } 2878 } 2879 2880 /** 2881 * Return the DHCP-assigned addresses from the last successful DHCP request, 2882 * if any. 2883 * @return the DHCP information 2884 */ getDhcpInfo()2885 public DhcpInfo getDhcpInfo() { 2886 try { 2887 return mService.getDhcpInfo(); 2888 } catch (RemoteException e) { 2889 throw e.rethrowFromSystemServer(); 2890 } 2891 } 2892 2893 /** 2894 * Enable or disable Wi-Fi. 2895 * <p> 2896 * Applications must have the {@link android.Manifest.permission#CHANGE_WIFI_STATE} 2897 * permission to toggle wifi. 2898 * 2899 * @param enabled {@code true} to enable, {@code false} to disable. 2900 * @return {@code false} if the request cannot be satisfied; {@code true} indicates that wifi is 2901 * either already in the requested state, or in progress toward the requested state. 2902 * @throws {@link java.lang.SecurityException} if the caller is missing required permissions. 2903 * 2904 * @deprecated Starting with Build.VERSION_CODES#Q, applications are not allowed to 2905 * enable/disable Wi-Fi. 2906 * <b>Compatibility Note:</b> For applications targeting 2907 * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always fail and return 2908 * {@code false}. If apps are targeting an older SDK ({@link android.os.Build.VERSION_CODES#P} 2909 * or below), they can continue to use this API. 2910 * <p> 2911 * Deprecation Exemptions: 2912 * <ul> 2913 * <li>Device Owner (DO), Profile Owner (PO) and system apps. 2914 * </ul> 2915 */ 2916 @Deprecated setWifiEnabled(boolean enabled)2917 public boolean setWifiEnabled(boolean enabled) { 2918 try { 2919 return mService.setWifiEnabled(mContext.getOpPackageName(), enabled); 2920 } catch (RemoteException e) { 2921 throw e.rethrowFromSystemServer(); 2922 } 2923 } 2924 2925 /** 2926 * Gets the Wi-Fi enabled state. 2927 * @return One of {@link #WIFI_STATE_DISABLED}, 2928 * {@link #WIFI_STATE_DISABLING}, {@link #WIFI_STATE_ENABLED}, 2929 * {@link #WIFI_STATE_ENABLING}, {@link #WIFI_STATE_UNKNOWN} 2930 * @see #isWifiEnabled() 2931 */ getWifiState()2932 public int getWifiState() { 2933 try { 2934 return mService.getWifiEnabledState(); 2935 } catch (RemoteException e) { 2936 throw e.rethrowFromSystemServer(); 2937 } 2938 } 2939 2940 /** 2941 * Return whether Wi-Fi is enabled or disabled. 2942 * @return {@code true} if Wi-Fi is enabled 2943 * @see #getWifiState() 2944 */ isWifiEnabled()2945 public boolean isWifiEnabled() { 2946 return getWifiState() == WIFI_STATE_ENABLED; 2947 } 2948 2949 /** 2950 * Calculates the level of the signal. This should be used any time a signal 2951 * is being shown. 2952 * 2953 * @param rssi The power of the signal measured in RSSI. 2954 * @param numLevels The number of levels to consider in the calculated level. 2955 * @return A level of the signal, given in the range of 0 to numLevels-1 (both inclusive). 2956 * @deprecated Callers should use {@link #calculateSignalLevel(int)} instead to get the 2957 * signal level using the system default RSSI thresholds, or otherwise compute the RSSI level 2958 * themselves using their own formula. 2959 */ 2960 @Deprecated calculateSignalLevel(int rssi, int numLevels)2961 public static int calculateSignalLevel(int rssi, int numLevels) { 2962 if (rssi <= MIN_RSSI) { 2963 return 0; 2964 } else if (rssi >= MAX_RSSI) { 2965 return numLevels - 1; 2966 } else { 2967 float inputRange = (MAX_RSSI - MIN_RSSI); 2968 float outputRange = (numLevels - 1); 2969 return (int)((float)(rssi - MIN_RSSI) * outputRange / inputRange); 2970 } 2971 } 2972 2973 /** 2974 * Given a raw RSSI, return the RSSI signal quality rating using the system default RSSI 2975 * quality rating thresholds. 2976 * @param rssi a raw RSSI value, in dBm, usually between -55 and -90 2977 * @return the RSSI signal quality rating, in the range 2978 * [0, {@link #getMaxSignalLevel()}], where 0 is the lowest (worst signal) RSSI 2979 * rating and {@link #getMaxSignalLevel()} is the highest (best signal) RSSI rating. 2980 */ 2981 @IntRange(from = 0) calculateSignalLevel(int rssi)2982 public int calculateSignalLevel(int rssi) { 2983 try { 2984 return mService.calculateSignalLevel(rssi); 2985 } catch (RemoteException e) { 2986 throw e.rethrowFromSystemServer(); 2987 } 2988 } 2989 2990 /** 2991 * Get the system default maximum signal level. 2992 * This is the maximum RSSI level returned by {@link #calculateSignalLevel(int)}. 2993 */ 2994 @IntRange(from = 0) getMaxSignalLevel()2995 public int getMaxSignalLevel() { 2996 return calculateSignalLevel(Integer.MAX_VALUE); 2997 } 2998 2999 /** 3000 * Compares two signal strengths. 3001 * 3002 * @param rssiA The power of the first signal measured in RSSI. 3003 * @param rssiB The power of the second signal measured in RSSI. 3004 * @return Returns <0 if the first signal is weaker than the second signal, 3005 * 0 if the two signals have the same strength, and >0 if the first 3006 * signal is stronger than the second signal. 3007 */ compareSignalLevel(int rssiA, int rssiB)3008 public static int compareSignalLevel(int rssiA, int rssiB) { 3009 return rssiA - rssiB; 3010 } 3011 3012 /** 3013 * Call allowing ConnectivityService to update WifiService with interface mode changes. 3014 * 3015 * @param ifaceName String name of the updated interface, or null to represent all interfaces 3016 * @param mode int representing the new mode, one of: 3017 * {@link #IFACE_IP_MODE_TETHERED}, 3018 * {@link #IFACE_IP_MODE_LOCAL_ONLY}, 3019 * {@link #IFACE_IP_MODE_CONFIGURATION_ERROR}, 3020 * {@link #IFACE_IP_MODE_UNSPECIFIED} 3021 * 3022 * @hide 3023 */ 3024 @SystemApi 3025 @RequiresPermission(anyOf = { 3026 android.Manifest.permission.NETWORK_STACK, 3027 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK 3028 }) updateInterfaceIpState(@ullable String ifaceName, @IfaceIpMode int mode)3029 public void updateInterfaceIpState(@Nullable String ifaceName, @IfaceIpMode int mode) { 3030 try { 3031 mService.updateInterfaceIpState(ifaceName, mode); 3032 } catch (RemoteException e) { 3033 throw e.rethrowFromSystemServer(); 3034 } 3035 } 3036 3037 /** 3038 * Start Soft AP (hotspot) mode for tethering purposes with the specified configuration. 3039 * Note that starting Soft AP mode may disable station mode operation if the device does not 3040 * support concurrency. 3041 * @param wifiConfig SSID, security and channel details as part of WifiConfiguration, or null to 3042 * use the persisted Soft AP configuration that was previously set using 3043 * {@link #setWifiApConfiguration(WifiConfiguration)}. 3044 * @return {@code true} if the operation succeeded, {@code false} otherwise 3045 * 3046 * @hide 3047 */ 3048 @RequiresPermission(anyOf = { 3049 android.Manifest.permission.NETWORK_STACK, 3050 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK 3051 }) startSoftAp(@ullable WifiConfiguration wifiConfig)3052 public boolean startSoftAp(@Nullable WifiConfiguration wifiConfig) { 3053 try { 3054 return mService.startSoftAp(wifiConfig); 3055 } catch (RemoteException e) { 3056 throw e.rethrowFromSystemServer(); 3057 } 3058 } 3059 3060 /** 3061 * Start Soft AP (hotspot) mode for tethering purposes with the specified configuration. 3062 * Note that starting Soft AP mode may disable station mode operation if the device does not 3063 * support concurrency. 3064 * @param softApConfig A valid SoftApConfiguration specifying the configuration of the SAP, 3065 * or null to use the persisted Soft AP configuration that was previously 3066 * set using {@link #setSoftApConfiguration(softApConfiguration)}. 3067 * @return {@code true} if the operation succeeded, {@code false} otherwise 3068 * 3069 * @hide 3070 */ 3071 @SystemApi 3072 @RequiresPermission(anyOf = { 3073 android.Manifest.permission.NETWORK_STACK, 3074 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK 3075 }) startTetheredHotspot(@ullable SoftApConfiguration softApConfig)3076 public boolean startTetheredHotspot(@Nullable SoftApConfiguration softApConfig) { 3077 try { 3078 return mService.startTetheredHotspot(softApConfig); 3079 } catch (RemoteException e) { 3080 throw e.rethrowFromSystemServer(); 3081 } 3082 } 3083 3084 3085 /** 3086 * Stop SoftAp mode. 3087 * Note that stopping softap mode will restore the previous wifi mode. 3088 * @return {@code true} if the operation succeeds, {@code false} otherwise 3089 * 3090 * @hide 3091 */ 3092 @SystemApi 3093 @RequiresPermission(anyOf = { 3094 android.Manifest.permission.NETWORK_STACK, 3095 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK 3096 }) stopSoftAp()3097 public boolean stopSoftAp() { 3098 try { 3099 return mService.stopSoftAp(); 3100 } catch (RemoteException e) { 3101 throw e.rethrowFromSystemServer(); 3102 } 3103 } 3104 3105 /** 3106 * Request a local only hotspot that an application can use to communicate between co-located 3107 * devices connected to the created WiFi hotspot. The network created by this method will not 3108 * have Internet access. Each application can make a single request for the hotspot, but 3109 * multiple applications could be requesting the hotspot at the same time. When multiple 3110 * applications have successfully registered concurrently, they will be sharing the underlying 3111 * hotspot. {@link LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} is called 3112 * when the hotspot is ready for use by the application. 3113 * <p> 3114 * Each application can make a single active call to this method. The {@link 3115 * LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} callback supplies the 3116 * requestor with a {@link LocalOnlyHotspotReservation} that contains a 3117 * {@link SoftApConfiguration} with the SSID, security type and credentials needed to connect 3118 * to the hotspot. Communicating this information is up to the application. 3119 * <p> 3120 * If the LocalOnlyHotspot cannot be created, the {@link LocalOnlyHotspotCallback#onFailed(int)} 3121 * method will be called. Example failures include errors bringing up the network or if 3122 * there is an incompatible operating mode. For example, if the user is currently using Wifi 3123 * Tethering to provide an upstream to another device, LocalOnlyHotspot will not start due to 3124 * an incompatible mode. The possible error codes include: 3125 * {@link LocalOnlyHotspotCallback#ERROR_NO_CHANNEL}, 3126 * {@link LocalOnlyHotspotCallback#ERROR_GENERIC}, 3127 * {@link LocalOnlyHotspotCallback#ERROR_INCOMPATIBLE_MODE} and 3128 * {@link LocalOnlyHotspotCallback#ERROR_TETHERING_DISALLOWED}. 3129 * <p> 3130 * Internally, requests will be tracked to prevent the hotspot from being torn down while apps 3131 * are still using it. The {@link LocalOnlyHotspotReservation} object passed in the {@link 3132 * LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} call should be closed when 3133 * the LocalOnlyHotspot is no longer needed using {@link LocalOnlyHotspotReservation#close()}. 3134 * Since the hotspot may be shared among multiple applications, removing the final registered 3135 * application request will trigger the hotspot teardown. This means that applications should 3136 * not listen to broadcasts containing wifi state to determine if the hotspot was stopped after 3137 * they are done using it. Additionally, once {@link LocalOnlyHotspotReservation#close()} is 3138 * called, applications will not receive callbacks of any kind. 3139 * <p> 3140 * Applications should be aware that the user may also stop the LocalOnlyHotspot through the 3141 * Settings UI; it is not guaranteed to stay up as long as there is a requesting application. 3142 * The requestors will be notified of this case via 3143 * {@link LocalOnlyHotspotCallback#onStopped()}. Other cases may arise where the hotspot is 3144 * torn down (Emergency mode, etc). Application developers should be aware that it can stop 3145 * unexpectedly, but they will receive a notification if they have properly registered. 3146 * <p> 3147 * Applications should also be aware that this network will be shared with other applications. 3148 * Applications are responsible for protecting their data on this network (e.g., TLS). 3149 * <p> 3150 * Applications need to have the following permissions to start LocalOnlyHotspot: {@link 3151 * android.Manifest.permission#CHANGE_WIFI_STATE} and {@link 3152 * android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}. Callers without 3153 * the permissions will trigger a {@link java.lang.SecurityException}. 3154 * <p> 3155 * @param callback LocalOnlyHotspotCallback for the application to receive updates about 3156 * operating status. 3157 * @param handler Handler to be used for callbacks. If the caller passes a null Handler, the 3158 * main thread will be used. 3159 */ 3160 @RequiresPermission(allOf = { 3161 android.Manifest.permission.CHANGE_WIFI_STATE, 3162 android.Manifest.permission.ACCESS_FINE_LOCATION}) startLocalOnlyHotspot(LocalOnlyHotspotCallback callback, @Nullable Handler handler)3163 public void startLocalOnlyHotspot(LocalOnlyHotspotCallback callback, 3164 @Nullable Handler handler) { 3165 Executor executor = handler == null ? null : new HandlerExecutor(handler); 3166 startLocalOnlyHotspotInternal(null, executor, callback); 3167 } 3168 3169 /** 3170 * Starts a local-only hotspot with a specific configuration applied. See 3171 * {@link #startLocalOnlyHotspot(LocalOnlyHotspotCallback, Handler)}. 3172 * 3173 * Applications need either {@link android.Manifest.permission#NETWORK_SETUP_WIZARD} or 3174 * {@link android.Manifest.permission#NETWORK_SETTINGS} to call this method. 3175 * 3176 * Since custom configuration settings may be incompatible with each other, the hotspot started 3177 * through this method cannot coexist with another hotspot created through 3178 * startLocalOnlyHotspot. If this is attempted, the first hotspot request wins and others 3179 * receive {@link LocalOnlyHotspotCallback#ERROR_GENERIC} through 3180 * {@link LocalOnlyHotspotCallback#onFailed}. 3181 * 3182 * @param config Custom configuration for the hotspot. See {@link SoftApConfiguration}. 3183 * @param executor Executor to run callback methods on, or null to use the main thread. 3184 * @param callback Callback object for updates about hotspot status, or null for no updates. 3185 * @hide 3186 */ 3187 @SystemApi 3188 @RequiresPermission(anyOf = { 3189 android.Manifest.permission.NETWORK_SETTINGS, 3190 android.Manifest.permission.NETWORK_SETUP_WIZARD}) startLocalOnlyHotspot(@onNull SoftApConfiguration config, @Nullable Executor executor, @Nullable LocalOnlyHotspotCallback callback)3191 public void startLocalOnlyHotspot(@NonNull SoftApConfiguration config, 3192 @Nullable Executor executor, 3193 @Nullable LocalOnlyHotspotCallback callback) { 3194 Objects.requireNonNull(config); 3195 startLocalOnlyHotspotInternal(config, executor, callback); 3196 } 3197 3198 /** 3199 * Common implementation of both configurable and non-configurable LOHS. 3200 * 3201 * @param config App-specified configuration, or null. When present, additional privileges are 3202 * required, and the hotspot cannot be shared with other clients. 3203 * @param executor Executor to run callback methods on, or null to use the main thread. 3204 * @param callback Callback object for updates about hotspot status, or null for no updates. 3205 */ startLocalOnlyHotspotInternal( @ullable SoftApConfiguration config, @Nullable Executor executor, @Nullable LocalOnlyHotspotCallback callback)3206 private void startLocalOnlyHotspotInternal( 3207 @Nullable SoftApConfiguration config, 3208 @Nullable Executor executor, 3209 @Nullable LocalOnlyHotspotCallback callback) { 3210 if (executor == null) { 3211 executor = mContext.getMainExecutor(); 3212 } 3213 synchronized (mLock) { 3214 LocalOnlyHotspotCallbackProxy proxy = 3215 new LocalOnlyHotspotCallbackProxy(this, executor, callback); 3216 try { 3217 String packageName = mContext.getOpPackageName(); 3218 String featureId = mContext.getAttributionTag(); 3219 int returnCode = mService.startLocalOnlyHotspot(proxy, packageName, featureId, 3220 config); 3221 if (returnCode != LocalOnlyHotspotCallback.REQUEST_REGISTERED) { 3222 // Send message to the proxy to make sure we call back on the correct thread 3223 proxy.onHotspotFailed(returnCode); 3224 return; 3225 } 3226 mLOHSCallbackProxy = proxy; 3227 } catch (RemoteException e) { 3228 throw e.rethrowFromSystemServer(); 3229 } 3230 } 3231 } 3232 3233 /** 3234 * Cancels a pending local only hotspot request. This can be used by the calling application to 3235 * cancel the existing request if the provided callback has not been triggered. Calling this 3236 * method will be equivalent to closing the returned LocalOnlyHotspotReservation, but it is not 3237 * explicitly required. 3238 * <p> 3239 * When cancelling this request, application developers should be aware that there may still be 3240 * outstanding local only hotspot requests and the hotspot may still start, or continue running. 3241 * Additionally, if a callback was registered, it will no longer be triggered after calling 3242 * cancel. 3243 * 3244 * @hide 3245 */ 3246 @UnsupportedAppUsage cancelLocalOnlyHotspotRequest()3247 public void cancelLocalOnlyHotspotRequest() { 3248 synchronized (mLock) { 3249 stopLocalOnlyHotspot(); 3250 } 3251 } 3252 3253 /** 3254 * Method used to inform WifiService that the LocalOnlyHotspot is no longer needed. This 3255 * method is used by WifiManager to release LocalOnlyHotspotReservations held by calling 3256 * applications and removes the internal tracking for the hotspot request. When all requesting 3257 * applications are finished using the hotspot, it will be stopped and WiFi will return to the 3258 * previous operational mode. 3259 * 3260 * This method should not be called by applications. Instead, they should call the close() 3261 * method on their LocalOnlyHotspotReservation. 3262 */ stopLocalOnlyHotspot()3263 private void stopLocalOnlyHotspot() { 3264 synchronized (mLock) { 3265 if (mLOHSCallbackProxy == null) { 3266 // nothing to do, the callback was already cleaned up. 3267 return; 3268 } 3269 mLOHSCallbackProxy = null; 3270 try { 3271 mService.stopLocalOnlyHotspot(); 3272 } catch (RemoteException e) { 3273 throw e.rethrowFromSystemServer(); 3274 } 3275 } 3276 } 3277 3278 /** 3279 * Allow callers (Settings UI) to watch LocalOnlyHotspot state changes. Callers will 3280 * receive a {@link LocalOnlyHotspotSubscription} object as a parameter of the 3281 * {@link LocalOnlyHotspotObserver#onRegistered(LocalOnlyHotspotSubscription)}. The registered 3282 * callers will receive the {@link LocalOnlyHotspotObserver#onStarted(SoftApConfiguration)} and 3283 * {@link LocalOnlyHotspotObserver#onStopped()} callbacks. 3284 * <p> 3285 * Applications should have the 3286 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} 3287 * permission. Callers without the permission will trigger a 3288 * {@link java.lang.SecurityException}. 3289 * <p> 3290 * @param observer LocalOnlyHotspotObserver callback. 3291 * @param handler Handler to use for callbacks 3292 * 3293 * @hide 3294 */ watchLocalOnlyHotspot(LocalOnlyHotspotObserver observer, @Nullable Handler handler)3295 public void watchLocalOnlyHotspot(LocalOnlyHotspotObserver observer, 3296 @Nullable Handler handler) { 3297 Executor executor = handler == null ? mContext.getMainExecutor() 3298 : new HandlerExecutor(handler); 3299 synchronized (mLock) { 3300 mLOHSObserverProxy = 3301 new LocalOnlyHotspotObserverProxy(this, executor, observer); 3302 try { 3303 mService.startWatchLocalOnlyHotspot(mLOHSObserverProxy); 3304 mLOHSObserverProxy.registered(); 3305 } catch (RemoteException e) { 3306 mLOHSObserverProxy = null; 3307 throw e.rethrowFromSystemServer(); 3308 } 3309 } 3310 } 3311 3312 /** 3313 * Allow callers to stop watching LocalOnlyHotspot state changes. After calling this method, 3314 * applications will no longer receive callbacks. 3315 * 3316 * @hide 3317 */ unregisterLocalOnlyHotspotObserver()3318 public void unregisterLocalOnlyHotspotObserver() { 3319 synchronized (mLock) { 3320 if (mLOHSObserverProxy == null) { 3321 // nothing to do, the callback was already cleaned up 3322 return; 3323 } 3324 mLOHSObserverProxy = null; 3325 try { 3326 mService.stopWatchLocalOnlyHotspot(); 3327 } catch (RemoteException e) { 3328 throw e.rethrowFromSystemServer(); 3329 } 3330 } 3331 } 3332 3333 /** 3334 * Gets the tethered Wi-Fi hotspot enabled state. 3335 * @return One of {@link #WIFI_AP_STATE_DISABLED}, 3336 * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED}, 3337 * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED} 3338 * @see #isWifiApEnabled() 3339 * 3340 * @hide 3341 */ 3342 @SystemApi 3343 @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) getWifiApState()3344 public int getWifiApState() { 3345 try { 3346 return mService.getWifiApEnabledState(); 3347 } catch (RemoteException e) { 3348 throw e.rethrowFromSystemServer(); 3349 } 3350 } 3351 3352 /** 3353 * Return whether tethered Wi-Fi AP is enabled or disabled. 3354 * @return {@code true} if tethered Wi-Fi AP is enabled 3355 * @see #getWifiApState() 3356 * 3357 * @hide 3358 */ 3359 @SystemApi 3360 @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) isWifiApEnabled()3361 public boolean isWifiApEnabled() { 3362 return getWifiApState() == WIFI_AP_STATE_ENABLED; 3363 } 3364 3365 /** 3366 * Gets the tethered Wi-Fi AP Configuration. 3367 * @return AP details in WifiConfiguration 3368 * 3369 * Note that AP detail may contain configuration which is cannot be represented 3370 * by the legacy WifiConfiguration, in such cases a null will be returned. 3371 * 3372 * @deprecated This API is deprecated. Use {@link #getSoftApConfiguration()} instead. 3373 * @hide 3374 */ 3375 @Nullable 3376 @SystemApi 3377 @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) 3378 @Deprecated getWifiApConfiguration()3379 public WifiConfiguration getWifiApConfiguration() { 3380 try { 3381 return mService.getWifiApConfiguration(); 3382 } catch (RemoteException e) { 3383 throw e.rethrowFromSystemServer(); 3384 } 3385 } 3386 3387 /** 3388 * Gets the Wi-Fi tethered AP Configuration. 3389 * @return AP details in {@link SoftApConfiguration} 3390 * 3391 * @hide 3392 */ 3393 @NonNull 3394 @SystemApi 3395 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) getSoftApConfiguration()3396 public SoftApConfiguration getSoftApConfiguration() { 3397 try { 3398 return mService.getSoftApConfiguration(); 3399 } catch (RemoteException e) { 3400 throw e.rethrowFromSystemServer(); 3401 } 3402 } 3403 3404 /** 3405 * Sets the tethered Wi-Fi AP Configuration. 3406 * @return {@code true} if the operation succeeded, {@code false} otherwise 3407 * 3408 * @deprecated This API is deprecated. Use {@link #setSoftApConfiguration(SoftApConfiguration)} 3409 * instead. 3410 * @hide 3411 */ 3412 @SystemApi 3413 @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) 3414 @Deprecated setWifiApConfiguration(WifiConfiguration wifiConfig)3415 public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) { 3416 try { 3417 return mService.setWifiApConfiguration(wifiConfig, mContext.getOpPackageName()); 3418 } catch (RemoteException e) { 3419 throw e.rethrowFromSystemServer(); 3420 } 3421 } 3422 3423 /** 3424 * Sets the tethered Wi-Fi AP Configuration. 3425 * 3426 * If the API is called while the tethered soft AP is enabled, the configuration will apply to 3427 * the current soft AP if the new configuration only includes 3428 * {@link SoftApConfiguration.Builder#setMaxNumberOfClients(int)} 3429 * or {@link SoftApConfiguration.Builder#setShutdownTimeoutMillis(long)} 3430 * or {@link SoftApConfiguration.Builder#setClientControlByUserEnabled(boolean)} 3431 * or {@link SoftApConfiguration.Builder#setBlockedClientList(List)} 3432 * or {@link SoftApConfiguration.Builder#setAllowedClientList(List)} 3433 * 3434 * Otherwise, the configuration changes will be applied when the Soft AP is next started 3435 * (the framework will not stop/start the AP). 3436 * 3437 * @param softApConfig A valid SoftApConfiguration specifying the configuration of the SAP. 3438 * @return {@code true} if the operation succeeded, {@code false} otherwise 3439 * 3440 * @hide 3441 */ 3442 @SystemApi 3443 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) setSoftApConfiguration(@onNull SoftApConfiguration softApConfig)3444 public boolean setSoftApConfiguration(@NonNull SoftApConfiguration softApConfig) { 3445 try { 3446 return mService.setSoftApConfiguration( 3447 softApConfig, mContext.getOpPackageName()); 3448 } catch (RemoteException e) { 3449 throw e.rethrowFromSystemServer(); 3450 } 3451 } 3452 3453 /** 3454 * Enable/Disable TDLS on a specific local route. 3455 * 3456 * <p> 3457 * TDLS enables two wireless endpoints to talk to each other directly 3458 * without going through the access point that is managing the local 3459 * network. It saves bandwidth and improves quality of the link. 3460 * </p> 3461 * <p> 3462 * This API enables/disables the option of using TDLS. If enabled, the 3463 * underlying hardware is free to use TDLS or a hop through the access 3464 * point. If disabled, existing TDLS session is torn down and 3465 * hardware is restricted to use access point for transferring wireless 3466 * packets. Default value for all routes is 'disabled', meaning restricted 3467 * to use access point for transferring packets. 3468 * </p> 3469 * 3470 * @param remoteIPAddress IP address of the endpoint to setup TDLS with 3471 * @param enable true = setup and false = tear down TDLS 3472 */ setTdlsEnabled(InetAddress remoteIPAddress, boolean enable)3473 public void setTdlsEnabled(InetAddress remoteIPAddress, boolean enable) { 3474 try { 3475 mService.enableTdls(remoteIPAddress.getHostAddress(), enable); 3476 } catch (RemoteException e) { 3477 throw e.rethrowFromSystemServer(); 3478 } 3479 } 3480 3481 /** 3482 * Similar to {@link #setTdlsEnabled(InetAddress, boolean) }, except 3483 * this version allows you to specify remote endpoint with a MAC address. 3484 * @param remoteMacAddress MAC address of the remote endpoint such as 00:00:0c:9f:f2:ab 3485 * @param enable true = setup and false = tear down TDLS 3486 */ setTdlsEnabledWithMacAddress(String remoteMacAddress, boolean enable)3487 public void setTdlsEnabledWithMacAddress(String remoteMacAddress, boolean enable) { 3488 try { 3489 mService.enableTdlsWithMacAddress(remoteMacAddress, enable); 3490 } catch (RemoteException e) { 3491 throw e.rethrowFromSystemServer(); 3492 } 3493 } 3494 3495 /** 3496 * Passed with {@link ActionListener#onFailure}. 3497 * Indicates that the operation failed due to an internal error. 3498 * @hide 3499 */ 3500 public static final int ERROR = 0; 3501 3502 /** 3503 * Passed with {@link ActionListener#onFailure}. 3504 * Indicates that the operation is already in progress 3505 * @hide 3506 */ 3507 public static final int IN_PROGRESS = 1; 3508 3509 /** 3510 * Passed with {@link ActionListener#onFailure}. 3511 * Indicates that the operation failed because the framework is busy and 3512 * unable to service the request 3513 * @hide 3514 */ 3515 public static final int BUSY = 2; 3516 3517 /** @hide */ 3518 @Retention(RetentionPolicy.SOURCE) 3519 @IntDef({ERROR, IN_PROGRESS, BUSY}) 3520 public @interface ActionListenerFailureReason {} 3521 3522 /* WPS specific errors */ 3523 /** WPS overlap detected 3524 * @deprecated This is deprecated 3525 */ 3526 public static final int WPS_OVERLAP_ERROR = 3; 3527 /** WEP on WPS is prohibited 3528 * @deprecated This is deprecated 3529 */ 3530 public static final int WPS_WEP_PROHIBITED = 4; 3531 /** TKIP only prohibited 3532 * @deprecated This is deprecated 3533 */ 3534 public static final int WPS_TKIP_ONLY_PROHIBITED = 5; 3535 /** Authentication failure on WPS 3536 * @deprecated This is deprecated 3537 */ 3538 public static final int WPS_AUTH_FAILURE = 6; 3539 /** WPS timed out 3540 * @deprecated This is deprecated 3541 */ 3542 public static final int WPS_TIMED_OUT = 7; 3543 3544 /** 3545 * Passed with {@link ActionListener#onFailure}. 3546 * Indicates that the operation failed due to invalid inputs 3547 * @hide 3548 */ 3549 public static final int INVALID_ARGS = 8; 3550 3551 /** 3552 * Passed with {@link ActionListener#onFailure}. 3553 * Indicates that the operation failed due to user permissions. 3554 * @hide 3555 */ 3556 public static final int NOT_AUTHORIZED = 9; 3557 3558 /** 3559 * Interface for callback invocation on an application action 3560 * @hide 3561 */ 3562 @SystemApi 3563 public interface ActionListener { 3564 /** 3565 * The operation succeeded. 3566 */ onSuccess()3567 void onSuccess(); 3568 /** 3569 * The operation failed. 3570 * @param reason The reason for failure depends on the operation. 3571 */ onFailure(@ctionListenerFailureReason int reason)3572 void onFailure(@ActionListenerFailureReason int reason); 3573 } 3574 3575 /** Interface for callback invocation on a start WPS action 3576 * @deprecated This is deprecated 3577 */ 3578 public static abstract class WpsCallback { 3579 3580 /** WPS start succeeded 3581 * @deprecated This API is deprecated 3582 */ onStarted(String pin)3583 public abstract void onStarted(String pin); 3584 3585 /** WPS operation completed successfully 3586 * @deprecated This API is deprecated 3587 */ onSucceeded()3588 public abstract void onSucceeded(); 3589 3590 /** 3591 * WPS operation failed 3592 * @param reason The reason for failure could be one of 3593 * {@link #WPS_TKIP_ONLY_PROHIBITED}, {@link #WPS_OVERLAP_ERROR}, 3594 * {@link #WPS_WEP_PROHIBITED}, {@link #WPS_TIMED_OUT} or {@link #WPS_AUTH_FAILURE} 3595 * and some generic errors. 3596 * @deprecated This API is deprecated 3597 */ onFailed(int reason)3598 public abstract void onFailed(int reason); 3599 } 3600 3601 /** 3602 * Base class for soft AP callback. Should be extended by applications and set when calling 3603 * {@link WifiManager#registerSoftApCallback(Executor, SoftApCallback)}. 3604 * 3605 * @hide 3606 */ 3607 @SystemApi 3608 public interface SoftApCallback { 3609 /** 3610 * Called when soft AP state changes. 3611 * 3612 * @param state the new AP state. One of {@link #WIFI_AP_STATE_DISABLED}, 3613 * {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED}, 3614 * {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED} 3615 * @param failureReason reason when in failed state. One of 3616 * {@link #SAP_START_FAILURE_GENERAL}, 3617 * {@link #SAP_START_FAILURE_NO_CHANNEL}, 3618 * {@link #SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION} 3619 */ onStateChanged(@ifiApState int state, @SapStartFailure int failureReason)3620 default void onStateChanged(@WifiApState int state, @SapStartFailure int failureReason) {} 3621 3622 /** 3623 * Called when the connected clients to soft AP changes. 3624 * 3625 * @param clients the currently connected clients 3626 */ onConnectedClientsChanged(@onNull List<WifiClient> clients)3627 default void onConnectedClientsChanged(@NonNull List<WifiClient> clients) {} 3628 3629 /** 3630 * Called when information of softap changes. 3631 * 3632 * @param softApInfo is the softap information. {@link SoftApInfo} 3633 */ onInfoChanged(@onNull SoftApInfo softApInfo)3634 default void onInfoChanged(@NonNull SoftApInfo softApInfo) { 3635 // Do nothing: can be updated to add SoftApInfo details (e.g. channel) to the UI. 3636 } 3637 3638 /** 3639 * Called when capability of softap changes. 3640 * 3641 * @param softApCapability is the softap capability. {@link SoftApCapability} 3642 */ onCapabilityChanged(@onNull SoftApCapability softApCapability)3643 default void onCapabilityChanged(@NonNull SoftApCapability softApCapability) { 3644 // Do nothing: can be updated to add SoftApCapability details (e.g. meximum supported 3645 // client number) to the UI. 3646 } 3647 3648 /** 3649 * Called when client trying to connect but device blocked the client with specific reason. 3650 * 3651 * Can be used to ask user to update client to allowed list or blocked list 3652 * when reason is {@link SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER}, or 3653 * indicate the block due to maximum supported client number limitation when reason is 3654 * {@link SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS}. 3655 * 3656 * @param client the currently blocked client. 3657 * @param blockedReason one of blocked reason from {@link SapClientBlockedReason} 3658 */ onBlockedClientConnecting(@onNull WifiClient client, @SapClientBlockedReason int blockedReason)3659 default void onBlockedClientConnecting(@NonNull WifiClient client, 3660 @SapClientBlockedReason int blockedReason) { 3661 // Do nothing: can be used to ask user to update client to allowed list or blocked list. 3662 } 3663 } 3664 3665 /** 3666 * Callback proxy for SoftApCallback objects. 3667 * 3668 * @hide 3669 */ 3670 private class SoftApCallbackProxy extends ISoftApCallback.Stub { 3671 private final Executor mExecutor; 3672 private final SoftApCallback mCallback; 3673 SoftApCallbackProxy(Executor executor, SoftApCallback callback)3674 SoftApCallbackProxy(Executor executor, SoftApCallback callback) { 3675 mExecutor = executor; 3676 mCallback = callback; 3677 } 3678 3679 @Override onStateChanged(int state, int failureReason)3680 public void onStateChanged(int state, int failureReason) { 3681 if (mVerboseLoggingEnabled) { 3682 Log.v(TAG, "SoftApCallbackProxy: onStateChanged: state=" + state 3683 + ", failureReason=" + failureReason); 3684 } 3685 3686 Binder.clearCallingIdentity(); 3687 mExecutor.execute(() -> { 3688 mCallback.onStateChanged(state, failureReason); 3689 }); 3690 } 3691 3692 @Override onConnectedClientsChanged(List<WifiClient> clients)3693 public void onConnectedClientsChanged(List<WifiClient> clients) { 3694 if (mVerboseLoggingEnabled) { 3695 Log.v(TAG, "SoftApCallbackProxy: onConnectedClientsChanged: clients=" 3696 + clients.size() + " clients"); 3697 } 3698 3699 Binder.clearCallingIdentity(); 3700 mExecutor.execute(() -> { 3701 mCallback.onConnectedClientsChanged(clients); 3702 }); 3703 } 3704 3705 @Override onInfoChanged(SoftApInfo softApInfo)3706 public void onInfoChanged(SoftApInfo softApInfo) { 3707 if (mVerboseLoggingEnabled) { 3708 Log.v(TAG, "SoftApCallbackProxy: onInfoChange: softApInfo=" + softApInfo); 3709 } 3710 3711 Binder.clearCallingIdentity(); 3712 mExecutor.execute(() -> { 3713 mCallback.onInfoChanged(softApInfo); 3714 }); 3715 } 3716 3717 @Override onCapabilityChanged(SoftApCapability capability)3718 public void onCapabilityChanged(SoftApCapability capability) { 3719 if (mVerboseLoggingEnabled) { 3720 Log.v(TAG, "SoftApCallbackProxy: onCapabilityChanged: SoftApCapability=" 3721 + capability); 3722 } 3723 3724 Binder.clearCallingIdentity(); 3725 mExecutor.execute(() -> { 3726 mCallback.onCapabilityChanged(capability); 3727 }); 3728 } 3729 3730 @Override onBlockedClientConnecting(@onNull WifiClient client, int blockedReason)3731 public void onBlockedClientConnecting(@NonNull WifiClient client, int blockedReason) { 3732 if (mVerboseLoggingEnabled) { 3733 Log.v(TAG, "SoftApCallbackProxy: onBlockedClientConnecting: client=" + client 3734 + " with reason = " + blockedReason); 3735 } 3736 3737 Binder.clearCallingIdentity(); 3738 mExecutor.execute(() -> { 3739 mCallback.onBlockedClientConnecting(client, blockedReason); 3740 }); 3741 } 3742 } 3743 3744 /** 3745 * Registers a callback for Soft AP. See {@link SoftApCallback}. Caller will receive the 3746 * following callbacks on registration: 3747 * <ul> 3748 * <li> {@link SoftApCallback#onStateChanged(int, int)}</li> 3749 * <li> {@link SoftApCallback#onConnectedClientsChanged(List<WifiClient>)}</li> 3750 * <li> {@link SoftApCallback#onInfoChanged(SoftApInfo)}</li> 3751 * <li> {@link SoftApCallback#onCapabilityChanged(SoftApCapability)}</li> 3752 * </ul> 3753 * These will be dispatched on registration to provide the caller with the current state 3754 * (and are not an indication of any current change). Note that receiving an immediate 3755 * WIFI_AP_STATE_FAILED value for soft AP state indicates that the latest attempt to start 3756 * soft AP has failed. Caller can unregister a previously registered callback using 3757 * {@link #unregisterSoftApCallback} 3758 * <p> 3759 * Applications should have the 3760 * {@link android.Manifest.permission#NETWORK_SETTINGS NETWORK_SETTINGS} permission. Callers 3761 * without the permission will trigger a {@link java.lang.SecurityException}. 3762 * <p> 3763 * 3764 * @param executor The Executor on whose thread to execute the callbacks of the {@code callback} 3765 * object. 3766 * @param callback Callback for soft AP events 3767 * @hide 3768 */ 3769 @SystemApi 3770 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) registerSoftApCallback(@onNull @allbackExecutor Executor executor, @NonNull SoftApCallback callback)3771 public void registerSoftApCallback(@NonNull @CallbackExecutor Executor executor, 3772 @NonNull SoftApCallback callback) { 3773 if (executor == null) throw new IllegalArgumentException("executor cannot be null"); 3774 if (callback == null) throw new IllegalArgumentException("callback cannot be null"); 3775 Log.v(TAG, "registerSoftApCallback: callback=" + callback + ", executor=" + executor); 3776 3777 Binder binder = new Binder(); 3778 try { 3779 mService.registerSoftApCallback( 3780 binder, new SoftApCallbackProxy(executor, callback), callback.hashCode()); 3781 } catch (RemoteException e) { 3782 throw e.rethrowFromSystemServer(); 3783 } 3784 } 3785 3786 /** 3787 * Allow callers to unregister a previously registered callback. After calling this method, 3788 * applications will no longer receive soft AP events. 3789 * 3790 * @param callback Callback to unregister for soft AP events 3791 * 3792 * @hide 3793 */ 3794 @SystemApi 3795 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) unregisterSoftApCallback(@onNull SoftApCallback callback)3796 public void unregisterSoftApCallback(@NonNull SoftApCallback callback) { 3797 if (callback == null) throw new IllegalArgumentException("callback cannot be null"); 3798 Log.v(TAG, "unregisterSoftApCallback: callback=" + callback); 3799 3800 try { 3801 mService.unregisterSoftApCallback(callback.hashCode()); 3802 } catch (RemoteException e) { 3803 throw e.rethrowFromSystemServer(); 3804 } 3805 } 3806 3807 /** 3808 * LocalOnlyHotspotReservation that contains the {@link SoftApConfiguration} for the active 3809 * LocalOnlyHotspot request. 3810 * <p> 3811 * Applications requesting LocalOnlyHotspot for sharing will receive an instance of the 3812 * LocalOnlyHotspotReservation in the 3813 * {@link LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} call. This 3814 * reservation contains the relevant {@link SoftApConfiguration}. 3815 * When an application is done with the LocalOnlyHotspot, they should call {@link 3816 * LocalOnlyHotspotReservation#close()}. Once this happens, the application will not receive 3817 * any further callbacks. If the LocalOnlyHotspot is stopped due to a 3818 * user triggered mode change, applications will be notified via the {@link 3819 * LocalOnlyHotspotCallback#onStopped()} callback. 3820 */ 3821 public class LocalOnlyHotspotReservation implements AutoCloseable { 3822 3823 private final CloseGuard mCloseGuard = new CloseGuard(); 3824 private final SoftApConfiguration mSoftApConfig; 3825 private final WifiConfiguration mWifiConfig; 3826 private boolean mClosed = false; 3827 3828 /** @hide */ 3829 @VisibleForTesting LocalOnlyHotspotReservation(SoftApConfiguration config)3830 public LocalOnlyHotspotReservation(SoftApConfiguration config) { 3831 mSoftApConfig = config; 3832 mWifiConfig = config.toWifiConfiguration(); 3833 mCloseGuard.open("close"); 3834 } 3835 3836 /** 3837 * Returns the {@link WifiConfiguration} of the current Local Only Hotspot (LOHS). 3838 * May be null if hotspot enabled and security type is not 3839 * {@code WifiConfiguration.KeyMgmt.None} or {@code WifiConfiguration.KeyMgmt.WPA2_PSK}. 3840 * 3841 * @deprecated Use {@code WifiManager#getSoftApConfiguration()} to get the 3842 * LOHS configuration. 3843 */ 3844 @Deprecated 3845 @Nullable getWifiConfiguration()3846 public WifiConfiguration getWifiConfiguration() { 3847 return mWifiConfig; 3848 } 3849 3850 /** 3851 * Returns the {@link SoftApConfiguration} of the current Local Only Hotspot (LOHS). 3852 */ 3853 @NonNull getSoftApConfiguration()3854 public SoftApConfiguration getSoftApConfiguration() { 3855 return mSoftApConfig; 3856 } 3857 3858 @Override close()3859 public void close() { 3860 try { 3861 synchronized (mLock) { 3862 if (!mClosed) { 3863 mClosed = true; 3864 stopLocalOnlyHotspot(); 3865 mCloseGuard.close(); 3866 } 3867 } 3868 } catch (Exception e) { 3869 Log.e(TAG, "Failed to stop Local Only Hotspot."); 3870 } finally { 3871 Reference.reachabilityFence(this); 3872 } 3873 } 3874 3875 @Override finalize()3876 protected void finalize() throws Throwable { 3877 try { 3878 if (mCloseGuard != null) { 3879 mCloseGuard.warnIfOpen(); 3880 } 3881 close(); 3882 } finally { 3883 super.finalize(); 3884 } 3885 } 3886 } 3887 3888 /** 3889 * Callback class for applications to receive updates about the LocalOnlyHotspot status. 3890 */ 3891 public static class LocalOnlyHotspotCallback { 3892 /** @hide */ 3893 public static final int REQUEST_REGISTERED = 0; 3894 3895 public static final int ERROR_NO_CHANNEL = 1; 3896 public static final int ERROR_GENERIC = 2; 3897 public static final int ERROR_INCOMPATIBLE_MODE = 3; 3898 public static final int ERROR_TETHERING_DISALLOWED = 4; 3899 3900 /** LocalOnlyHotspot start succeeded. */ onStarted(LocalOnlyHotspotReservation reservation)3901 public void onStarted(LocalOnlyHotspotReservation reservation) {}; 3902 3903 /** 3904 * LocalOnlyHotspot stopped. 3905 * <p> 3906 * The LocalOnlyHotspot can be disabled at any time by the user. When this happens, 3907 * applications will be notified that it was stopped. This will not be invoked when an 3908 * application calls {@link LocalOnlyHotspotReservation#close()}. 3909 */ onStopped()3910 public void onStopped() {}; 3911 3912 /** 3913 * LocalOnlyHotspot failed to start. 3914 * <p> 3915 * Applications can attempt to call 3916 * {@link WifiManager#startLocalOnlyHotspot(LocalOnlyHotspotCallback, Handler)} again at 3917 * a later time. 3918 * <p> 3919 * @param reason The reason for failure could be one of: {@link 3920 * #ERROR_TETHERING_DISALLOWED}, {@link #ERROR_INCOMPATIBLE_MODE}, 3921 * {@link #ERROR_NO_CHANNEL}, or {@link #ERROR_GENERIC}. 3922 */ onFailed(int reason)3923 public void onFailed(int reason) { }; 3924 } 3925 3926 /** 3927 * Callback proxy for LocalOnlyHotspotCallback objects. 3928 */ 3929 private static class LocalOnlyHotspotCallbackProxy extends ILocalOnlyHotspotCallback.Stub { 3930 private final WeakReference<WifiManager> mWifiManager; 3931 private final Executor mExecutor; 3932 private final LocalOnlyHotspotCallback mCallback; 3933 3934 /** 3935 * Constructs a {@link LocalOnlyHotspotCallbackProxy} using the specified executor. All 3936 * callbacks will run using the given executor. 3937 * 3938 * @param manager WifiManager 3939 * @param executor Executor for delivering callbacks. 3940 * @param callback LocalOnlyHotspotCallback to notify the calling application, or null. 3941 */ LocalOnlyHotspotCallbackProxy( @onNull WifiManager manager, @NonNull Executor executor, @Nullable LocalOnlyHotspotCallback callback)3942 LocalOnlyHotspotCallbackProxy( 3943 @NonNull WifiManager manager, 3944 @NonNull Executor executor, 3945 @Nullable LocalOnlyHotspotCallback callback) { 3946 mWifiManager = new WeakReference<>(manager); 3947 mExecutor = executor; 3948 mCallback = callback; 3949 } 3950 3951 @Override onHotspotStarted(SoftApConfiguration config)3952 public void onHotspotStarted(SoftApConfiguration config) { 3953 WifiManager manager = mWifiManager.get(); 3954 if (manager == null) return; 3955 3956 if (config == null) { 3957 Log.e(TAG, "LocalOnlyHotspotCallbackProxy: config cannot be null."); 3958 onHotspotFailed(LocalOnlyHotspotCallback.ERROR_GENERIC); 3959 return; 3960 } 3961 final LocalOnlyHotspotReservation reservation = 3962 manager.new LocalOnlyHotspotReservation(config); 3963 if (mCallback == null) return; 3964 mExecutor.execute(() -> mCallback.onStarted(reservation)); 3965 } 3966 3967 @Override onHotspotStopped()3968 public void onHotspotStopped() { 3969 WifiManager manager = mWifiManager.get(); 3970 if (manager == null) return; 3971 3972 Log.w(TAG, "LocalOnlyHotspotCallbackProxy: hotspot stopped"); 3973 if (mCallback == null) return; 3974 mExecutor.execute(() -> mCallback.onStopped()); 3975 } 3976 3977 @Override onHotspotFailed(int reason)3978 public void onHotspotFailed(int reason) { 3979 WifiManager manager = mWifiManager.get(); 3980 if (manager == null) return; 3981 3982 Log.w(TAG, "LocalOnlyHotspotCallbackProxy: failed to start. reason: " 3983 + reason); 3984 if (mCallback == null) return; 3985 mExecutor.execute(() -> mCallback.onFailed(reason)); 3986 } 3987 } 3988 3989 /** 3990 * LocalOnlyHotspotSubscription that is an AutoCloseable object for tracking applications 3991 * watching for LocalOnlyHotspot changes. 3992 * 3993 * @hide 3994 */ 3995 public class LocalOnlyHotspotSubscription implements AutoCloseable { 3996 private final CloseGuard mCloseGuard = new CloseGuard(); 3997 3998 /** @hide */ 3999 @VisibleForTesting LocalOnlyHotspotSubscription()4000 public LocalOnlyHotspotSubscription() { 4001 mCloseGuard.open("close"); 4002 } 4003 4004 @Override close()4005 public void close() { 4006 try { 4007 unregisterLocalOnlyHotspotObserver(); 4008 mCloseGuard.close(); 4009 } catch (Exception e) { 4010 Log.e(TAG, "Failed to unregister LocalOnlyHotspotObserver."); 4011 } finally { 4012 Reference.reachabilityFence(this); 4013 } 4014 } 4015 4016 @Override finalize()4017 protected void finalize() throws Throwable { 4018 try { 4019 if (mCloseGuard != null) { 4020 mCloseGuard.warnIfOpen(); 4021 } 4022 close(); 4023 } finally { 4024 super.finalize(); 4025 } 4026 } 4027 } 4028 4029 /** 4030 * Class to notify calling applications that watch for changes in LocalOnlyHotspot of updates. 4031 * 4032 * @hide 4033 */ 4034 public static class LocalOnlyHotspotObserver { 4035 /** 4036 * Confirm registration for LocalOnlyHotspotChanges by returning a 4037 * LocalOnlyHotspotSubscription. 4038 */ onRegistered(LocalOnlyHotspotSubscription subscription)4039 public void onRegistered(LocalOnlyHotspotSubscription subscription) {}; 4040 4041 /** 4042 * LocalOnlyHotspot started with the supplied config. 4043 */ onStarted(SoftApConfiguration config)4044 public void onStarted(SoftApConfiguration config) {}; 4045 4046 /** 4047 * LocalOnlyHotspot stopped. 4048 */ onStopped()4049 public void onStopped() {}; 4050 } 4051 4052 /** 4053 * Callback proxy for LocalOnlyHotspotObserver objects. 4054 */ 4055 private static class LocalOnlyHotspotObserverProxy extends ILocalOnlyHotspotCallback.Stub { 4056 private final WeakReference<WifiManager> mWifiManager; 4057 private final Executor mExecutor; 4058 private final LocalOnlyHotspotObserver mObserver; 4059 4060 /** 4061 * Constructs a {@link LocalOnlyHotspotObserverProxy} using the specified looper. 4062 * All callbacks will be delivered on the thread of the specified looper. 4063 * 4064 * @param manager WifiManager 4065 * @param executor Executor for delivering callbacks 4066 * @param observer LocalOnlyHotspotObserver to notify the calling application. 4067 */ LocalOnlyHotspotObserverProxy(WifiManager manager, Executor executor, final LocalOnlyHotspotObserver observer)4068 LocalOnlyHotspotObserverProxy(WifiManager manager, Executor executor, 4069 final LocalOnlyHotspotObserver observer) { 4070 mWifiManager = new WeakReference<>(manager); 4071 mExecutor = executor; 4072 mObserver = observer; 4073 } 4074 registered()4075 public void registered() throws RemoteException { 4076 WifiManager manager = mWifiManager.get(); 4077 if (manager == null) return; 4078 4079 mExecutor.execute(() -> 4080 mObserver.onRegistered(manager.new LocalOnlyHotspotSubscription())); 4081 } 4082 4083 @Override onHotspotStarted(SoftApConfiguration config)4084 public void onHotspotStarted(SoftApConfiguration config) { 4085 WifiManager manager = mWifiManager.get(); 4086 if (manager == null) return; 4087 4088 if (config == null) { 4089 Log.e(TAG, "LocalOnlyHotspotObserverProxy: config cannot be null."); 4090 return; 4091 } 4092 mExecutor.execute(() -> mObserver.onStarted(config)); 4093 } 4094 4095 @Override onHotspotStopped()4096 public void onHotspotStopped() { 4097 WifiManager manager = mWifiManager.get(); 4098 if (manager == null) return; 4099 4100 mExecutor.execute(() -> mObserver.onStopped()); 4101 } 4102 4103 @Override onHotspotFailed(int reason)4104 public void onHotspotFailed(int reason) { 4105 // do nothing 4106 } 4107 } 4108 4109 /** 4110 * Callback proxy for ActionListener objects. 4111 */ 4112 private class ActionListenerProxy extends IActionListener.Stub { 4113 private final String mActionTag; 4114 private final Handler mHandler; 4115 private final ActionListener mCallback; 4116 ActionListenerProxy(String actionTag, Looper looper, ActionListener callback)4117 ActionListenerProxy(String actionTag, Looper looper, ActionListener callback) { 4118 mActionTag = actionTag; 4119 mHandler = new Handler(looper); 4120 mCallback = callback; 4121 } 4122 4123 @Override onSuccess()4124 public void onSuccess() { 4125 if (mVerboseLoggingEnabled) { 4126 Log.v(TAG, "ActionListenerProxy:" + mActionTag + ": onSuccess"); 4127 } 4128 mHandler.post(() -> { 4129 mCallback.onSuccess(); 4130 }); 4131 } 4132 4133 @Override onFailure(@ctionListenerFailureReason int reason)4134 public void onFailure(@ActionListenerFailureReason int reason) { 4135 if (mVerboseLoggingEnabled) { 4136 Log.v(TAG, "ActionListenerProxy:" + mActionTag + ": onFailure=" + reason); 4137 } 4138 mHandler.post(() -> { 4139 mCallback.onFailure(reason); 4140 }); 4141 } 4142 } 4143 connectInternal(@ullable WifiConfiguration config, int networkId, @Nullable ActionListener listener)4144 private void connectInternal(@Nullable WifiConfiguration config, int networkId, 4145 @Nullable ActionListener listener) { 4146 ActionListenerProxy listenerProxy = null; 4147 Binder binder = null; 4148 if (listener != null) { 4149 listenerProxy = new ActionListenerProxy("connect", mLooper, listener); 4150 binder = new Binder(); 4151 } 4152 try { 4153 mService.connect(config, networkId, binder, listenerProxy, 4154 listener == null ? 0 : listener.hashCode()); 4155 } catch (RemoteException e) { 4156 if (listenerProxy != null) listenerProxy.onFailure(ERROR); 4157 } catch (SecurityException e) { 4158 if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED); 4159 } 4160 } 4161 4162 /** 4163 * Connect to a network with the given configuration. The network also 4164 * gets added to the list of configured networks for the foreground user. 4165 * 4166 * For a new network, this function is used instead of a 4167 * sequence of addNetwork(), enableNetwork(), and reconnect() 4168 * 4169 * @param config the set of variables that describe the configuration, 4170 * contained in a {@link WifiConfiguration} object. 4171 * @param listener for callbacks on success or failure. Can be null. 4172 * @throws IllegalStateException if the WifiManager instance needs to be 4173 * initialized again 4174 * 4175 * @hide 4176 */ 4177 @SystemApi 4178 @RequiresPermission(anyOf = { 4179 android.Manifest.permission.NETWORK_SETTINGS, 4180 android.Manifest.permission.NETWORK_SETUP_WIZARD, 4181 android.Manifest.permission.NETWORK_STACK 4182 }) connect(@onNull WifiConfiguration config, @Nullable ActionListener listener)4183 public void connect(@NonNull WifiConfiguration config, @Nullable ActionListener listener) { 4184 if (config == null) throw new IllegalArgumentException("config cannot be null"); 4185 connectInternal(config, WifiConfiguration.INVALID_NETWORK_ID, listener); 4186 } 4187 4188 /** 4189 * Connect to a network with the given networkId. 4190 * 4191 * This function is used instead of a enableNetwork() and reconnect() 4192 * 4193 * <li> This API will cause reconnect if the credentials of the current active 4194 * connection has been changed.</li> 4195 * <li> This API will cause reconnect if the current active connection is marked metered.</li> 4196 * 4197 * @param networkId the ID of the network as returned by {@link #addNetwork} or {@link 4198 * getConfiguredNetworks}. 4199 * @param listener for callbacks on success or failure. Can be null. 4200 * @throws IllegalStateException if the WifiManager instance needs to be 4201 * initialized again 4202 * @hide 4203 */ 4204 @SystemApi 4205 @RequiresPermission(anyOf = { 4206 android.Manifest.permission.NETWORK_SETTINGS, 4207 android.Manifest.permission.NETWORK_SETUP_WIZARD, 4208 android.Manifest.permission.NETWORK_STACK 4209 }) connect(int networkId, @Nullable ActionListener listener)4210 public void connect(int networkId, @Nullable ActionListener listener) { 4211 if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative"); 4212 connectInternal(null, networkId, listener); 4213 } 4214 4215 /** 4216 * Save the given network to the list of configured networks for the 4217 * foreground user. If the network already exists, the configuration 4218 * is updated. Any new network is enabled by default. 4219 * 4220 * For a new network, this function is used instead of a 4221 * sequence of addNetwork() and enableNetwork(). 4222 * 4223 * For an existing network, it accomplishes the task of updateNetwork() 4224 * 4225 * <li> This API will cause reconnect if the credentials of the current active 4226 * connection has been changed.</li> 4227 * <li> This API will cause disconnect if the current active connection is marked metered.</li> 4228 * 4229 * @param config the set of variables that describe the configuration, 4230 * contained in a {@link WifiConfiguration} object. 4231 * @param listener for callbacks on success or failure. Can be null. 4232 * @throws IllegalStateException if the WifiManager instance needs to be 4233 * initialized again 4234 * @hide 4235 */ 4236 @SystemApi 4237 @RequiresPermission(anyOf = { 4238 android.Manifest.permission.NETWORK_SETTINGS, 4239 android.Manifest.permission.NETWORK_SETUP_WIZARD, 4240 android.Manifest.permission.NETWORK_STACK 4241 }) save(@onNull WifiConfiguration config, @Nullable ActionListener listener)4242 public void save(@NonNull WifiConfiguration config, @Nullable ActionListener listener) { 4243 if (config == null) throw new IllegalArgumentException("config cannot be null"); 4244 ActionListenerProxy listenerProxy = null; 4245 Binder binder = null; 4246 if (listener != null) { 4247 listenerProxy = new ActionListenerProxy("save", mLooper, listener); 4248 binder = new Binder(); 4249 } 4250 try { 4251 mService.save(config, binder, listenerProxy, 4252 listener == null ? 0 : listener.hashCode()); 4253 } catch (RemoteException e) { 4254 if (listenerProxy != null) listenerProxy.onFailure(ERROR); 4255 } catch (SecurityException e) { 4256 if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED); 4257 } 4258 } 4259 4260 /** 4261 * Delete the network from the list of configured networks for the 4262 * foreground user. 4263 * 4264 * This function is used instead of a sequence of removeNetwork() 4265 * 4266 * @param config the set of variables that describe the configuration, 4267 * contained in a {@link WifiConfiguration} object. 4268 * @param listener for callbacks on success or failure. Can be null. 4269 * @throws IllegalStateException if the WifiManager instance needs to be 4270 * initialized again 4271 * @hide 4272 */ 4273 @SystemApi 4274 @RequiresPermission(anyOf = { 4275 android.Manifest.permission.NETWORK_SETTINGS, 4276 android.Manifest.permission.NETWORK_SETUP_WIZARD, 4277 android.Manifest.permission.NETWORK_STACK 4278 }) forget(int netId, @Nullable ActionListener listener)4279 public void forget(int netId, @Nullable ActionListener listener) { 4280 if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative"); 4281 ActionListenerProxy listenerProxy = null; 4282 Binder binder = null; 4283 if (listener != null) { 4284 listenerProxy = new ActionListenerProxy("forget", mLooper, listener); 4285 binder = new Binder(); 4286 } 4287 try { 4288 mService.forget(netId, binder, listenerProxy, 4289 listener == null ? 0 : listener.hashCode()); 4290 } catch (RemoteException e) { 4291 if (listenerProxy != null) listenerProxy.onFailure(ERROR); 4292 } catch (SecurityException e) { 4293 if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED); 4294 } 4295 } 4296 4297 /** 4298 * Disable network 4299 * 4300 * @param netId is the network Id 4301 * @param listener for callbacks on success or failure. Can be null. 4302 * @throws IllegalStateException if the WifiManager instance needs to be 4303 * initialized again 4304 * @deprecated This API is deprecated. Use {@link #disableNetwork(int)} instead. 4305 * @hide 4306 */ 4307 @SystemApi 4308 @RequiresPermission(anyOf = { 4309 android.Manifest.permission.NETWORK_SETTINGS, 4310 android.Manifest.permission.NETWORK_SETUP_WIZARD, 4311 android.Manifest.permission.NETWORK_STACK 4312 }) 4313 @Deprecated disable(int netId, @Nullable ActionListener listener)4314 public void disable(int netId, @Nullable ActionListener listener) { 4315 if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative"); 4316 // Simple wrapper which forwards the call to disableNetwork. This is a temporary 4317 // implementation until we can remove this API completely. 4318 boolean status = disableNetwork(netId); 4319 if (listener != null) { 4320 if (status) { 4321 listener.onSuccess(); 4322 } else { 4323 listener.onFailure(ERROR); 4324 } 4325 } 4326 } 4327 4328 /** 4329 * Enable/disable auto-join globally. 4330 * 4331 * @param allowAutojoin true to allow auto-join, false to disallow auto-join 4332 * @hide 4333 */ 4334 @SystemApi 4335 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) allowAutojoinGlobal(boolean allowAutojoin)4336 public void allowAutojoinGlobal(boolean allowAutojoin) { 4337 try { 4338 mService.allowAutojoinGlobal(allowAutojoin); 4339 } catch (RemoteException e) { 4340 throw e.rethrowFromSystemServer(); 4341 } 4342 } 4343 4344 4345 /** 4346 * Sets the user choice for allowing auto-join to a network. 4347 * The updated choice will be made available through the updated config supplied by the 4348 * CONFIGURED_NETWORKS_CHANGED broadcast. 4349 * 4350 * @param netId the id of the network to allow/disallow auto-join for. 4351 * @param allowAutojoin true to allow auto-join, false to disallow auto-join 4352 * @hide 4353 */ 4354 @SystemApi 4355 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) allowAutojoin(int netId, boolean allowAutojoin)4356 public void allowAutojoin(int netId, boolean allowAutojoin) { 4357 try { 4358 mService.allowAutojoin(netId, allowAutojoin); 4359 } catch (RemoteException e) { 4360 throw e.rethrowFromSystemServer(); 4361 } 4362 } 4363 4364 /** 4365 * Configure auto-join settings for a Passpoint profile. 4366 * 4367 * @param fqdn the FQDN (fully qualified domain name) of the passpoint profile. 4368 * @param allowAutojoin true to enable auto-join, false to disable auto-join. 4369 * @hide 4370 */ 4371 @SystemApi 4372 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) allowAutojoinPasspoint(@onNull String fqdn, boolean allowAutojoin)4373 public void allowAutojoinPasspoint(@NonNull String fqdn, boolean allowAutojoin) { 4374 try { 4375 mService.allowAutojoinPasspoint(fqdn, allowAutojoin); 4376 } catch (RemoteException e) { 4377 throw e.rethrowFromSystemServer(); 4378 } 4379 } 4380 4381 /** 4382 * Configure MAC randomization setting for a Passpoint profile. 4383 * MAC randomization is enabled by default. 4384 * 4385 * @param fqdn the FQDN (fully qualified domain name) of the passpoint profile. 4386 * @param enable true to enable MAC randomization, false to disable MAC randomization. 4387 * @hide 4388 */ 4389 @SystemApi 4390 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) setMacRandomizationSettingPasspointEnabled(@onNull String fqdn, boolean enable)4391 public void setMacRandomizationSettingPasspointEnabled(@NonNull String fqdn, boolean enable) { 4392 try { 4393 mService.setMacRandomizationSettingPasspointEnabled(fqdn, enable); 4394 } catch (RemoteException e) { 4395 throw e.rethrowFromSystemServer(); 4396 } 4397 } 4398 4399 /** 4400 * Sets the user's choice of metered override for a Passpoint profile. 4401 * 4402 * @param fqdn the FQDN (fully qualified domain name) of the passpoint profile. 4403 * @param meteredOverride One of three values: {@link WifiConfiguration#METERED_OVERRIDE_NONE}, 4404 * {@link WifiConfiguration#METERED_OVERRIDE_METERED}, 4405 * {@link WifiConfiguration#METERED_OVERRIDE_NOT_METERED} 4406 * @hide 4407 */ 4408 @SystemApi 4409 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) setPasspointMeteredOverride(@onNull String fqdn, @WifiConfiguration.MeteredOverride int meteredOverride)4410 public void setPasspointMeteredOverride(@NonNull String fqdn, 4411 @WifiConfiguration.MeteredOverride int meteredOverride) { 4412 try { 4413 mService.setPasspointMeteredOverride(fqdn, meteredOverride); 4414 } catch (RemoteException e) { 4415 throw e.rethrowFromSystemServer(); 4416 } 4417 } 4418 4419 /** 4420 * Temporarily disable a network. Should always trigger with user disconnect network. 4421 * 4422 * @param network Input can be SSID or FQDN. And caller must ensure that the SSID passed thru 4423 * this API matched the WifiConfiguration.SSID rules, and thus be surrounded by 4424 * quotes. 4425 * @hide 4426 */ 4427 @SystemApi 4428 @RequiresPermission(anyOf = { 4429 android.Manifest.permission.NETWORK_SETTINGS, 4430 android.Manifest.permission.NETWORK_STACK 4431 }) disableEphemeralNetwork(@onNull String network)4432 public void disableEphemeralNetwork(@NonNull String network) { 4433 if (TextUtils.isEmpty(network)) { 4434 throw new IllegalArgumentException("SSID cannot be null or empty!"); 4435 } 4436 try { 4437 mService.disableEphemeralNetwork(network, mContext.getOpPackageName()); 4438 } catch (RemoteException e) { 4439 throw e.rethrowFromSystemServer(); 4440 } 4441 } 4442 4443 /** 4444 * WPS suport has been deprecated from Client mode and this method will immediately trigger 4445 * {@link WpsCallback#onFailed(int)} with a generic error. 4446 * 4447 * @param config WPS configuration (does not support {@link WpsInfo#LABEL}) 4448 * @param listener for callbacks on success or failure. Can be null. 4449 * @throws IllegalStateException if the WifiManager instance needs to be initialized again 4450 * @deprecated This API is deprecated 4451 */ startWps(WpsInfo config, WpsCallback listener)4452 public void startWps(WpsInfo config, WpsCallback listener) { 4453 if (listener != null ) { 4454 listener.onFailed(ERROR); 4455 } 4456 } 4457 4458 /** 4459 * WPS support has been deprecated from Client mode and this method will immediately trigger 4460 * {@link WpsCallback#onFailed(int)} with a generic error. 4461 * 4462 * @param listener for callbacks on success or failure. Can be null. 4463 * @throws IllegalStateException if the WifiManager instance needs to be initialized again 4464 * @deprecated This API is deprecated 4465 */ cancelWps(WpsCallback listener)4466 public void cancelWps(WpsCallback listener) { 4467 if (listener != null) { 4468 listener.onFailed(ERROR); 4469 } 4470 } 4471 4472 /** 4473 * Allows an application to keep the Wi-Fi radio awake. 4474 * Normally the Wi-Fi radio may turn off when the user has not used the device in a while. 4475 * Acquiring a WifiLock will keep the radio on until the lock is released. Multiple 4476 * applications may hold WifiLocks, and the radio will only be allowed to turn off when no 4477 * WifiLocks are held in any application. 4478 * <p> 4479 * Before using a WifiLock, consider carefully if your application requires Wi-Fi access, or 4480 * could function over a mobile network, if available. A program that needs to download large 4481 * files should hold a WifiLock to ensure that the download will complete, but a program whose 4482 * network usage is occasional or low-bandwidth should not hold a WifiLock to avoid adversely 4483 * affecting battery life. 4484 * <p> 4485 * Note that WifiLocks cannot override the user-level "Wi-Fi Enabled" setting, nor Airplane 4486 * Mode. They simply keep the radio from turning off when Wi-Fi is already on but the device 4487 * is idle. 4488 * <p> 4489 * Any application using a WifiLock must request the {@code android.permission.WAKE_LOCK} 4490 * permission in an {@code <uses-permission>} element of the application's manifest. 4491 */ 4492 public class WifiLock { 4493 private String mTag; 4494 private final IBinder mBinder; 4495 private int mRefCount; 4496 int mLockType; 4497 private boolean mRefCounted; 4498 private boolean mHeld; 4499 private WorkSource mWorkSource; 4500 WifiLock(int lockType, String tag)4501 private WifiLock(int lockType, String tag) { 4502 mTag = tag; 4503 mLockType = lockType; 4504 mBinder = new Binder(); 4505 mRefCount = 0; 4506 mRefCounted = true; 4507 mHeld = false; 4508 } 4509 4510 /** 4511 * Locks the Wi-Fi radio on until {@link #release} is called. 4512 * 4513 * If this WifiLock is reference-counted, each call to {@code acquire} will increment the 4514 * reference count, and the radio will remain locked as long as the reference count is 4515 * above zero. 4516 * 4517 * If this WifiLock is not reference-counted, the first call to {@code acquire} will lock 4518 * the radio, but subsequent calls will be ignored. Only one call to {@link #release} 4519 * will be required, regardless of the number of times that {@code acquire} is called. 4520 */ acquire()4521 public void acquire() { 4522 synchronized (mBinder) { 4523 if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) { 4524 try { 4525 mService.acquireWifiLock(mBinder, mLockType, mTag, mWorkSource); 4526 synchronized (WifiManager.this) { 4527 if (mActiveLockCount >= MAX_ACTIVE_LOCKS) { 4528 mService.releaseWifiLock(mBinder); 4529 throw new UnsupportedOperationException( 4530 "Exceeded maximum number of wifi locks"); 4531 } 4532 mActiveLockCount++; 4533 } 4534 } catch (RemoteException e) { 4535 throw e.rethrowFromSystemServer(); 4536 } 4537 mHeld = true; 4538 } 4539 } 4540 } 4541 4542 /** 4543 * Unlocks the Wi-Fi radio, allowing it to turn off when the device is idle. 4544 * 4545 * If this WifiLock is reference-counted, each call to {@code release} will decrement the 4546 * reference count, and the radio will be unlocked only when the reference count reaches 4547 * zero. If the reference count goes below zero (that is, if {@code release} is called 4548 * a greater number of times than {@link #acquire}), an exception is thrown. 4549 * 4550 * If this WifiLock is not reference-counted, the first call to {@code release} (after 4551 * the radio was locked using {@link #acquire}) will unlock the radio, and subsequent 4552 * calls will be ignored. 4553 */ release()4554 public void release() { 4555 synchronized (mBinder) { 4556 if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { 4557 try { 4558 mService.releaseWifiLock(mBinder); 4559 synchronized (WifiManager.this) { 4560 mActiveLockCount--; 4561 } 4562 } catch (RemoteException e) { 4563 throw e.rethrowFromSystemServer(); 4564 } 4565 mHeld = false; 4566 } 4567 if (mRefCount < 0) { 4568 throw new RuntimeException("WifiLock under-locked " + mTag); 4569 } 4570 } 4571 } 4572 4573 /** 4574 * Controls whether this is a reference-counted or non-reference-counted WifiLock. 4575 * 4576 * Reference-counted WifiLocks keep track of the number of calls to {@link #acquire} and 4577 * {@link #release}, and only allow the radio to sleep when every call to {@link #acquire} 4578 * has been balanced with a call to {@link #release}. Non-reference-counted WifiLocks 4579 * lock the radio whenever {@link #acquire} is called and it is unlocked, and unlock the 4580 * radio whenever {@link #release} is called and it is locked. 4581 * 4582 * @param refCounted true if this WifiLock should keep a reference count 4583 */ setReferenceCounted(boolean refCounted)4584 public void setReferenceCounted(boolean refCounted) { 4585 mRefCounted = refCounted; 4586 } 4587 4588 /** 4589 * Checks whether this WifiLock is currently held. 4590 * 4591 * @return true if this WifiLock is held, false otherwise 4592 */ isHeld()4593 public boolean isHeld() { 4594 synchronized (mBinder) { 4595 return mHeld; 4596 } 4597 } 4598 setWorkSource(WorkSource ws)4599 public void setWorkSource(WorkSource ws) { 4600 synchronized (mBinder) { 4601 if (ws != null && ws.isEmpty()) { 4602 ws = null; 4603 } 4604 boolean changed = true; 4605 if (ws == null) { 4606 mWorkSource = null; 4607 } else { 4608 ws = ws.withoutNames(); 4609 if (mWorkSource == null) { 4610 changed = mWorkSource != null; 4611 mWorkSource = new WorkSource(ws); 4612 } else { 4613 changed = !mWorkSource.equals(ws); 4614 if (changed) { 4615 mWorkSource.set(ws); 4616 } 4617 } 4618 } 4619 if (changed && mHeld) { 4620 try { 4621 mService.updateWifiLockWorkSource(mBinder, mWorkSource); 4622 } catch (RemoteException e) { 4623 throw e.rethrowFromSystemServer(); 4624 } 4625 } 4626 } 4627 } 4628 toString()4629 public String toString() { 4630 String s1, s2, s3; 4631 synchronized (mBinder) { 4632 s1 = Integer.toHexString(System.identityHashCode(this)); 4633 s2 = mHeld ? "held; " : ""; 4634 if (mRefCounted) { 4635 s3 = "refcounted: refcount = " + mRefCount; 4636 } else { 4637 s3 = "not refcounted"; 4638 } 4639 return "WifiLock{ " + s1 + "; " + s2 + s3 + " }"; 4640 } 4641 } 4642 4643 @Override finalize()4644 protected void finalize() throws Throwable { 4645 super.finalize(); 4646 synchronized (mBinder) { 4647 if (mHeld) { 4648 try { 4649 mService.releaseWifiLock(mBinder); 4650 synchronized (WifiManager.this) { 4651 mActiveLockCount--; 4652 } 4653 } catch (RemoteException e) { 4654 throw e.rethrowFromSystemServer(); 4655 } 4656 } 4657 } 4658 } 4659 } 4660 4661 /** 4662 * Creates a new WifiLock. 4663 * 4664 * @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL_HIGH_PERF} 4665 * and {@link #WIFI_MODE_FULL_LOW_LATENCY} for descriptions of the types of Wi-Fi locks. 4666 * @param tag a tag for the WifiLock to identify it in debugging messages. This string is 4667 * never shown to the user under normal conditions, but should be descriptive 4668 * enough to identify your application and the specific WifiLock within it, if it 4669 * holds multiple WifiLocks. 4670 * 4671 * @return a new, unacquired WifiLock with the given tag. 4672 * 4673 * @see WifiLock 4674 */ createWifiLock(int lockType, String tag)4675 public WifiLock createWifiLock(int lockType, String tag) { 4676 return new WifiLock(lockType, tag); 4677 } 4678 4679 /** 4680 * Creates a new WifiLock. 4681 * 4682 * @param tag a tag for the WifiLock to identify it in debugging messages. This string is 4683 * never shown to the user under normal conditions, but should be descriptive 4684 * enough to identify your application and the specific WifiLock within it, if it 4685 * holds multiple WifiLocks. 4686 * 4687 * @return a new, unacquired WifiLock with the given tag. 4688 * 4689 * @see WifiLock 4690 * 4691 * @deprecated This API is non-functional. 4692 */ 4693 @Deprecated createWifiLock(String tag)4694 public WifiLock createWifiLock(String tag) { 4695 return new WifiLock(WIFI_MODE_FULL, tag); 4696 } 4697 4698 /** 4699 * Create a new MulticastLock 4700 * 4701 * @param tag a tag for the MulticastLock to identify it in debugging 4702 * messages. This string is never shown to the user under 4703 * normal conditions, but should be descriptive enough to 4704 * identify your application and the specific MulticastLock 4705 * within it, if it holds multiple MulticastLocks. 4706 * 4707 * @return a new, unacquired MulticastLock with the given tag. 4708 * 4709 * @see MulticastLock 4710 */ createMulticastLock(String tag)4711 public MulticastLock createMulticastLock(String tag) { 4712 return new MulticastLock(tag); 4713 } 4714 4715 /** 4716 * Allows an application to receive Wifi Multicast packets. 4717 * Normally the Wifi stack filters out packets not explicitly 4718 * addressed to this device. Acquring a MulticastLock will 4719 * cause the stack to receive packets addressed to multicast 4720 * addresses. Processing these extra packets can cause a noticeable 4721 * battery drain and should be disabled when not needed. 4722 */ 4723 public class MulticastLock { 4724 private String mTag; 4725 private final IBinder mBinder; 4726 private int mRefCount; 4727 private boolean mRefCounted; 4728 private boolean mHeld; 4729 MulticastLock(String tag)4730 private MulticastLock(String tag) { 4731 mTag = tag; 4732 mBinder = new Binder(); 4733 mRefCount = 0; 4734 mRefCounted = true; 4735 mHeld = false; 4736 } 4737 4738 /** 4739 * Locks Wifi Multicast on until {@link #release} is called. 4740 * 4741 * If this MulticastLock is reference-counted each call to 4742 * {@code acquire} will increment the reference count, and the 4743 * wifi interface will receive multicast packets as long as the 4744 * reference count is above zero. 4745 * 4746 * If this MulticastLock is not reference-counted, the first call to 4747 * {@code acquire} will turn on the multicast packets, but subsequent 4748 * calls will be ignored. Only one call to {@link #release} will 4749 * be required, regardless of the number of times that {@code acquire} 4750 * is called. 4751 * 4752 * Note that other applications may also lock Wifi Multicast on. 4753 * Only they can relinquish their lock. 4754 * 4755 * Also note that applications cannot leave Multicast locked on. 4756 * When an app exits or crashes, any Multicast locks will be released. 4757 */ acquire()4758 public void acquire() { 4759 synchronized (mBinder) { 4760 if (mRefCounted ? (++mRefCount == 1) : (!mHeld)) { 4761 try { 4762 mService.acquireMulticastLock(mBinder, mTag); 4763 synchronized (WifiManager.this) { 4764 if (mActiveLockCount >= MAX_ACTIVE_LOCKS) { 4765 mService.releaseMulticastLock(mTag); 4766 throw new UnsupportedOperationException( 4767 "Exceeded maximum number of wifi locks"); 4768 } 4769 mActiveLockCount++; 4770 } 4771 } catch (RemoteException e) { 4772 throw e.rethrowFromSystemServer(); 4773 } 4774 mHeld = true; 4775 } 4776 } 4777 } 4778 4779 /** 4780 * Unlocks Wifi Multicast, restoring the filter of packets 4781 * not addressed specifically to this device and saving power. 4782 * 4783 * If this MulticastLock is reference-counted, each call to 4784 * {@code release} will decrement the reference count, and the 4785 * multicast packets will only stop being received when the reference 4786 * count reaches zero. If the reference count goes below zero (that 4787 * is, if {@code release} is called a greater number of times than 4788 * {@link #acquire}), an exception is thrown. 4789 * 4790 * If this MulticastLock is not reference-counted, the first call to 4791 * {@code release} (after the radio was multicast locked using 4792 * {@link #acquire}) will unlock the multicast, and subsequent calls 4793 * will be ignored. 4794 * 4795 * Note that if any other Wifi Multicast Locks are still outstanding 4796 * this {@code release} call will not have an immediate effect. Only 4797 * when all applications have released all their Multicast Locks will 4798 * the Multicast filter be turned back on. 4799 * 4800 * Also note that when an app exits or crashes all of its Multicast 4801 * Locks will be automatically released. 4802 */ release()4803 public void release() { 4804 synchronized (mBinder) { 4805 if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { 4806 try { 4807 mService.releaseMulticastLock(mTag); 4808 synchronized (WifiManager.this) { 4809 mActiveLockCount--; 4810 } 4811 } catch (RemoteException e) { 4812 throw e.rethrowFromSystemServer(); 4813 } 4814 mHeld = false; 4815 } 4816 if (mRefCount < 0) { 4817 throw new RuntimeException("MulticastLock under-locked " 4818 + mTag); 4819 } 4820 } 4821 } 4822 4823 /** 4824 * Controls whether this is a reference-counted or non-reference- 4825 * counted MulticastLock. 4826 * 4827 * Reference-counted MulticastLocks keep track of the number of calls 4828 * to {@link #acquire} and {@link #release}, and only stop the 4829 * reception of multicast packets when every call to {@link #acquire} 4830 * has been balanced with a call to {@link #release}. Non-reference- 4831 * counted MulticastLocks allow the reception of multicast packets 4832 * whenever {@link #acquire} is called and stop accepting multicast 4833 * packets whenever {@link #release} is called. 4834 * 4835 * @param refCounted true if this MulticastLock should keep a reference 4836 * count 4837 */ setReferenceCounted(boolean refCounted)4838 public void setReferenceCounted(boolean refCounted) { 4839 mRefCounted = refCounted; 4840 } 4841 4842 /** 4843 * Checks whether this MulticastLock is currently held. 4844 * 4845 * @return true if this MulticastLock is held, false otherwise 4846 */ isHeld()4847 public boolean isHeld() { 4848 synchronized (mBinder) { 4849 return mHeld; 4850 } 4851 } 4852 toString()4853 public String toString() { 4854 String s1, s2, s3; 4855 synchronized (mBinder) { 4856 s1 = Integer.toHexString(System.identityHashCode(this)); 4857 s2 = mHeld ? "held; " : ""; 4858 if (mRefCounted) { 4859 s3 = "refcounted: refcount = " + mRefCount; 4860 } else { 4861 s3 = "not refcounted"; 4862 } 4863 return "MulticastLock{ " + s1 + "; " + s2 + s3 + " }"; 4864 } 4865 } 4866 4867 @Override finalize()4868 protected void finalize() throws Throwable { 4869 super.finalize(); 4870 setReferenceCounted(false); 4871 release(); 4872 } 4873 } 4874 4875 /** 4876 * Check multicast filter status. 4877 * 4878 * @return true if multicast packets are allowed. 4879 * 4880 * @hide pending API council approval 4881 */ isMulticastEnabled()4882 public boolean isMulticastEnabled() { 4883 try { 4884 return mService.isMulticastEnabled(); 4885 } catch (RemoteException e) { 4886 throw e.rethrowFromSystemServer(); 4887 } 4888 } 4889 4890 /** 4891 * Initialize the multicast filtering to 'on' 4892 * @hide no intent to publish 4893 */ 4894 @UnsupportedAppUsage initializeMulticastFiltering()4895 public boolean initializeMulticastFiltering() { 4896 try { 4897 mService.initializeMulticastFiltering(); 4898 return true; 4899 } catch (RemoteException e) { 4900 throw e.rethrowFromSystemServer(); 4901 } 4902 } 4903 4904 /** 4905 * Set Wi-Fi verbose logging level from developer settings. 4906 * 4907 * @param enable true to enable verbose logging, false to disable. 4908 * 4909 * @hide 4910 */ 4911 @SystemApi 4912 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) setVerboseLoggingEnabled(boolean enable)4913 public void setVerboseLoggingEnabled(boolean enable) { 4914 enableVerboseLogging(enable ? 1 : 0); 4915 } 4916 4917 /** @hide */ 4918 @UnsupportedAppUsage( 4919 maxTargetSdk = Build.VERSION_CODES.Q, 4920 publicAlternatives = "Use {@code #setVerboseLoggingEnabled(boolean)} instead." 4921 ) 4922 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) enableVerboseLogging(int verbose)4923 public void enableVerboseLogging (int verbose) { 4924 try { 4925 mService.enableVerboseLogging(verbose); 4926 } catch (Exception e) { 4927 //ignore any failure here 4928 Log.e(TAG, "enableVerboseLogging " + e.toString()); 4929 } 4930 } 4931 4932 /** 4933 * Get the persisted Wi-Fi verbose logging level, set by 4934 * {@link #setVerboseLoggingEnabled(boolean)}. 4935 * No permissions are required to call this method. 4936 * 4937 * @return true to indicate that verbose logging is enabled, false to indicate that verbose 4938 * logging is disabled. 4939 * 4940 * @hide 4941 */ 4942 @SystemApi isVerboseLoggingEnabled()4943 public boolean isVerboseLoggingEnabled() { 4944 return getVerboseLoggingLevel() > 0; 4945 } 4946 4947 /** @hide */ 4948 // TODO(b/145484145): remove once SUW stops calling this via reflection 4949 @UnsupportedAppUsage( 4950 maxTargetSdk = Build.VERSION_CODES.Q, 4951 publicAlternatives = "Use {@code #isVerboseLoggingEnabled()} instead." 4952 ) getVerboseLoggingLevel()4953 public int getVerboseLoggingLevel() { 4954 try { 4955 return mService.getVerboseLoggingLevel(); 4956 } catch (RemoteException e) { 4957 throw e.rethrowFromSystemServer(); 4958 } 4959 } 4960 4961 /** 4962 * Removes all saved Wi-Fi networks, Passpoint configurations, ephemeral networks, Network 4963 * Requests, and Network Suggestions. 4964 * 4965 * @hide 4966 */ 4967 @SystemApi 4968 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) factoryReset()4969 public void factoryReset() { 4970 try { 4971 mService.factoryReset(mContext.getOpPackageName()); 4972 } catch (RemoteException e) { 4973 throw e.rethrowFromSystemServer(); 4974 } 4975 } 4976 4977 /** 4978 * Get {@link Network} object of current wifi network, or null if not connected. 4979 * @hide 4980 */ 4981 @Nullable 4982 @SystemApi 4983 @RequiresPermission(anyOf = { 4984 android.Manifest.permission.NETWORK_SETTINGS, 4985 android.Manifest.permission.NETWORK_SETUP_WIZARD 4986 }) getCurrentNetwork()4987 public Network getCurrentNetwork() { 4988 try { 4989 return mService.getCurrentNetwork(); 4990 } catch (RemoteException e) { 4991 throw e.rethrowFromSystemServer(); 4992 } 4993 } 4994 4995 /** 4996 * Deprecated 4997 * returns false 4998 * @hide 4999 * @deprecated 5000 */ setEnableAutoJoinWhenAssociated(boolean enabled)5001 public boolean setEnableAutoJoinWhenAssociated(boolean enabled) { 5002 return false; 5003 } 5004 5005 /** 5006 * Deprecated 5007 * returns false 5008 * @hide 5009 * @deprecated 5010 */ getEnableAutoJoinWhenAssociated()5011 public boolean getEnableAutoJoinWhenAssociated() { 5012 return false; 5013 } 5014 5015 /** 5016 * Returns a byte stream representing the data that needs to be backed up to save the 5017 * current Wifi state. 5018 * This Wifi state can be restored by calling {@link #restoreBackupData(byte[])}. 5019 * @hide 5020 */ 5021 @NonNull 5022 @SystemApi 5023 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) retrieveBackupData()5024 public byte[] retrieveBackupData() { 5025 try { 5026 return mService.retrieveBackupData(); 5027 } catch (RemoteException e) { 5028 throw e.rethrowFromSystemServer(); 5029 } 5030 } 5031 5032 /** 5033 * Restore state from the backed up data. 5034 * @param data byte stream in the same format produced by {@link #retrieveBackupData()} 5035 * @hide 5036 */ 5037 @SystemApi 5038 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) restoreBackupData(@onNull byte[] data)5039 public void restoreBackupData(@NonNull byte[] data) { 5040 try { 5041 mService.restoreBackupData(data); 5042 } catch (RemoteException e) { 5043 throw e.rethrowFromSystemServer(); 5044 } 5045 } 5046 5047 /** 5048 * Returns a byte stream representing the data that needs to be backed up to save the 5049 * current soft ap config data. 5050 * 5051 * This soft ap config can be restored by calling {@link #restoreSoftApBackupData(byte[])} 5052 * @hide 5053 */ 5054 @NonNull 5055 @SystemApi 5056 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) retrieveSoftApBackupData()5057 public byte[] retrieveSoftApBackupData() { 5058 try { 5059 return mService.retrieveSoftApBackupData(); 5060 } catch (RemoteException e) { 5061 throw e.rethrowFromSystemServer(); 5062 } 5063 } 5064 5065 /** 5066 * Returns soft ap config from the backed up data or null if data is invalid. 5067 * @param data byte stream in the same format produced by {@link #retrieveSoftApBackupData()} 5068 * 5069 * @hide 5070 */ 5071 @Nullable 5072 @SystemApi 5073 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) restoreSoftApBackupData(@onNull byte[] data)5074 public SoftApConfiguration restoreSoftApBackupData(@NonNull byte[] data) { 5075 try { 5076 return mService.restoreSoftApBackupData(data); 5077 } catch (RemoteException e) { 5078 throw e.rethrowFromSystemServer(); 5079 } 5080 } 5081 5082 /** 5083 * Restore state from the older version of back up data. 5084 * The old backup data was essentially a backup of wpa_supplicant.conf 5085 * and ipconfig.txt file. 5086 * @param supplicantData bytes representing wpa_supplicant.conf 5087 * @param ipConfigData bytes representing ipconfig.txt 5088 * @hide 5089 */ 5090 @SystemApi 5091 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) restoreSupplicantBackupData( @onNull byte[] supplicantData, @NonNull byte[] ipConfigData)5092 public void restoreSupplicantBackupData( 5093 @NonNull byte[] supplicantData, @NonNull byte[] ipConfigData) { 5094 try { 5095 mService.restoreSupplicantBackupData(supplicantData, ipConfigData); 5096 } catch (RemoteException e) { 5097 throw e.rethrowFromSystemServer(); 5098 } 5099 } 5100 5101 /** 5102 * Start subscription provisioning flow 5103 * 5104 * @param provider {@link OsuProvider} to provision with 5105 * @param executor the Executor on which to run the callback. 5106 * @param callback {@link ProvisioningCallback} for updates regarding provisioning flow 5107 * @hide 5108 */ 5109 @SystemApi 5110 @RequiresPermission(anyOf = { 5111 android.Manifest.permission.NETWORK_SETTINGS, 5112 android.Manifest.permission.NETWORK_SETUP_WIZARD 5113 }) startSubscriptionProvisioning(@onNull OsuProvider provider, @NonNull @CallbackExecutor Executor executor, @NonNull ProvisioningCallback callback)5114 public void startSubscriptionProvisioning(@NonNull OsuProvider provider, 5115 @NonNull @CallbackExecutor Executor executor, @NonNull ProvisioningCallback callback) { 5116 // Verify arguments 5117 if (executor == null) { 5118 throw new IllegalArgumentException("executor must not be null"); 5119 } 5120 if (callback == null) { 5121 throw new IllegalArgumentException("callback must not be null"); 5122 } 5123 try { 5124 mService.startSubscriptionProvisioning(provider, 5125 new ProvisioningCallbackProxy(executor, callback)); 5126 } catch (RemoteException e) { 5127 throw e.rethrowFromSystemServer(); 5128 } 5129 } 5130 5131 /** 5132 * Helper class to support OSU Provisioning callbacks 5133 */ 5134 private static class ProvisioningCallbackProxy extends IProvisioningCallback.Stub { 5135 private final Executor mExecutor; 5136 private final ProvisioningCallback mCallback; 5137 ProvisioningCallbackProxy(Executor executor, ProvisioningCallback callback)5138 ProvisioningCallbackProxy(Executor executor, ProvisioningCallback callback) { 5139 mExecutor = executor; 5140 mCallback = callback; 5141 } 5142 5143 @Override onProvisioningStatus(int status)5144 public void onProvisioningStatus(int status) { 5145 mExecutor.execute(() -> mCallback.onProvisioningStatus(status)); 5146 } 5147 5148 @Override onProvisioningFailure(int status)5149 public void onProvisioningFailure(int status) { 5150 mExecutor.execute(() -> mCallback.onProvisioningFailure(status)); 5151 } 5152 5153 @Override onProvisioningComplete()5154 public void onProvisioningComplete() { 5155 mExecutor.execute(() -> mCallback.onProvisioningComplete()); 5156 } 5157 } 5158 5159 /** 5160 * Interface for Traffic state callback. Should be extended by applications and set when 5161 * calling {@link #registerTrafficStateCallback(Executor, WifiManager.TrafficStateCallback)}. 5162 * @hide 5163 */ 5164 @SystemApi 5165 public interface TrafficStateCallback { 5166 /** @hide */ 5167 @Retention(RetentionPolicy.SOURCE) 5168 @IntDef(prefix = {"DATA_ACTIVITY_"}, value = { 5169 DATA_ACTIVITY_NONE, 5170 DATA_ACTIVITY_IN, 5171 DATA_ACTIVITY_OUT, 5172 DATA_ACTIVITY_INOUT}) 5173 @interface DataActivity {} 5174 5175 // Lowest bit indicates data reception and the second lowest bit indicates data transmitted 5176 /** No data in or out */ 5177 int DATA_ACTIVITY_NONE = 0x00; 5178 /** Data in, no data out */ 5179 int DATA_ACTIVITY_IN = 0x01; 5180 /** Data out, no data in */ 5181 int DATA_ACTIVITY_OUT = 0x02; 5182 /** Data in and out */ 5183 int DATA_ACTIVITY_INOUT = 0x03; 5184 5185 /** 5186 * Callback invoked to inform clients about the current traffic state. 5187 * 5188 * @param state One of the values: {@link #DATA_ACTIVITY_NONE}, {@link #DATA_ACTIVITY_IN}, 5189 * {@link #DATA_ACTIVITY_OUT} & {@link #DATA_ACTIVITY_INOUT}. 5190 */ onStateChanged(@ataActivity int state)5191 void onStateChanged(@DataActivity int state); 5192 } 5193 5194 /** 5195 * Callback proxy for TrafficStateCallback objects. 5196 * 5197 * @hide 5198 */ 5199 private class TrafficStateCallbackProxy extends ITrafficStateCallback.Stub { 5200 private final Executor mExecutor; 5201 private final TrafficStateCallback mCallback; 5202 TrafficStateCallbackProxy(Executor executor, TrafficStateCallback callback)5203 TrafficStateCallbackProxy(Executor executor, TrafficStateCallback callback) { 5204 mExecutor = executor; 5205 mCallback = callback; 5206 } 5207 5208 @Override onStateChanged(int state)5209 public void onStateChanged(int state) { 5210 if (mVerboseLoggingEnabled) { 5211 Log.v(TAG, "TrafficStateCallbackProxy: onStateChanged state=" + state); 5212 } 5213 Binder.clearCallingIdentity(); 5214 mExecutor.execute(() -> { 5215 mCallback.onStateChanged(state); 5216 }); 5217 } 5218 } 5219 5220 /** 5221 * Registers a callback for monitoring traffic state. See {@link TrafficStateCallback}. These 5222 * callbacks will be invoked periodically by platform to inform clients about the current 5223 * traffic state. Caller can unregister a previously registered callback using 5224 * {@link #unregisterTrafficStateCallback(TrafficStateCallback)} 5225 * <p> 5226 * Applications should have the 5227 * {@link android.Manifest.permission#NETWORK_SETTINGS NETWORK_SETTINGS} permission. Callers 5228 * without the permission will trigger a {@link java.lang.SecurityException}. 5229 * <p> 5230 * 5231 * @param executor The Executor on whose thread to execute the callbacks of the {@code callback} 5232 * object. 5233 * @param callback Callback for traffic state events 5234 * @hide 5235 */ 5236 @SystemApi 5237 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) registerTrafficStateCallback(@onNull @allbackExecutor Executor executor, @NonNull TrafficStateCallback callback)5238 public void registerTrafficStateCallback(@NonNull @CallbackExecutor Executor executor, 5239 @NonNull TrafficStateCallback callback) { 5240 if (executor == null) throw new IllegalArgumentException("executor cannot be null"); 5241 if (callback == null) throw new IllegalArgumentException("callback cannot be null"); 5242 Log.v(TAG, "registerTrafficStateCallback: callback=" + callback + ", executor=" + executor); 5243 5244 Binder binder = new Binder(); 5245 try { 5246 mService.registerTrafficStateCallback( 5247 binder, new TrafficStateCallbackProxy(executor, callback), callback.hashCode()); 5248 } catch (RemoteException e) { 5249 throw e.rethrowFromSystemServer(); 5250 } 5251 } 5252 5253 /** 5254 * Allow callers to unregister a previously registered callback. After calling this method, 5255 * applications will no longer receive traffic state notifications. 5256 * 5257 * @param callback Callback to unregister for traffic state events 5258 * @hide 5259 */ 5260 @SystemApi 5261 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) unregisterTrafficStateCallback(@onNull TrafficStateCallback callback)5262 public void unregisterTrafficStateCallback(@NonNull TrafficStateCallback callback) { 5263 if (callback == null) throw new IllegalArgumentException("callback cannot be null"); 5264 Log.v(TAG, "unregisterTrafficStateCallback: callback=" + callback); 5265 5266 try { 5267 mService.unregisterTrafficStateCallback(callback.hashCode()); 5268 } catch (RemoteException e) { 5269 throw e.rethrowFromSystemServer(); 5270 } 5271 } 5272 5273 /** 5274 * Helper method to update the local verbose logging flag based on the verbose logging 5275 * level from wifi service. 5276 */ updateVerboseLoggingEnabledFromService()5277 private void updateVerboseLoggingEnabledFromService() { 5278 mVerboseLoggingEnabled = isVerboseLoggingEnabled(); 5279 } 5280 5281 /** 5282 * @return true if this device supports WPA3-Personal SAE 5283 */ isWpa3SaeSupported()5284 public boolean isWpa3SaeSupported() { 5285 return isFeatureSupported(WIFI_FEATURE_WPA3_SAE); 5286 } 5287 5288 /** 5289 * @return true if this device supports WPA3-Enterprise Suite-B-192 5290 */ isWpa3SuiteBSupported()5291 public boolean isWpa3SuiteBSupported() { 5292 return isFeatureSupported(WIFI_FEATURE_WPA3_SUITE_B); 5293 } 5294 5295 /** 5296 * @return true if this device supports Wi-Fi Enhanced Open (OWE) 5297 */ isEnhancedOpenSupported()5298 public boolean isEnhancedOpenSupported() { 5299 return isFeatureSupported(WIFI_FEATURE_OWE); 5300 } 5301 5302 /** 5303 * Wi-Fi Easy Connect (DPP) introduces standardized mechanisms to simplify the provisioning and 5304 * configuration of Wi-Fi devices. 5305 * For more details, visit <a href="https://www.wi-fi.org/">https://www.wi-fi.org/</a> and 5306 * search for "Easy Connect" or "Device Provisioning Protocol specification". 5307 * 5308 * @return true if this device supports Wi-Fi Easy-connect (Device Provisioning Protocol) 5309 */ isEasyConnectSupported()5310 public boolean isEasyConnectSupported() { 5311 return isFeatureSupported(WIFI_FEATURE_DPP); 5312 } 5313 5314 /** 5315 * @return true if this device supports WAPI. 5316 */ isWapiSupported()5317 public boolean isWapiSupported() { 5318 return isFeatureSupported(WIFI_FEATURE_WAPI); 5319 } 5320 5321 /** 5322 * Gets the factory Wi-Fi MAC addresses. 5323 * @return Array of String representing Wi-Fi MAC addresses sorted lexically or an empty Array 5324 * if failed. 5325 * @hide 5326 */ 5327 @NonNull 5328 @SystemApi 5329 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) getFactoryMacAddresses()5330 public String[] getFactoryMacAddresses() { 5331 try { 5332 return mService.getFactoryMacAddresses(); 5333 } catch (RemoteException e) { 5334 throw e.rethrowFromSystemServer(); 5335 } 5336 } 5337 5338 /** @hide */ 5339 @Retention(RetentionPolicy.SOURCE) 5340 @IntDef(prefix = {"DEVICE_MOBILITY_STATE_"}, value = { 5341 DEVICE_MOBILITY_STATE_UNKNOWN, 5342 DEVICE_MOBILITY_STATE_HIGH_MVMT, 5343 DEVICE_MOBILITY_STATE_LOW_MVMT, 5344 DEVICE_MOBILITY_STATE_STATIONARY}) 5345 public @interface DeviceMobilityState {} 5346 5347 /** 5348 * Unknown device mobility state 5349 * 5350 * @see #setDeviceMobilityState(int) 5351 * 5352 * @hide 5353 */ 5354 @SystemApi 5355 public static final int DEVICE_MOBILITY_STATE_UNKNOWN = 0; 5356 5357 /** 5358 * High movement device mobility state. 5359 * e.g. on a bike, in a motor vehicle 5360 * 5361 * @see #setDeviceMobilityState(int) 5362 * 5363 * @hide 5364 */ 5365 @SystemApi 5366 public static final int DEVICE_MOBILITY_STATE_HIGH_MVMT = 1; 5367 5368 /** 5369 * Low movement device mobility state. 5370 * e.g. walking, running 5371 * 5372 * @see #setDeviceMobilityState(int) 5373 * 5374 * @hide 5375 */ 5376 @SystemApi 5377 public static final int DEVICE_MOBILITY_STATE_LOW_MVMT = 2; 5378 5379 /** 5380 * Stationary device mobility state 5381 * 5382 * @see #setDeviceMobilityState(int) 5383 * 5384 * @hide 5385 */ 5386 @SystemApi 5387 public static final int DEVICE_MOBILITY_STATE_STATIONARY = 3; 5388 5389 /** 5390 * Updates the device mobility state. Wifi uses this information to adjust the interval between 5391 * Wifi scans in order to balance power consumption with scan accuracy. 5392 * The default mobility state when the device boots is {@link #DEVICE_MOBILITY_STATE_UNKNOWN}. 5393 * This API should be called whenever there is a change in the mobility state. 5394 * @param state the updated device mobility state 5395 * @hide 5396 */ 5397 @SystemApi 5398 @RequiresPermission(android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE) setDeviceMobilityState(@eviceMobilityState int state)5399 public void setDeviceMobilityState(@DeviceMobilityState int state) { 5400 try { 5401 mService.setDeviceMobilityState(state); 5402 } catch (RemoteException e) { 5403 throw e.rethrowFromSystemServer(); 5404 } 5405 } 5406 5407 /* Easy Connect - AKA Device Provisioning Protocol (DPP) */ 5408 5409 /** 5410 * Easy Connect Network role: Station. 5411 * 5412 * @hide 5413 */ 5414 @SystemApi 5415 public static final int EASY_CONNECT_NETWORK_ROLE_STA = 0; 5416 5417 /** 5418 * Easy Connect Network role: Access Point. 5419 * 5420 * @hide 5421 */ 5422 @SystemApi 5423 public static final int EASY_CONNECT_NETWORK_ROLE_AP = 1; 5424 5425 /** @hide */ 5426 @IntDef(prefix = {"EASY_CONNECT_NETWORK_ROLE_"}, value = { 5427 EASY_CONNECT_NETWORK_ROLE_STA, 5428 EASY_CONNECT_NETWORK_ROLE_AP, 5429 }) 5430 @Retention(RetentionPolicy.SOURCE) 5431 public @interface EasyConnectNetworkRole { 5432 } 5433 5434 /** 5435 * Start Easy Connect (DPP) in Configurator-Initiator role. The current device will initiate 5436 * Easy Connect bootstrapping with a peer, and configure the peer with the SSID and password of 5437 * the specified network using the Easy Connect protocol on an encrypted link. 5438 * 5439 * @param enrolleeUri URI of the Enrollee obtained separately (e.g. QR code scanning) 5440 * @param selectedNetworkId Selected network ID to be sent to the peer 5441 * @param enrolleeNetworkRole The network role of the enrollee 5442 * @param callback Callback for status updates 5443 * @param executor The Executor on which to run the callback. 5444 * @hide 5445 */ 5446 @SystemApi 5447 @RequiresPermission(anyOf = { 5448 android.Manifest.permission.NETWORK_SETTINGS, 5449 android.Manifest.permission.NETWORK_SETUP_WIZARD}) startEasyConnectAsConfiguratorInitiator(@onNull String enrolleeUri, int selectedNetworkId, @EasyConnectNetworkRole int enrolleeNetworkRole, @NonNull @CallbackExecutor Executor executor, @NonNull EasyConnectStatusCallback callback)5450 public void startEasyConnectAsConfiguratorInitiator(@NonNull String enrolleeUri, 5451 int selectedNetworkId, @EasyConnectNetworkRole int enrolleeNetworkRole, 5452 @NonNull @CallbackExecutor Executor executor, 5453 @NonNull EasyConnectStatusCallback callback) { 5454 Binder binder = new Binder(); 5455 try { 5456 mService.startDppAsConfiguratorInitiator(binder, enrolleeUri, selectedNetworkId, 5457 enrolleeNetworkRole, new EasyConnectCallbackProxy(executor, callback)); 5458 } catch (RemoteException e) { 5459 throw e.rethrowFromSystemServer(); 5460 } 5461 } 5462 5463 /** 5464 * Start Easy Connect (DPP) in Enrollee-Initiator role. The current device will initiate Easy 5465 * Connect bootstrapping with a peer, and receive the SSID and password from the peer 5466 * configurator. 5467 * 5468 * @param configuratorUri URI of the Configurator obtained separately (e.g. QR code scanning) 5469 * @param callback Callback for status updates 5470 * @param executor The Executor on which to run the callback. 5471 * @hide 5472 */ 5473 @SystemApi 5474 @RequiresPermission(anyOf = { 5475 android.Manifest.permission.NETWORK_SETTINGS, 5476 android.Manifest.permission.NETWORK_SETUP_WIZARD}) startEasyConnectAsEnrolleeInitiator(@onNull String configuratorUri, @NonNull @CallbackExecutor Executor executor, @NonNull EasyConnectStatusCallback callback)5477 public void startEasyConnectAsEnrolleeInitiator(@NonNull String configuratorUri, 5478 @NonNull @CallbackExecutor Executor executor, 5479 @NonNull EasyConnectStatusCallback callback) { 5480 Binder binder = new Binder(); 5481 try { 5482 mService.startDppAsEnrolleeInitiator(binder, configuratorUri, 5483 new EasyConnectCallbackProxy(executor, callback)); 5484 } catch (RemoteException e) { 5485 throw e.rethrowFromSystemServer(); 5486 } 5487 } 5488 5489 /** 5490 * Stop or abort a current Easy Connect (DPP) session. This call, once processed, will 5491 * terminate any ongoing transaction, and clean up all associated resources. Caller should not 5492 * expect any callbacks once this call is made. However, due to the asynchronous nature of 5493 * this call, a callback may be fired if it was already pending in the queue. 5494 * 5495 * @hide 5496 */ 5497 @SystemApi 5498 @RequiresPermission(anyOf = { 5499 android.Manifest.permission.NETWORK_SETTINGS, 5500 android.Manifest.permission.NETWORK_SETUP_WIZARD}) stopEasyConnectSession()5501 public void stopEasyConnectSession() { 5502 try { 5503 /* Request lower layers to stop/abort and clear resources */ 5504 mService.stopDppSession(); 5505 } catch (RemoteException e) { 5506 throw e.rethrowFromSystemServer(); 5507 } 5508 } 5509 5510 /** 5511 * Helper class to support Easy Connect (DPP) callbacks 5512 * 5513 * @hide 5514 */ 5515 private static class EasyConnectCallbackProxy extends IDppCallback.Stub { 5516 private final Executor mExecutor; 5517 private final EasyConnectStatusCallback mEasyConnectStatusCallback; 5518 EasyConnectCallbackProxy(Executor executor, EasyConnectStatusCallback easyConnectStatusCallback)5519 EasyConnectCallbackProxy(Executor executor, 5520 EasyConnectStatusCallback easyConnectStatusCallback) { 5521 mExecutor = executor; 5522 mEasyConnectStatusCallback = easyConnectStatusCallback; 5523 } 5524 5525 @Override onSuccessConfigReceived(int newNetworkId)5526 public void onSuccessConfigReceived(int newNetworkId) { 5527 Log.d(TAG, "Easy Connect onSuccessConfigReceived callback"); 5528 Binder.clearCallingIdentity(); 5529 mExecutor.execute(() -> { 5530 mEasyConnectStatusCallback.onEnrolleeSuccess(newNetworkId); 5531 }); 5532 } 5533 5534 @Override onSuccess(int status)5535 public void onSuccess(int status) { 5536 Log.d(TAG, "Easy Connect onSuccess callback"); 5537 Binder.clearCallingIdentity(); 5538 mExecutor.execute(() -> { 5539 mEasyConnectStatusCallback.onConfiguratorSuccess(status); 5540 }); 5541 } 5542 5543 @Override onFailure(int status, String ssid, String channelList, int[] operatingClassArray)5544 public void onFailure(int status, String ssid, String channelList, 5545 int[] operatingClassArray) { 5546 Log.d(TAG, "Easy Connect onFailure callback"); 5547 Binder.clearCallingIdentity(); 5548 mExecutor.execute(() -> { 5549 SparseArray<int[]> channelListArray = parseDppChannelList(channelList); 5550 mEasyConnectStatusCallback.onFailure(status, ssid, channelListArray, 5551 operatingClassArray); 5552 }); 5553 } 5554 5555 @Override onProgress(int status)5556 public void onProgress(int status) { 5557 Log.d(TAG, "Easy Connect onProgress callback"); 5558 Binder.clearCallingIdentity(); 5559 mExecutor.execute(() -> { 5560 mEasyConnectStatusCallback.onProgress(status); 5561 }); 5562 } 5563 } 5564 5565 /** 5566 * Interface for Wi-Fi usability statistics listener. Should be implemented by applications and 5567 * set when calling {@link WifiManager#addOnWifiUsabilityStatsListener(Executor, 5568 * OnWifiUsabilityStatsListener)}. 5569 * 5570 * @hide 5571 */ 5572 @SystemApi 5573 public interface OnWifiUsabilityStatsListener { 5574 /** 5575 * Called when Wi-Fi usability statistics is updated. 5576 * 5577 * @param seqNum The sequence number of statistics, used to derive the timing of updated 5578 * Wi-Fi usability statistics, set by framework and incremented by one after 5579 * each update. 5580 * @param isSameBssidAndFreq The flag to indicate whether the BSSID and the frequency of 5581 * network stays the same or not relative to the last update of 5582 * Wi-Fi usability stats. 5583 * @param stats The updated Wi-Fi usability statistics. 5584 */ onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq, @NonNull WifiUsabilityStatsEntry stats)5585 void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq, 5586 @NonNull WifiUsabilityStatsEntry stats); 5587 } 5588 5589 /** 5590 * Adds a listener for Wi-Fi usability statistics. See {@link OnWifiUsabilityStatsListener}. 5591 * Multiple listeners can be added. Callers will be invoked periodically by framework to 5592 * inform clients about the current Wi-Fi usability statistics. Callers can remove a previously 5593 * added listener using {@link removeOnWifiUsabilityStatsListener}. 5594 * 5595 * @param executor The executor on which callback will be invoked. 5596 * @param listener Listener for Wifi usability statistics. 5597 * 5598 * @hide 5599 */ 5600 @SystemApi 5601 @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) addOnWifiUsabilityStatsListener(@onNull @allbackExecutor Executor executor, @NonNull OnWifiUsabilityStatsListener listener)5602 public void addOnWifiUsabilityStatsListener(@NonNull @CallbackExecutor Executor executor, 5603 @NonNull OnWifiUsabilityStatsListener listener) { 5604 if (executor == null) throw new IllegalArgumentException("executor cannot be null"); 5605 if (listener == null) throw new IllegalArgumentException("listener cannot be null"); 5606 if (mVerboseLoggingEnabled) { 5607 Log.v(TAG, "addOnWifiUsabilityStatsListener: listener=" + listener); 5608 } 5609 try { 5610 mService.addOnWifiUsabilityStatsListener(new Binder(), 5611 new IOnWifiUsabilityStatsListener.Stub() { 5612 @Override 5613 public void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq, 5614 WifiUsabilityStatsEntry stats) { 5615 if (mVerboseLoggingEnabled) { 5616 Log.v(TAG, "OnWifiUsabilityStatsListener: " 5617 + "onWifiUsabilityStats: seqNum=" + seqNum); 5618 } 5619 Binder.clearCallingIdentity(); 5620 executor.execute(() -> listener.onWifiUsabilityStats( 5621 seqNum, isSameBssidAndFreq, stats)); 5622 } 5623 }, 5624 listener.hashCode() 5625 ); 5626 } catch (RemoteException e) { 5627 throw e.rethrowFromSystemServer(); 5628 } 5629 } 5630 5631 /** 5632 * Allow callers to remove a previously registered listener. After calling this method, 5633 * applications will no longer receive Wi-Fi usability statistics. 5634 * 5635 * @param listener Listener to remove the Wi-Fi usability statistics. 5636 * 5637 * @hide 5638 */ 5639 @SystemApi 5640 @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) removeOnWifiUsabilityStatsListener(@onNull OnWifiUsabilityStatsListener listener)5641 public void removeOnWifiUsabilityStatsListener(@NonNull OnWifiUsabilityStatsListener listener) { 5642 if (listener == null) throw new IllegalArgumentException("listener cannot be null"); 5643 if (mVerboseLoggingEnabled) { 5644 Log.v(TAG, "removeOnWifiUsabilityStatsListener: listener=" + listener); 5645 } 5646 try { 5647 mService.removeOnWifiUsabilityStatsListener(listener.hashCode()); 5648 } catch (RemoteException e) { 5649 throw e.rethrowFromSystemServer(); 5650 } 5651 } 5652 5653 /** 5654 * Provide a Wi-Fi usability score information to be recorded (but not acted upon) by the 5655 * framework. The Wi-Fi usability score is derived from {@link OnWifiUsabilityStatsListener} 5656 * where a score is matched to Wi-Fi usability statistics using the sequence number. The score 5657 * is used to quantify whether Wi-Fi is usable in a future time. 5658 * 5659 * @param seqNum Sequence number of the Wi-Fi usability score. 5660 * @param score The Wi-Fi usability score, expected range: [0, 100]. 5661 * @param predictionHorizonSec Prediction horizon of the Wi-Fi usability score in second, 5662 * expected range: [0, 30]. 5663 * 5664 * @hide 5665 */ 5666 @SystemApi 5667 @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec)5668 public void updateWifiUsabilityScore(int seqNum, int score, int predictionHorizonSec) { 5669 try { 5670 mService.updateWifiUsabilityScore(seqNum, score, predictionHorizonSec); 5671 } catch (RemoteException e) { 5672 throw e.rethrowFromSystemServer(); 5673 } 5674 } 5675 5676 /** 5677 * Abstract class for scan results callback. Should be extended by applications and set when 5678 * calling {@link WifiManager#registerScanResultsCallback(Executor, ScanResultsCallback)}. 5679 */ 5680 public abstract static class ScanResultsCallback { 5681 private final ScanResultsCallbackProxy mScanResultsCallbackProxy; 5682 ScanResultsCallback()5683 public ScanResultsCallback() { 5684 mScanResultsCallbackProxy = new ScanResultsCallbackProxy(); 5685 } 5686 5687 /** 5688 * Called when new scan results are available. 5689 * Clients should use {@link WifiManager#getScanResults()} to get the scan results. 5690 */ onScanResultsAvailable()5691 public abstract void onScanResultsAvailable(); 5692 getProxy()5693 /*package*/ @NonNull ScanResultsCallbackProxy getProxy() { 5694 return mScanResultsCallbackProxy; 5695 } 5696 5697 private static class ScanResultsCallbackProxy extends IScanResultsCallback.Stub { 5698 private final Object mLock = new Object(); 5699 @Nullable @GuardedBy("mLock") private Executor mExecutor; 5700 @Nullable @GuardedBy("mLock") private ScanResultsCallback mCallback; 5701 ScanResultsCallbackProxy()5702 ScanResultsCallbackProxy() { 5703 mCallback = null; 5704 mExecutor = null; 5705 } 5706 initProxy(@onNull Executor executor, @NonNull ScanResultsCallback callback)5707 /*package*/ void initProxy(@NonNull Executor executor, 5708 @NonNull ScanResultsCallback callback) { 5709 synchronized (mLock) { 5710 mExecutor = executor; 5711 mCallback = callback; 5712 } 5713 } 5714 cleanUpProxy()5715 /*package*/ void cleanUpProxy() { 5716 synchronized (mLock) { 5717 mExecutor = null; 5718 mCallback = null; 5719 } 5720 } 5721 5722 @Override onScanResultsAvailable()5723 public void onScanResultsAvailable() { 5724 ScanResultsCallback callback; 5725 Executor executor; 5726 synchronized (mLock) { 5727 executor = mExecutor; 5728 callback = mCallback; 5729 } 5730 if (callback == null || executor == null) { 5731 return; 5732 } 5733 Binder.clearCallingIdentity(); 5734 executor.execute(callback::onScanResultsAvailable); 5735 } 5736 } 5737 5738 } 5739 5740 /** 5741 * Register a callback for Scan Results. See {@link ScanResultsCallback}. 5742 * Caller will receive the event when scan results are available. 5743 * Caller should use {@link WifiManager#getScanResults()} requires 5744 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} to get the scan results. 5745 * Caller can remove a previously registered callback using 5746 * {@link WifiManager#unregisterScanResultsCallback(ScanResultsCallback)} 5747 * Same caller can add multiple listeners. 5748 * <p> 5749 * Applications should have the 5750 * {@link android.Manifest.permission#ACCESS_WIFI_STATE} permission. Callers 5751 * without the permission will trigger a {@link java.lang.SecurityException}. 5752 * <p> 5753 * 5754 * @param executor The executor to execute the callback of the {@code callback} object. 5755 * @param callback callback for Scan Results events 5756 */ 5757 5758 @RequiresPermission(ACCESS_WIFI_STATE) registerScanResultsCallback(@onNull @allbackExecutor Executor executor, @NonNull ScanResultsCallback callback)5759 public void registerScanResultsCallback(@NonNull @CallbackExecutor Executor executor, 5760 @NonNull ScanResultsCallback callback) { 5761 if (executor == null) throw new IllegalArgumentException("executor cannot be null"); 5762 if (callback == null) throw new IllegalArgumentException("callback cannot be null"); 5763 5764 Log.v(TAG, "registerScanResultsCallback: callback=" + callback 5765 + ", executor=" + executor); 5766 ScanResultsCallback.ScanResultsCallbackProxy proxy = callback.getProxy(); 5767 proxy.initProxy(executor, callback); 5768 try { 5769 mService.registerScanResultsCallback(proxy); 5770 } catch (RemoteException e) { 5771 throw e.rethrowFromSystemServer(); 5772 } 5773 } 5774 5775 /** 5776 * Allow callers to unregister a previously registered callback. After calling this method, 5777 * applications will no longer receive Scan Results events. 5778 * 5779 * @param callback callback to unregister for Scan Results events 5780 */ 5781 @RequiresPermission(ACCESS_WIFI_STATE) unregisterScanResultsCallback(@onNull ScanResultsCallback callback)5782 public void unregisterScanResultsCallback(@NonNull ScanResultsCallback callback) { 5783 if (callback == null) throw new IllegalArgumentException("callback cannot be null"); 5784 Log.v(TAG, "unregisterScanResultsCallback: Callback=" + callback); 5785 ScanResultsCallback.ScanResultsCallbackProxy proxy = callback.getProxy(); 5786 try { 5787 mService.unregisterScanResultsCallback(proxy); 5788 } catch (RemoteException e) { 5789 throw e.rethrowFromSystemServer(); 5790 } finally { 5791 proxy.cleanUpProxy(); 5792 } 5793 } 5794 5795 /** 5796 * Interface for suggestion connection status listener. 5797 * Should be implemented by applications and set when calling 5798 * {@link WifiManager#addSuggestionConnectionStatusListener( 5799 * Executor, SuggestionConnectionStatusListener)}. 5800 */ 5801 public interface SuggestionConnectionStatusListener { 5802 5803 /** 5804 * Called when the framework attempted to connect to a suggestion provided by the 5805 * registering app, but the connection to the suggestion failed. 5806 * @param wifiNetworkSuggestion The suggestion which failed to connect. 5807 * @param failureReason the connection failure reason code. One of 5808 * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_ASSOCIATION}, 5809 * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION}, 5810 * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_IP_PROVISIONING} 5811 * {@link #STATUS_SUGGESTION_CONNECTION_FAILURE_UNKNOWN} 5812 */ onConnectionStatus( @onNull WifiNetworkSuggestion wifiNetworkSuggestion, @SuggestionConnectionStatusCode int failureReason)5813 void onConnectionStatus( 5814 @NonNull WifiNetworkSuggestion wifiNetworkSuggestion, 5815 @SuggestionConnectionStatusCode int failureReason); 5816 } 5817 5818 private class SuggestionConnectionStatusListenerProxy extends 5819 ISuggestionConnectionStatusListener.Stub { 5820 private final Executor mExecutor; 5821 private final SuggestionConnectionStatusListener mListener; 5822 SuggestionConnectionStatusListenerProxy(@onNull Executor executor, @NonNull SuggestionConnectionStatusListener listener)5823 SuggestionConnectionStatusListenerProxy(@NonNull Executor executor, 5824 @NonNull SuggestionConnectionStatusListener listener) { 5825 mExecutor = executor; 5826 mListener = listener; 5827 } 5828 5829 @Override onConnectionStatus(@onNull WifiNetworkSuggestion wifiNetworkSuggestion, int failureReason)5830 public void onConnectionStatus(@NonNull WifiNetworkSuggestion wifiNetworkSuggestion, 5831 int failureReason) { 5832 mExecutor.execute(() -> 5833 mListener.onConnectionStatus(wifiNetworkSuggestion, failureReason)); 5834 } 5835 5836 } 5837 5838 /** 5839 * Add a listener for suggestion networks. See {@link SuggestionConnectionStatusListener}. 5840 * Caller will receive the event when suggested network have connection failure. 5841 * Caller can remove a previously registered listener using 5842 * {@link WifiManager#removeSuggestionConnectionStatusListener( 5843 * SuggestionConnectionStatusListener)} 5844 * Same caller can add multiple listeners to monitor the event. 5845 * <p> 5846 * Applications should have the 5847 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and 5848 * {@link android.Manifest.permission#ACCESS_WIFI_STATE} permissions. 5849 * Callers without the permission will trigger a {@link java.lang.SecurityException}. 5850 * <p> 5851 * 5852 * @param executor The executor to execute the listener of the {@code listener} object. 5853 * @param listener listener for suggestion network connection failure. 5854 */ 5855 @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, ACCESS_WIFI_STATE}) addSuggestionConnectionStatusListener(@onNull @allbackExecutor Executor executor, @NonNull SuggestionConnectionStatusListener listener)5856 public void addSuggestionConnectionStatusListener(@NonNull @CallbackExecutor Executor executor, 5857 @NonNull SuggestionConnectionStatusListener listener) { 5858 if (listener == null) throw new IllegalArgumentException("Listener cannot be null"); 5859 if (executor == null) throw new IllegalArgumentException("Executor cannot be null"); 5860 Log.v(TAG, "addSuggestionConnectionStatusListener listener=" + listener 5861 + ", executor=" + executor); 5862 try { 5863 mService.registerSuggestionConnectionStatusListener(new Binder(), 5864 new SuggestionConnectionStatusListenerProxy(executor, listener), 5865 listener.hashCode(), mContext.getOpPackageName(), mContext.getAttributionTag()); 5866 } catch (RemoteException e) { 5867 throw e.rethrowFromSystemServer(); 5868 } 5869 5870 } 5871 5872 /** 5873 * Allow callers to remove a previously registered listener. After calling this method, 5874 * applications will no longer receive suggestion connection events through that listener. 5875 * 5876 * @param listener listener to remove. 5877 */ 5878 @RequiresPermission(ACCESS_WIFI_STATE) removeSuggestionConnectionStatusListener( @onNull SuggestionConnectionStatusListener listener)5879 public void removeSuggestionConnectionStatusListener( 5880 @NonNull SuggestionConnectionStatusListener listener) { 5881 if (listener == null) throw new IllegalArgumentException("Listener cannot be null"); 5882 Log.v(TAG, "removeSuggestionConnectionStatusListener: listener=" + listener); 5883 try { 5884 mService.unregisterSuggestionConnectionStatusListener(listener.hashCode(), 5885 mContext.getOpPackageName()); 5886 } catch (RemoteException e) { 5887 throw e.rethrowFromSystemServer(); 5888 } 5889 } 5890 5891 /** 5892 * Parse the list of channels the DPP enrollee reports when it fails to find an AP. 5893 * 5894 * @param channelList List of channels in the format defined in the DPP specification. 5895 * @return A parsed sparse array, where the operating class is the key. 5896 * @hide 5897 */ 5898 @VisibleForTesting parseDppChannelList(String channelList)5899 public static SparseArray<int[]> parseDppChannelList(String channelList) { 5900 SparseArray<int[]> channelListArray = new SparseArray<>(); 5901 5902 if (TextUtils.isEmpty(channelList)) { 5903 return channelListArray; 5904 } 5905 StringTokenizer str = new StringTokenizer(channelList, ","); 5906 String classStr = null; 5907 List<Integer> channelsInClass = new ArrayList<>(); 5908 5909 try { 5910 while (str.hasMoreElements()) { 5911 String cur = str.nextToken(); 5912 5913 /** 5914 * Example for a channel list: 5915 * 5916 * 81/1,2,3,4,5,6,7,8,9,10,11,115/36,40,44,48,118/52,56,60,64,121/100,104,108,112, 5917 * 116,120,124,128,132,136,140,0/144,124/149,153,157,161,125/165 5918 * 5919 * Detect operating class by the delimiter of '/' and use a string tokenizer with 5920 * ',' as a delimiter. 5921 */ 5922 int classDelim = cur.indexOf('/'); 5923 if (classDelim != -1) { 5924 if (classStr != null) { 5925 // Store the last channel array in the sparse array, where the operating 5926 // class is the key (as an integer). 5927 int[] channelsArray = new int[channelsInClass.size()]; 5928 for (int i = 0; i < channelsInClass.size(); i++) { 5929 channelsArray[i] = channelsInClass.get(i); 5930 } 5931 channelListArray.append(Integer.parseInt(classStr), channelsArray); 5932 channelsInClass = new ArrayList<>(); 5933 } 5934 5935 // Init a new operating class and store the first channel 5936 classStr = cur.substring(0, classDelim); 5937 String channelStr = cur.substring(classDelim + 1); 5938 channelsInClass.add(Integer.parseInt(channelStr)); 5939 } else { 5940 if (classStr == null) { 5941 // Invalid format 5942 Log.e(TAG, "Cannot parse DPP channel list"); 5943 return new SparseArray<>(); 5944 } 5945 channelsInClass.add(Integer.parseInt(cur)); 5946 } 5947 } 5948 5949 // Store the last array 5950 if (classStr != null) { 5951 int[] channelsArray = new int[channelsInClass.size()]; 5952 for (int i = 0; i < channelsInClass.size(); i++) { 5953 channelsArray[i] = channelsInClass.get(i); 5954 } 5955 channelListArray.append(Integer.parseInt(classStr), channelsArray); 5956 } 5957 return channelListArray; 5958 } catch (NumberFormatException e) { 5959 Log.e(TAG, "Cannot parse DPP channel list"); 5960 return new SparseArray<>(); 5961 } 5962 } 5963 5964 /** 5965 * Callback interface for framework to receive network status updates and trigger of updating 5966 * {@link WifiUsabilityStatsEntry}. 5967 * 5968 * @hide 5969 */ 5970 @SystemApi 5971 public interface ScoreUpdateObserver { 5972 /** 5973 * Called by applications to indicate network status. 5974 * 5975 * @param sessionId The ID to indicate current Wi-Fi network connection obtained from 5976 * {@link WifiConnectedNetworkScorer#onStart(int)}. 5977 * @param score The score representing link quality of current Wi-Fi network connection. 5978 * Populated by connected network scorer in applications.. 5979 */ notifyScoreUpdate(int sessionId, int score)5980 void notifyScoreUpdate(int sessionId, int score); 5981 5982 /** 5983 * Called by applications to trigger an update of {@link WifiUsabilityStatsEntry}. 5984 * To receive update applications need to add WifiUsabilityStatsEntry listener. See 5985 * {@link addOnWifiUsabilityStatsListener(Executor, OnWifiUsabilityStatsListener)}. 5986 * 5987 * @param sessionId The ID to indicate current Wi-Fi network connection obtained from 5988 * {@link WifiConnectedNetworkScorer#onStart(int)}. 5989 */ triggerUpdateOfWifiUsabilityStats(int sessionId)5990 void triggerUpdateOfWifiUsabilityStats(int sessionId); 5991 } 5992 5993 /** 5994 * Callback proxy for {@link ScoreUpdateObserver} objects. 5995 * 5996 * @hide 5997 */ 5998 private class ScoreUpdateObserverProxy implements ScoreUpdateObserver { 5999 private final IScoreUpdateObserver mScoreUpdateObserver; 6000 ScoreUpdateObserverProxy(IScoreUpdateObserver observer)6001 private ScoreUpdateObserverProxy(IScoreUpdateObserver observer) { 6002 mScoreUpdateObserver = observer; 6003 } 6004 6005 @Override notifyScoreUpdate(int sessionId, int score)6006 public void notifyScoreUpdate(int sessionId, int score) { 6007 try { 6008 mScoreUpdateObserver.notifyScoreUpdate(sessionId, score); 6009 } catch (RemoteException e) { 6010 throw e.rethrowFromSystemServer(); 6011 } 6012 } 6013 6014 @Override triggerUpdateOfWifiUsabilityStats(int sessionId)6015 public void triggerUpdateOfWifiUsabilityStats(int sessionId) { 6016 try { 6017 mScoreUpdateObserver.triggerUpdateOfWifiUsabilityStats(sessionId); 6018 } catch (RemoteException e) { 6019 throw e.rethrowFromSystemServer(); 6020 } 6021 } 6022 } 6023 6024 /** 6025 * Interface for Wi-Fi connected network scorer. Should be implemented by applications and set 6026 * when calling 6027 * {@link WifiManager#setWifiConnectedNetworkScorer(Executor, WifiConnectedNetworkScorer)}. 6028 * 6029 * @hide 6030 */ 6031 @SystemApi 6032 public interface WifiConnectedNetworkScorer { 6033 /** 6034 * Called by framework to indicate the start of a network connection. 6035 * @param sessionId The ID to indicate current Wi-Fi network connection. 6036 */ onStart(int sessionId)6037 void onStart(int sessionId); 6038 6039 /** 6040 * Called by framework to indicate the end of a network connection. 6041 * @param sessionId The ID to indicate current Wi-Fi network connection obtained from 6042 * {@link WifiConnectedNetworkScorer#onStart(int)}. 6043 */ onStop(int sessionId)6044 void onStop(int sessionId); 6045 6046 /** 6047 * Framework sets callback for score change events after application sets its scorer. 6048 * @param observerImpl The instance for {@link WifiManager#ScoreUpdateObserver}. Should be 6049 * implemented and instantiated by framework. 6050 */ onSetScoreUpdateObserver(@onNull ScoreUpdateObserver observerImpl)6051 void onSetScoreUpdateObserver(@NonNull ScoreUpdateObserver observerImpl); 6052 } 6053 6054 /** 6055 * Callback proxy for {@link WifiConnectedNetworkScorer} objects. 6056 * 6057 * @hide 6058 */ 6059 private class WifiConnectedNetworkScorerProxy extends IWifiConnectedNetworkScorer.Stub { 6060 private Executor mExecutor; 6061 private WifiConnectedNetworkScorer mScorer; 6062 WifiConnectedNetworkScorerProxy(Executor executor, WifiConnectedNetworkScorer scorer)6063 WifiConnectedNetworkScorerProxy(Executor executor, WifiConnectedNetworkScorer scorer) { 6064 mExecutor = executor; 6065 mScorer = scorer; 6066 } 6067 6068 @Override onStart(int sessionId)6069 public void onStart(int sessionId) { 6070 if (mVerboseLoggingEnabled) { 6071 Log.v(TAG, "WifiConnectedNetworkScorer: " + "onStart: sessionId=" + sessionId); 6072 } 6073 Binder.clearCallingIdentity(); 6074 mExecutor.execute(() -> mScorer.onStart(sessionId)); 6075 } 6076 6077 @Override onStop(int sessionId)6078 public void onStop(int sessionId) { 6079 if (mVerboseLoggingEnabled) { 6080 Log.v(TAG, "WifiConnectedNetworkScorer: " + "onStop: sessionId=" + sessionId); 6081 } 6082 Binder.clearCallingIdentity(); 6083 mExecutor.execute(() -> mScorer.onStop(sessionId)); 6084 } 6085 6086 @Override onSetScoreUpdateObserver(IScoreUpdateObserver observerImpl)6087 public void onSetScoreUpdateObserver(IScoreUpdateObserver observerImpl) { 6088 if (mVerboseLoggingEnabled) { 6089 Log.v(TAG, "WifiConnectedNetworkScorer: " 6090 + "onSetScoreUpdateObserver: observerImpl=" + observerImpl); 6091 } 6092 Binder.clearCallingIdentity(); 6093 mExecutor.execute(() -> mScorer.onSetScoreUpdateObserver( 6094 new ScoreUpdateObserverProxy(observerImpl))); 6095 } 6096 } 6097 6098 /** 6099 * Set a callback for Wi-Fi connected network scorer. See {@link WifiConnectedNetworkScorer}. 6100 * Only a single scorer can be set. Caller will be invoked periodically by framework to inform 6101 * client about start and stop of Wi-Fi connection. Caller can clear a previously set scorer 6102 * using {@link clearWifiConnectedNetworkScorer()}. 6103 * 6104 * @param executor The executor on which callback will be invoked. 6105 * @param scorer Scorer for Wi-Fi network implemented by application. 6106 * @return true Scorer is set successfully. 6107 * 6108 * @hide 6109 */ 6110 @SystemApi 6111 @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) setWifiConnectedNetworkScorer(@onNull @allbackExecutor Executor executor, @NonNull WifiConnectedNetworkScorer scorer)6112 public boolean setWifiConnectedNetworkScorer(@NonNull @CallbackExecutor Executor executor, 6113 @NonNull WifiConnectedNetworkScorer scorer) { 6114 if (executor == null) throw new IllegalArgumentException("executor cannot be null"); 6115 if (scorer == null) throw new IllegalArgumentException("scorer cannot be null"); 6116 if (mVerboseLoggingEnabled) { 6117 Log.v(TAG, "setWifiConnectedNetworkScorer: scorer=" + scorer); 6118 } 6119 try { 6120 return mService.setWifiConnectedNetworkScorer(new Binder(), 6121 new WifiConnectedNetworkScorerProxy(executor, scorer)); 6122 } catch (RemoteException e) { 6123 throw e.rethrowFromSystemServer(); 6124 } 6125 } 6126 6127 /** 6128 * Allow caller to clear a previously set scorer. After calling this method, 6129 * client will no longer receive information about start and stop of Wi-Fi connection. 6130 * 6131 * @hide 6132 */ 6133 @SystemApi 6134 @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) clearWifiConnectedNetworkScorer()6135 public void clearWifiConnectedNetworkScorer() { 6136 if (mVerboseLoggingEnabled) { 6137 Log.v(TAG, "clearWifiConnectedNetworkScorer"); 6138 } 6139 try { 6140 mService.clearWifiConnectedNetworkScorer(); 6141 } catch (RemoteException e) { 6142 throw e.rethrowFromSystemServer(); 6143 } 6144 } 6145 6146 /** 6147 * Enable/disable wifi scan throttling from 3rd party apps. 6148 * 6149 * <p> 6150 * The throttling limits for apps are described in 6151 * <a href="Wi-Fi Scan Throttling"> 6152 * https://developer.android.com/guide/topics/connectivity/wifi-scan#wifi-scan-throttling</a> 6153 * </p> 6154 * 6155 * @param enable true to allow scan throttling, false to disallow scan throttling. 6156 * @hide 6157 */ 6158 @SystemApi 6159 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) setScanThrottleEnabled(boolean enable)6160 public void setScanThrottleEnabled(boolean enable) { 6161 try { 6162 mService.setScanThrottleEnabled(enable); 6163 } catch (RemoteException e) { 6164 throw e.rethrowFromSystemServer(); 6165 } 6166 } 6167 6168 /** 6169 * Get the persisted Wi-Fi scan throttle state. Defaults to true, unless changed by the user via 6170 * Developer options. 6171 * 6172 * <p> 6173 * The throttling limits for apps are described in 6174 * <a href="Wi-Fi Scan Throttling"> 6175 * https://developer.android.com/guide/topics/connectivity/wifi-scan#wifi-scan-throttling</a> 6176 * </p> 6177 * 6178 * @return true to indicate that scan throttling is enabled, false to indicate that scan 6179 * throttling is disabled. 6180 */ 6181 @RequiresPermission(ACCESS_WIFI_STATE) isScanThrottleEnabled()6182 public boolean isScanThrottleEnabled() { 6183 try { 6184 return mService.isScanThrottleEnabled(); 6185 } catch (RemoteException e) { 6186 throw e.rethrowFromSystemServer(); 6187 } 6188 } 6189 6190 /** 6191 * Enable/disable wifi auto wakeup feature. 6192 * 6193 * <p> 6194 * The feature is described in 6195 * <a href="Wi-Fi Turn on automatically"> 6196 * https://source.android.com/devices/tech/connect/wifi-infrastructure 6197 * #turn_on_wi-fi_automatically 6198 * </a> 6199 * 6200 * @param enable true to enable, false to disable. 6201 * @hide 6202 */ 6203 @SystemApi 6204 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) setAutoWakeupEnabled(boolean enable)6205 public void setAutoWakeupEnabled(boolean enable) { 6206 try { 6207 mService.setAutoWakeupEnabled(enable); 6208 } catch (RemoteException e) { 6209 throw e.rethrowFromSystemServer(); 6210 } 6211 } 6212 6213 /** 6214 * Get the persisted Wi-Fi auto wakeup feature state. Defaults to false, unless changed by the 6215 * user via Settings. 6216 * 6217 * <p> 6218 * The feature is described in 6219 * <a href="Wi-Fi Turn on automatically"> 6220 * https://source.android.com/devices/tech/connect/wifi-infrastructure 6221 * #turn_on_wi-fi_automatically 6222 * </a> 6223 * 6224 * @return true to indicate that wakeup feature is enabled, false to indicate that wakeup 6225 * feature is disabled. 6226 */ 6227 @RequiresPermission(ACCESS_WIFI_STATE) isAutoWakeupEnabled()6228 public boolean isAutoWakeupEnabled() { 6229 try { 6230 return mService.isAutoWakeupEnabled(); 6231 } catch (RemoteException e) { 6232 throw e.rethrowFromSystemServer(); 6233 } 6234 } 6235 } 6236