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