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 android.annotation.FlaggedApi; 20 import android.annotation.IntDef; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.annotation.RequiresPermission; 24 import android.annotation.SuppressLint; 25 import android.annotation.SystemApi; 26 import android.compat.annotation.UnsupportedAppUsage; 27 import android.content.pm.PackageManager; 28 import android.net.IpConfiguration; 29 import android.net.IpConfiguration.ProxySettings; 30 import android.net.MacAddress; 31 import android.net.NetworkSpecifier; 32 import android.net.ProxyInfo; 33 import android.net.StaticIpConfiguration; 34 import android.net.Uri; 35 import android.os.Build; 36 import android.os.Parcel; 37 import android.os.ParcelUuid; 38 import android.os.Parcelable; 39 import android.os.SystemClock; 40 import android.os.UserHandle; 41 import android.telephony.SubscriptionInfo; 42 import android.telephony.SubscriptionManager; 43 import android.telephony.TelephonyManager; 44 import android.text.TextUtils; 45 import android.util.Log; 46 import android.util.SparseArray; 47 48 import androidx.annotation.Keep; 49 import androidx.annotation.RequiresApi; 50 51 import com.android.internal.annotations.VisibleForTesting; 52 import com.android.modules.utils.build.SdkLevel; 53 import com.android.net.module.util.MacAddressUtils; 54 import com.android.wifi.flags.Flags; 55 56 import java.lang.annotation.Retention; 57 import java.lang.annotation.RetentionPolicy; 58 import java.time.Instant; 59 import java.time.LocalDateTime; 60 import java.time.ZoneId; 61 import java.util.ArrayList; 62 import java.util.Arrays; 63 import java.util.BitSet; 64 import java.util.Calendar; 65 import java.util.Collections; 66 import java.util.HashMap; 67 import java.util.HashSet; 68 import java.util.List; 69 import java.util.Objects; 70 import java.util.Set; 71 72 /** 73 * A class representing a configured Wi-Fi network, including the 74 * security configuration. 75 * 76 * @deprecated Use {@link WifiNetworkSpecifier.Builder} to create {@link NetworkSpecifier} and 77 * {@link WifiNetworkSuggestion.Builder} to create {@link WifiNetworkSuggestion}. This class can 78 * still be used with privileged APIs such as 79 * {@link WifiManager#addNetwork(WifiConfiguration)}. 80 */ 81 @Deprecated 82 public class WifiConfiguration implements Parcelable { 83 private static final String TAG = "WifiConfiguration"; 84 /** 85 * Current Version of the Backup Serializer. 86 */ 87 private static final int BACKUP_VERSION = 3; 88 /** {@hide} */ 89 public static final String ssidVarName = "ssid"; 90 /** {@hide} */ 91 public static final String bssidVarName = "bssid"; 92 /** {@hide} */ 93 public static final String pskVarName = "psk"; 94 /** {@hide} */ 95 @Deprecated @UnsupportedAppUsage 96 public static final String[] wepKeyVarNames = {"wep_key0", "wep_key1", "wep_key2", "wep_key3"}; 97 /** {@hide} */ 98 @Deprecated 99 public static final String wepTxKeyIdxVarName = "wep_tx_keyidx"; 100 /** {@hide} */ 101 public static final String priorityVarName = "priority"; 102 /** {@hide} */ 103 public static final String hiddenSSIDVarName = "scan_ssid"; 104 /** {@hide} */ 105 public static final String pmfVarName = "ieee80211w"; 106 /** {@hide} */ 107 public static final String updateIdentiferVarName = "update_identifier"; 108 /** 109 * The network ID for an invalid network. 110 * 111 * @hide 112 */ 113 @SystemApi 114 public static final int INVALID_NETWORK_ID = -1; 115 /** {@hide} */ 116 public static final int LOCAL_ONLY_NETWORK_ID = -2; 117 118 /** {@hide} */ 119 private String mPasspointManagementObjectTree; 120 /** {@hide} */ 121 private static final int MAXIMUM_RANDOM_MAC_GENERATION_RETRY = 3; 122 123 /** 124 * Recognized key management schemes. 125 */ 126 public static class KeyMgmt { KeyMgmt()127 private KeyMgmt() { } 128 129 /** @hide */ 130 @Retention(RetentionPolicy.SOURCE) 131 @IntDef(value = { 132 NONE, 133 WPA_PSK, 134 WPA_EAP, 135 IEEE8021X, 136 WPA2_PSK, 137 OSEN, 138 FT_PSK, 139 FT_EAP, 140 SAE, 141 OWE, 142 SUITE_B_192, 143 WPA_PSK_SHA256, 144 WPA_EAP_SHA256, 145 WAPI_PSK, 146 WAPI_CERT, 147 FILS_SHA256, 148 FILS_SHA384, 149 DPP}) 150 public @interface KeyMgmtScheme {} 151 152 /** WPA is not used; plaintext or static WEP could be used. */ 153 public static final int NONE = 0; 154 /** WPA pre-shared key (requires {@code preSharedKey} to be specified). */ 155 public static final int WPA_PSK = 1; 156 /** WPA using EAP authentication. Generally used with an external authentication server. */ 157 public static final int WPA_EAP = 2; 158 /** 159 * IEEE 802.1X using EAP authentication and (optionally) dynamically 160 * generated WEP keys. 161 */ 162 public static final int IEEE8021X = 3; 163 164 /** 165 * WPA2 pre-shared key for use with soft access point 166 * (requires {@code preSharedKey} to be specified). 167 */ 168 public static final int WPA2_PSK = 4; 169 /** 170 * Hotspot 2.0 r2 OSEN: 171 */ 172 public static final int OSEN = 5; 173 174 /** 175 * IEEE 802.11r Fast BSS Transition with PSK authentication. 176 */ 177 public static final int FT_PSK = 6; 178 179 /** 180 * IEEE 802.11r Fast BSS Transition with EAP authentication. 181 */ 182 public static final int FT_EAP = 7; 183 184 /** 185 * Simultaneous Authentication of Equals 186 */ 187 public static final int SAE = 8; 188 189 /** 190 * Opportunististic Wireless Encryption 191 */ 192 public static final int OWE = 9; 193 194 /** 195 * SUITE_B_192 192 bit level 196 */ 197 public static final int SUITE_B_192 = 10; 198 199 /** 200 * WPA pre-shared key with stronger SHA256-based algorithms. 201 */ 202 public static final int WPA_PSK_SHA256 = 11; 203 204 /** 205 * WPA using EAP authentication with stronger SHA256-based algorithms. 206 */ 207 public static final int WPA_EAP_SHA256 = 12; 208 209 /** 210 * WAPI pre-shared key (requires {@code preSharedKey} to be specified). 211 */ 212 public static final int WAPI_PSK = 13; 213 214 /** 215 * WAPI certificate to be specified. 216 */ 217 public static final int WAPI_CERT = 14; 218 219 /** 220 * IEEE 802.11ai FILS SK with SHA256 221 */ 222 public static final int FILS_SHA256 = 15; 223 /** 224 * IEEE 802.11ai FILS SK with SHA384: 225 */ 226 public static final int FILS_SHA384 = 16; 227 228 /** 229 * Easy Connect - AKA Device Provisioning Protocol (DPP) 230 * For more details, visit <a href="https://www.wi-fi.org/">https://www.wi-fi.org/</a> and 231 * search for "Easy Connect" or "Device Provisioning Protocol specification". 232 */ 233 public static final int DPP = 17; 234 235 public static final String varName = "key_mgmt"; 236 237 public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP", 238 "IEEE8021X", "WPA2_PSK", "OSEN", "FT_PSK", "FT_EAP", 239 "SAE", "OWE", "SUITE_B_192", "WPA_PSK_SHA256", "WPA_EAP_SHA256", 240 "WAPI_PSK", "WAPI_CERT", "FILS_SHA256", "FILS_SHA384", "DPP" }; 241 } 242 243 /** 244 * Recognized security protocols. 245 */ 246 public static class Protocol { Protocol()247 private Protocol() { } 248 249 /** WPA/IEEE 802.11i/D3.0 250 * @deprecated Due to security and performance limitations, use of WPA-1 networks 251 * is discouraged. WPA-2 (RSN) should be used instead. */ 252 @Deprecated 253 public static final int WPA = 0; 254 /** RSN WPA2/WPA3/IEEE 802.11i */ 255 public static final int RSN = 1; 256 /** HS2.0 r2 OSEN 257 * @hide 258 */ 259 public static final int OSEN = 2; 260 261 /** 262 * WAPI Protocol 263 */ 264 public static final int WAPI = 3; 265 266 /** @hide */ 267 @Retention(RetentionPolicy.SOURCE) 268 @IntDef(value = {WPA, RSN, OSEN, WAPI}) 269 public @interface ProtocolScheme {}; 270 271 public static final String varName = "proto"; 272 273 public static final String[] strings = { "WPA", "RSN", "OSEN", "WAPI" }; 274 } 275 276 /** 277 * Recognized IEEE 802.11 authentication algorithms. 278 */ 279 public static class AuthAlgorithm { AuthAlgorithm()280 private AuthAlgorithm() { } 281 282 /** Open System authentication (required for WPA/WPA2) */ 283 public static final int OPEN = 0; 284 /** Shared Key authentication (requires static WEP keys) 285 * @deprecated Due to security and performance limitations, use of WEP networks 286 * is discouraged. */ 287 @Deprecated 288 public static final int SHARED = 1; 289 /** LEAP/Network EAP (only used with LEAP) */ 290 public static final int LEAP = 2; 291 292 /** SAE (Used only for WPA3-Personal) */ 293 public static final int SAE = 3; 294 295 /** @hide */ 296 @Retention(RetentionPolicy.SOURCE) 297 @IntDef(value = {OPEN, SHARED, LEAP, SAE}) 298 public @interface AuthAlgorithmScheme {}; 299 300 public static final String varName = "auth_alg"; 301 302 public static final String[] strings = { "OPEN", "SHARED", "LEAP", "SAE" }; 303 } 304 305 /** 306 * Recognized pairwise ciphers for WPA. 307 */ 308 public static class PairwiseCipher { PairwiseCipher()309 private PairwiseCipher() { } 310 311 /** Use only Group keys (deprecated) */ 312 public static final int NONE = 0; 313 /** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] 314 * @deprecated Due to security and performance limitations, use of WPA-1 networks 315 * is discouraged. WPA-2 (RSN) should be used instead. */ 316 @Deprecated 317 public static final int TKIP = 1; 318 /** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */ 319 public static final int CCMP = 2; 320 /** 321 * AES in Galois/Counter Mode 322 */ 323 public static final int GCMP_256 = 3; 324 /** 325 * SMS4 cipher for WAPI 326 */ 327 public static final int SMS4 = 4; 328 329 /** 330 * AES in Galois/Counter Mode with a 128-bit integrity key 331 */ 332 public static final int GCMP_128 = 5; 333 334 /** @hide */ 335 @Retention(RetentionPolicy.SOURCE) 336 @IntDef(value = {NONE, TKIP, CCMP, GCMP_256, SMS4, GCMP_128}) 337 public @interface PairwiseCipherScheme {}; 338 339 public static final String varName = "pairwise"; 340 341 public static final String[] strings = { "NONE", "TKIP", "CCMP", "GCMP_256", "SMS4", 342 "GCMP_128" }; 343 } 344 345 /** 346 * Recognized group ciphers. 347 * <pre> 348 * CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] 349 * TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] 350 * WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key 351 * WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11) 352 * GCMP_256 = AES in Galois/Counter Mode 353 * </pre> 354 */ 355 public static class GroupCipher { GroupCipher()356 private GroupCipher() { } 357 358 /** WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11) 359 * @deprecated Due to security and performance limitations, use of WEP networks 360 * is discouraged. */ 361 @Deprecated 362 public static final int WEP40 = 0; 363 /** WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key 364 * @deprecated Due to security and performance limitations, use of WEP networks 365 * is discouraged. */ 366 @Deprecated 367 public static final int WEP104 = 1; 368 /** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] */ 369 public static final int TKIP = 2; 370 /** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */ 371 public static final int CCMP = 3; 372 /** Hotspot 2.0 r2 OSEN 373 * @hide 374 */ 375 public static final int GTK_NOT_USED = 4; 376 /** 377 * AES in Galois/Counter Mode 378 */ 379 public static final int GCMP_256 = 5; 380 /** 381 * SMS4 cipher for WAPI 382 */ 383 public static final int SMS4 = 6; 384 /** 385 * AES in Galois/Counter Mode with a 128-bit integrity key 386 */ 387 public static final int GCMP_128 = 7; 388 389 /** @hide */ 390 @Retention(RetentionPolicy.SOURCE) 391 @IntDef(value = {WEP40, WEP104, TKIP, CCMP, GTK_NOT_USED, GCMP_256, SMS4, GCMP_128}) 392 public @interface GroupCipherScheme {}; 393 394 public static final String varName = "group"; 395 396 public static final String[] strings = 397 { /* deprecated */ "WEP40", /* deprecated */ "WEP104", 398 "TKIP", "CCMP", "GTK_NOT_USED", "GCMP_256", 399 "SMS4", "GCMP_128" }; 400 } 401 402 /** 403 * Recognized group management ciphers. 404 * <pre> 405 * BIP_CMAC_256 = Cipher-based Message Authentication Code 256 bits 406 * BIP_GMAC_128 = Galois Message Authentication Code 128 bits 407 * BIP_GMAC_256 = Galois Message Authentication Code 256 bits 408 * </pre> 409 */ 410 public static class GroupMgmtCipher { GroupMgmtCipher()411 private GroupMgmtCipher() { } 412 413 /** CMAC-256 = Cipher-based Message Authentication Code */ 414 public static final int BIP_CMAC_256 = 0; 415 416 /** GMAC-128 = Galois Message Authentication Code */ 417 public static final int BIP_GMAC_128 = 1; 418 419 /** GMAC-256 = Galois Message Authentication Code */ 420 public static final int BIP_GMAC_256 = 2; 421 422 /** @hide */ 423 @Retention(RetentionPolicy.SOURCE) 424 @IntDef(value = {BIP_CMAC_256, BIP_GMAC_128, BIP_GMAC_256}) 425 public @interface GroupMgmtCipherScheme {}; 426 427 private static final String varName = "groupMgmt"; 428 429 /** @hide */ 430 @SuppressLint("AllUpper") 431 public static final @NonNull String[] strings = { "BIP_CMAC_256", 432 "BIP_GMAC_128", "BIP_GMAC_256"}; 433 } 434 435 /** 436 * Recognized suiteB ciphers. 437 * <pre> 438 * ECDHE_ECDSA 439 * ECDHE_RSA 440 * </pre> 441 * @hide 442 */ 443 public static class SuiteBCipher { SuiteBCipher()444 private SuiteBCipher() { } 445 446 /** Diffie-Hellman with Elliptic Curve_ECDSA signature */ 447 public static final int ECDHE_ECDSA = 0; 448 449 /** Diffie-Hellman with_RSA signature */ 450 public static final int ECDHE_RSA = 1; 451 452 /** @hide */ 453 @Retention(RetentionPolicy.SOURCE) 454 @IntDef(value = {ECDHE_ECDSA, ECDHE_RSA}) 455 public @interface SuiteBCipherScheme {}; 456 457 private static final String varName = "SuiteB"; 458 459 /** @hide */ 460 @SuppressLint("AllUpper") 461 public static final String[] strings = { "ECDHE_ECDSA", "ECDHE_RSA" }; 462 } 463 464 /** Possible status of a network configuration. */ 465 public static class Status { Status()466 private Status() { } 467 468 /** this is the network we are currently connected to */ 469 public static final int CURRENT = 0; 470 /** supplicant will not attempt to use this network */ 471 public static final int DISABLED = 1; 472 /** supplicant will consider this network available for association */ 473 public static final int ENABLED = 2; 474 475 public static final String[] strings = { "current", "disabled", "enabled" }; 476 } 477 478 /** Security type for an open network. */ 479 public static final int SECURITY_TYPE_OPEN = 0; 480 /** Security type for a WEP network. */ 481 public static final int SECURITY_TYPE_WEP = 1; 482 /** Security type for a PSK network. */ 483 public static final int SECURITY_TYPE_PSK = 2; 484 /** Security type for an EAP network. */ 485 public static final int SECURITY_TYPE_EAP = 3; 486 /** Security type for an SAE network. */ 487 public static final int SECURITY_TYPE_SAE = 4; 488 /** 489 * Security type for a WPA3-Enterprise in 192-bit security network. 490 * This is the same as {@link #SECURITY_TYPE_EAP_SUITE_B} and uses the same value. 491 */ 492 public static final int SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT = 5; 493 /** 494 * Security type for a WPA3-Enterprise in 192-bit security network. 495 * @deprecated Use the {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT} constant 496 * (which is the same value). 497 */ 498 @Deprecated 499 public static final int SECURITY_TYPE_EAP_SUITE_B = 500 SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT; 501 /** Security type for an OWE network. */ 502 public static final int SECURITY_TYPE_OWE = 6; 503 /** Security type for a WAPI PSK network. */ 504 public static final int SECURITY_TYPE_WAPI_PSK = 7; 505 /** Security type for a WAPI Certificate network. */ 506 public static final int SECURITY_TYPE_WAPI_CERT = 8; 507 /** Security type for a WPA3-Enterprise network. */ 508 public static final int SECURITY_TYPE_EAP_WPA3_ENTERPRISE = 9; 509 /** 510 * Security type for an OSEN network. 511 * @hide 512 */ 513 public static final int SECURITY_TYPE_OSEN = 10; 514 /** 515 * Security type for a Passpoint R1/R2 network. 516 * Passpoint R1/R2 uses Enterprise security, where TKIP and WEP are not allowed. 517 * @hide 518 */ 519 public static final int SECURITY_TYPE_PASSPOINT_R1_R2 = 11; 520 521 /** 522 * Security type for a Passpoint R3 network. 523 * Passpoint R3 uses Enterprise security, where TKIP and WEP are not allowed, 524 * and PMF must be set to Required. 525 * @hide 526 */ 527 public static final int SECURITY_TYPE_PASSPOINT_R3 = 12; 528 529 /** Security type for Easy Connect (DPP) network */ 530 public static final int SECURITY_TYPE_DPP = 13; 531 532 /** 533 * This is used for the boundary check and should be the same as the last type. 534 * @hide 535 */ 536 public static final int SECURITY_TYPE_NUM = SECURITY_TYPE_DPP; 537 538 /** 539 * Security types we support. 540 * @hide 541 */ 542 @Retention(RetentionPolicy.SOURCE) 543 @IntDef(prefix = { "SECURITY_TYPE_" }, value = { 544 SECURITY_TYPE_OPEN, 545 SECURITY_TYPE_WEP, 546 SECURITY_TYPE_PSK, 547 SECURITY_TYPE_EAP, 548 SECURITY_TYPE_SAE, 549 SECURITY_TYPE_EAP_SUITE_B, 550 SECURITY_TYPE_OWE, 551 SECURITY_TYPE_WAPI_PSK, 552 SECURITY_TYPE_WAPI_CERT, 553 SECURITY_TYPE_EAP_WPA3_ENTERPRISE, 554 SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT, 555 SECURITY_TYPE_PASSPOINT_R1_R2, 556 SECURITY_TYPE_PASSPOINT_R3, 557 SECURITY_TYPE_DPP, 558 }) 559 public @interface SecurityType {} 560 561 private static final String[] SECURITY_TYPE_NAMES = { 562 "open", "wep", "wpa2-psk", "wpa2-enterprise", 563 "wpa3-sae", "wpa3 enterprise 192-bit", "owe", 564 "wapi-psk", "wapi-cert", "wpa3 enterprise", 565 "wpa3 enterprise 192-bit", "passpoint r1/r2", 566 "passpoint r3", "dpp"}; 567 568 private List<SecurityParams> mSecurityParamsList = new ArrayList<>(); 569 updateLegacySecurityParams()570 private void updateLegacySecurityParams() { 571 if (mSecurityParamsList.isEmpty()) return; 572 mSecurityParamsList.get(0).updateLegacyWifiConfiguration(this); 573 } 574 575 /** 576 * Set the various security params to correspond to the provided security type. 577 * This is accomplished by setting the various BitSets exposed in WifiConfiguration. 578 * <br> 579 * This API would clear existing security types and add a default one. 580 * 581 * Before calling this API with {@link #SECURITY_TYPE_DPP} as securityType, 582 * call {@link WifiManager#isEasyConnectDppAkmSupported() to know whether this security type is 583 * supported or not. 584 * 585 * @param securityType One of the following security types: 586 * {@link #SECURITY_TYPE_OPEN}, 587 * {@link #SECURITY_TYPE_WEP}, 588 * {@link #SECURITY_TYPE_PSK}, 589 * {@link #SECURITY_TYPE_EAP}, 590 * {@link #SECURITY_TYPE_SAE}, 591 * {@link #SECURITY_TYPE_OWE}, 592 * {@link #SECURITY_TYPE_WAPI_PSK}, 593 * {@link #SECURITY_TYPE_WAPI_CERT}, 594 * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE}, 595 * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT}, 596 * {@link #SECURITY_TYPE_DPP}, 597 */ setSecurityParams(@ecurityType int securityType)598 public void setSecurityParams(@SecurityType int securityType) { 599 // Clear existing data. 600 mSecurityParamsList.clear(); 601 addSecurityParams(securityType); 602 } 603 604 /** 605 * Set security params by the given key management mask. 606 * 607 * @param givenAllowedKeyManagement the given allowed key management mask. 608 * @hide 609 */ setSecurityParams(@onNull BitSet givenAllowedKeyManagement)610 public void setSecurityParams(@NonNull BitSet givenAllowedKeyManagement) { 611 if (givenAllowedKeyManagement == null) { 612 throw new IllegalArgumentException("Invalid allowed key management mask."); 613 } 614 // Clear existing data. 615 mSecurityParamsList.clear(); 616 allowedKeyManagement = (BitSet) givenAllowedKeyManagement.clone(); 617 convertLegacyFieldsToSecurityParamsIfNeeded(); 618 } 619 620 /** 621 * Add the various security params. 622 * <br> 623 * This API would clear existing security types and add a default one. 624 * @hide 625 */ setSecurityParams(SecurityParams params)626 public void setSecurityParams(SecurityParams params) { 627 // Clear existing data. 628 mSecurityParamsList.clear(); 629 addSecurityParams(params); 630 } 631 632 /** 633 * Set the security params by the given security params list. 634 * 635 * This will overwrite existing security params list directly. 636 * 637 * @param securityParamsList the desired security params list. 638 * @hide 639 */ setSecurityParams(@onNull List<SecurityParams> securityParamsList)640 public void setSecurityParams(@NonNull List<SecurityParams> securityParamsList) { 641 if (securityParamsList == null || securityParamsList.isEmpty()) { 642 throw new IllegalArgumentException("An empty security params list is invalid."); 643 } 644 mSecurityParamsList = new ArrayList<>(securityParamsList.size()); 645 securityParamsList.forEach(p -> mSecurityParamsList.add(new SecurityParams(p))); 646 updateLegacySecurityParams(); 647 } 648 649 /** 650 * Add the various security params to correspond to the provided security type. 651 * This is accomplished by setting the various BitSets exposed in WifiConfiguration. 652 * 653 * @param securityType One of the following security types: 654 * {@link #SECURITY_TYPE_OPEN}, 655 * {@link #SECURITY_TYPE_WEP}, 656 * {@link #SECURITY_TYPE_PSK}, 657 * {@link #SECURITY_TYPE_EAP}, 658 * {@link #SECURITY_TYPE_SAE}, 659 * {@link #SECURITY_TYPE_OWE}, 660 * {@link #SECURITY_TYPE_WAPI_PSK}, 661 * {@link #SECURITY_TYPE_WAPI_CERT}, 662 * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE}, 663 * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT}, 664 * {@link #SECURITY_TYPE_DPP}, 665 * 666 * @hide 667 */ 668 @Keep addSecurityParams(@ecurityType int securityType)669 public void addSecurityParams(@SecurityType int securityType) { 670 // This ensures that there won't be duplicate security types. 671 for (SecurityParams params : mSecurityParamsList) { 672 if (params.isSecurityType(securityType)) { 673 throw new IllegalArgumentException("duplicate security type " + securityType); 674 } 675 } 676 addSecurityParams(SecurityParams.createSecurityParamsBySecurityType(securityType)); 677 } 678 679 /** @hide */ addSecurityParams(@onNull SecurityParams newParams)680 public void addSecurityParams(@NonNull SecurityParams newParams) { 681 // This ensures that there won't be duplicate security types. 682 for (SecurityParams params : mSecurityParamsList) { 683 if (params.isSameSecurityType(newParams)) { 684 throw new IllegalArgumentException("duplicate security params " + newParams); 685 } 686 } 687 if (!mSecurityParamsList.isEmpty()) { 688 if (newParams.isEnterpriseSecurityType() && !isEnterprise()) { 689 throw new IllegalArgumentException( 690 "An enterprise security type cannot be added to a personal configuation."); 691 } 692 if (!newParams.isEnterpriseSecurityType() && isEnterprise()) { 693 throw new IllegalArgumentException( 694 "A personal security type cannot be added to an enterprise configuation."); 695 } 696 if (newParams.isOpenSecurityType() && !isOpenNetwork()) { 697 throw new IllegalArgumentException( 698 "An open security type cannot be added to a non-open configuation."); 699 } 700 if (!newParams.isOpenSecurityType() && isOpenNetwork()) { 701 throw new IllegalArgumentException( 702 "A non-open security type cannot be added to an open configuation."); 703 } 704 if (newParams.isSecurityType(SECURITY_TYPE_OSEN)) { 705 throw new IllegalArgumentException( 706 "An OSEN security type must be the only one type."); 707 } 708 } 709 mSecurityParamsList.add(new SecurityParams(newParams)); 710 updateLegacySecurityParams(); 711 } 712 isWpa3EnterpriseConfiguration()713 private boolean isWpa3EnterpriseConfiguration() { 714 if (!allowedKeyManagement.get(KeyMgmt.WPA_EAP_SHA256) 715 && !allowedKeyManagement.get(KeyMgmt.WPA_EAP) 716 && !allowedKeyManagement.get(KeyMgmt.IEEE8021X)) { 717 return false; 718 } 719 if (!requirePmf) return false; 720 // Only RSN protocol is set. 721 if (allowedProtocols.cardinality() > 1) return false; 722 if (!allowedProtocols.get(Protocol.RSN)) return false; 723 // TKIP is not allowed. 724 if (allowedPairwiseCiphers.get(PairwiseCipher.TKIP)) return false; 725 if (allowedGroupCiphers.get(GroupCipher.TKIP)) return false; 726 return true; 727 } 728 729 /** 730 * Return whether the configuration is a WPA-Personal network 731 * @hide 732 */ isWpaPersonalOnlyConfiguration()733 public boolean isWpaPersonalOnlyConfiguration() { 734 return isSecurityType(SECURITY_TYPE_PSK) 735 && allowedProtocols.get(Protocol.WPA) 736 && !allowedProtocols.get(Protocol.RSN); 737 } 738 739 /** 740 * If there is no security params, generate one according to legacy fields. 741 * @hide 742 */ 743 @Keep convertLegacyFieldsToSecurityParamsIfNeeded()744 public void convertLegacyFieldsToSecurityParamsIfNeeded() { 745 if (!mSecurityParamsList.isEmpty()) return; 746 if (allowedKeyManagement.get(KeyMgmt.WAPI_CERT)) { 747 setSecurityParams(SECURITY_TYPE_WAPI_CERT); 748 } else if (allowedKeyManagement.get(KeyMgmt.WAPI_PSK)) { 749 setSecurityParams(SECURITY_TYPE_WAPI_PSK); 750 } else if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) { 751 setSecurityParams(SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT); 752 } else if (allowedKeyManagement.get(KeyMgmt.DPP)) { 753 setSecurityParams(SECURITY_TYPE_DPP); 754 } else if (allowedKeyManagement.get(KeyMgmt.OWE)) { 755 setSecurityParams(SECURITY_TYPE_OWE); 756 } else if (allowedKeyManagement.get(KeyMgmt.SAE)) { 757 setSecurityParams(SECURITY_TYPE_SAE); 758 } else if (allowedKeyManagement.get(KeyMgmt.OSEN)) { 759 setSecurityParams(SECURITY_TYPE_OSEN); 760 } else if (allowedKeyManagement.get(KeyMgmt.WPA2_PSK) 761 || allowedKeyManagement.get(KeyMgmt.WPA_PSK_SHA256) 762 || allowedKeyManagement.get(KeyMgmt.FT_PSK)) { 763 setSecurityParams(SECURITY_TYPE_PSK); 764 } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP) 765 || allowedKeyManagement.get(KeyMgmt.FT_EAP) 766 || allowedKeyManagement.get(KeyMgmt.IEEE8021X) 767 || allowedKeyManagement.get(KeyMgmt.WPA_EAP_SHA256) 768 || allowedKeyManagement.get(KeyMgmt.FILS_SHA256) 769 || allowedKeyManagement.get(KeyMgmt.FILS_SHA384)) { 770 if (isWpa3EnterpriseConfiguration()) { 771 setSecurityParams(SECURITY_TYPE_EAP_WPA3_ENTERPRISE); 772 } else { 773 setSecurityParams(SECURITY_TYPE_EAP); 774 } 775 } else if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) { 776 setSecurityParams(SECURITY_TYPE_PSK); 777 } else if (allowedKeyManagement.get(KeyMgmt.DPP)) { 778 setSecurityParams(SECURITY_TYPE_DPP); 779 } else if (allowedKeyManagement.get(KeyMgmt.NONE)) { 780 if (hasWepKeys()) { 781 setSecurityParams(SECURITY_TYPE_WEP); 782 } else { 783 setSecurityParams(SECURITY_TYPE_OPEN); 784 } 785 } else { 786 setSecurityParams(SECURITY_TYPE_OPEN); 787 } 788 } 789 790 /** 791 * Disable the various security params to correspond to the provided security type. 792 * This is accomplished by setting the various BitSets exposed in WifiConfiguration. 793 * 794 * @param securityType One of the following security types: 795 * {@link #SECURITY_TYPE_OPEN}, 796 * {@link #SECURITY_TYPE_WEP}, 797 * {@link #SECURITY_TYPE_PSK}, 798 * {@link #SECURITY_TYPE_EAP}, 799 * {@link #SECURITY_TYPE_SAE}, 800 * {@link #SECURITY_TYPE_OWE}, 801 * {@link #SECURITY_TYPE_WAPI_PSK}, 802 * {@link #SECURITY_TYPE_WAPI_CERT}, 803 * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE}, 804 * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT}, 805 * {@link #SECURITY_TYPE_DPP}, 806 * 807 * @hide 808 */ setSecurityParamsEnabled(@ecurityType int securityType, boolean enable)809 public void setSecurityParamsEnabled(@SecurityType int securityType, boolean enable) { 810 for (SecurityParams p : mSecurityParamsList) { 811 if (p.isSecurityType(securityType)) { 812 p.setEnabled(enable); 813 return; 814 } 815 } 816 } 817 818 /** 819 * Set whether a type is added by auto-upgrade. 820 * 821 * @param securityType One of the following security types: 822 * {@link #SECURITY_TYPE_OPEN}, 823 * {@link #SECURITY_TYPE_WEP}, 824 * {@link #SECURITY_TYPE_PSK}, 825 * {@link #SECURITY_TYPE_EAP}, 826 * {@link #SECURITY_TYPE_SAE}, 827 * {@link #SECURITY_TYPE_OWE}, 828 * {@link #SECURITY_TYPE_WAPI_PSK}, 829 * {@link #SECURITY_TYPE_WAPI_CERT}, 830 * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE}, 831 * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT}, 832 * 833 * @hide 834 */ setSecurityParamsIsAddedByAutoUpgrade( @ecurityType int securityType, boolean isAddedByAutoUpgrade)835 public void setSecurityParamsIsAddedByAutoUpgrade( 836 @SecurityType int securityType, boolean isAddedByAutoUpgrade) { 837 for (SecurityParams p : mSecurityParamsList) { 838 if (p.isSecurityType(securityType)) { 839 p.setIsAddedByAutoUpgrade(isAddedByAutoUpgrade); 840 return; 841 } 842 } 843 } 844 845 /** 846 * Get the specific security param. 847 * 848 * @param securityType One of the following security types: 849 * {@link #SECURITY_TYPE_OPEN}, 850 * {@link #SECURITY_TYPE_WEP}, 851 * {@link #SECURITY_TYPE_PSK}, 852 * {@link #SECURITY_TYPE_EAP}, 853 * {@link #SECURITY_TYPE_SAE}, 854 * {@link #SECURITY_TYPE_OWE}, 855 * {@link #SECURITY_TYPE_WAPI_PSK}, 856 * {@link #SECURITY_TYPE_WAPI_CERT}, 857 * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE}, 858 * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT}, 859 * {@link #SECURITY_TYPE_DPP}, 860 * 861 * @return the copy of specific security params if found; otherwise null. 862 * @hide 863 */ getSecurityParams(@ecurityType int securityType)864 public @Nullable SecurityParams getSecurityParams(@SecurityType int securityType) { 865 for (SecurityParams p : mSecurityParamsList) { 866 if (p.isSecurityType(securityType)) { 867 return new SecurityParams(p); 868 } 869 } 870 return null; 871 } 872 873 /** 874 * Indicate whether this configuration is the specific security type. 875 * 876 * @param securityType One of the following security types: 877 * {@link #SECURITY_TYPE_OPEN}, 878 * {@link #SECURITY_TYPE_WEP}, 879 * {@link #SECURITY_TYPE_PSK}, 880 * {@link #SECURITY_TYPE_EAP}, 881 * {@link #SECURITY_TYPE_SAE}, 882 * {@link #SECURITY_TYPE_OWE}, 883 * {@link #SECURITY_TYPE_WAPI_PSK}, 884 * {@link #SECURITY_TYPE_WAPI_CERT}, 885 * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE}, 886 * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT}, 887 * {@link #SECURITY_TYPE_DPP}, 888 * 889 * @return true if there is a security params matches the type. 890 * @hide 891 */ 892 @Keep isSecurityType(@ecurityType int securityType)893 public boolean isSecurityType(@SecurityType int securityType) { 894 for (SecurityParams p : mSecurityParamsList) { 895 if (p.isSecurityType(securityType)) { 896 return true; 897 } 898 } 899 return false; 900 } 901 902 /** 903 * Get the security params list of this configuration. 904 * 905 * The returning list is a priority list, the first is the lowest priority and default one. 906 * 907 * @return this list of security params. 908 * @hide 909 */ getSecurityParamsList()910 public List<SecurityParams> getSecurityParamsList() { 911 return Collections.unmodifiableList(mSecurityParamsList); 912 } 913 914 /** 915 * Get the default params which is the same as the legacy fields. 916 * 917 * @return the default security params. 918 * @hide 919 */ 920 @Keep getDefaultSecurityParams()921 public @NonNull SecurityParams getDefaultSecurityParams() { 922 return new SecurityParams(mSecurityParamsList.get(0)); 923 } 924 925 /** 926 * Enable the support of Fast Initial Link Set-up (FILS). 927 * 928 * FILS can be applied to all security types. 929 * @param enableFilsSha256 Enable FILS SHA256. 930 * @param enableFilsSha384 Enable FILS SHA256. 931 * @hide 932 */ enableFils(boolean enableFilsSha256, boolean enableFilsSha384)933 public void enableFils(boolean enableFilsSha256, boolean enableFilsSha384) { 934 mSecurityParamsList.forEach(params -> 935 params.enableFils(enableFilsSha256, enableFilsSha384)); 936 updateLegacySecurityParams(); 937 } 938 939 /** 940 * Indicate FILS SHA256 is enabled. 941 * 942 * @return true if FILS SHA256 is enabled. 943 * @hide 944 */ isFilsSha256Enabled()945 public boolean isFilsSha256Enabled() { 946 for (SecurityParams p : mSecurityParamsList) { 947 if (p.getAllowedKeyManagement().get(KeyMgmt.FILS_SHA256)) { 948 return true; 949 } 950 } 951 return false; 952 } 953 954 /** 955 * Indicate FILS SHA384 is enabled. 956 * 957 * @return true if FILS SHA384 is enabled. 958 * @hide 959 */ isFilsSha384Enabled()960 public boolean isFilsSha384Enabled() { 961 for (SecurityParams p : mSecurityParamsList) { 962 if (p.getAllowedKeyManagement().get(KeyMgmt.FILS_SHA384)) { 963 return true; 964 } 965 } 966 return false; 967 } 968 969 /** 970 * Enable Suite-B ciphers. 971 * 972 * @param enableEcdheEcdsa enable Diffie-Hellman with Elliptic Curve ECDSA cipher support. 973 * @param enableEcdheRsa enable Diffie-Hellman with RSA cipher support. 974 * @hide 975 */ enableSuiteBCiphers(boolean enableEcdheEcdsa, boolean enableEcdheRsa)976 public void enableSuiteBCiphers(boolean enableEcdheEcdsa, boolean enableEcdheRsa) { 977 for (SecurityParams p : mSecurityParamsList) { 978 if (p.isSecurityType(SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT)) { 979 p.enableSuiteBCiphers(enableEcdheEcdsa, enableEcdheRsa); 980 updateLegacySecurityParams(); 981 return; 982 } 983 } 984 } 985 986 /** 987 * Indicate ECDHE_ECDSA is enabled. 988 * 989 * @return true if enabled. 990 * @hide 991 */ isSuiteBCipherEcdheEcdsaEnabled()992 public boolean isSuiteBCipherEcdheEcdsaEnabled() { 993 for (SecurityParams p : mSecurityParamsList) { 994 if (p.getAllowedSuiteBCiphers().get(SuiteBCipher.ECDHE_ECDSA)) { 995 return true; 996 } 997 } 998 return false; 999 } 1000 1001 /** 1002 * Indicate ECDHE_RSA is enabled. 1003 * 1004 * @return true if enabled. 1005 * @hide 1006 */ isSuiteBCipherEcdheRsaEnabled()1007 public boolean isSuiteBCipherEcdheRsaEnabled() { 1008 for (SecurityParams p : mSecurityParamsList) { 1009 if (p.getAllowedSuiteBCiphers().get(SuiteBCipher.ECDHE_RSA)) { 1010 return true; 1011 } 1012 } 1013 return false; 1014 } 1015 1016 /** 1017 * Set SAE Hash-toElement only mode enabled. 1018 * Before calling this API, call {@link WifiManager#isWpa3SaeH2eSupported() 1019 * to know whether WPA3 SAE Hash-toElement is supported or not. 1020 * 1021 * @param enable true if enabled; false otherwise. 1022 * @hide 1023 */ enableSaeH2eOnlyMode(boolean enable)1024 public void enableSaeH2eOnlyMode(boolean enable) { 1025 for (SecurityParams p : mSecurityParamsList) { 1026 if (p.isSecurityType(SECURITY_TYPE_SAE)) { 1027 p.enableSaeH2eOnlyMode(enable); 1028 return; 1029 } 1030 } 1031 } 1032 1033 /** 1034 * Set SAE Public-Key only mode enabled. 1035 * Before calling this API, call {@link WifiManager#isWpa3SaePkSupported() 1036 * to know whether WPA3 SAE Public-Key is supported or not. 1037 * 1038 * @param enable true if enabled; false otherwise. 1039 * @hide 1040 */ enableSaePkOnlyMode(boolean enable)1041 public void enableSaePkOnlyMode(boolean enable) { 1042 for (SecurityParams p : mSecurityParamsList) { 1043 if (p.isSecurityType(SECURITY_TYPE_SAE)) { 1044 p.enableSaePkOnlyMode(enable); 1045 return; 1046 } 1047 } 1048 } 1049 1050 /** @hide */ 1051 public static final int UNKNOWN_UID = -1; 1052 1053 /** 1054 * The ID number that the supplicant uses to identify this 1055 * network configuration entry. This must be passed as an argument 1056 * to most calls into the supplicant. 1057 */ 1058 public int networkId; 1059 1060 // TODO (b/235236813): Remove this field and use quality network selection status instead. 1061 /** 1062 * The current status of this network configuration entry. 1063 * @see Status 1064 */ 1065 public int status; 1066 1067 /** 1068 * The network's SSID. Can either be a UTF-8 string, 1069 * which must be enclosed in double quotation marks 1070 * (e.g., {@code "MyNetwork"}), or a string of 1071 * hex digits, which are not enclosed in quotes 1072 * (e.g., {@code 01a243f405}). 1073 */ 1074 public String SSID; 1075 1076 /** 1077 * When set, this network configuration entry should only be used when 1078 * associating with the AP having the specified BSSID. The value is 1079 * a string in the format of an Ethernet MAC address, e.g., 1080 * <code>XX:XX:XX:XX:XX:XX</code> where each <code>X</code> is a hex digit. 1081 */ 1082 public String BSSID; 1083 1084 private List<MacAddress> mBssidAllowlist; 1085 1086 private byte[] mEncryptedPreSharedKey; 1087 private byte[] mEncryptedPreSharedKeyIv; 1088 private boolean mHasPreSharedKeyChanged; 1089 1090 /** 1091 * Set a list of BSSIDs to control if this network configuration entry should be used to 1092 * associate an AP. 1093 * <ul> 1094 * <li>If set with {@code null}, then there are no restrictions on the connection. The 1095 * configuration will associate to any AP.</li> 1096 * <li>If set to an empty list then the configuration will not associate to any AP.</li> 1097 * <li>If set to a non-empty list then the configuration will only associate to APs whose BSSID 1098 * is on the list.</li> 1099 * </ul> 1100 * @param bssidAllowlist A list of {@link MacAddress} representing the BSSID of APs, 1101 * {@code null} to allow all BSSIDs (no restriction). 1102 * @hide 1103 */ 1104 @SystemApi setBssidAllowlist(@ullable List<MacAddress> bssidAllowlist)1105 public void setBssidAllowlist(@Nullable List<MacAddress> bssidAllowlist) { 1106 if (bssidAllowlist == null) { 1107 mBssidAllowlist = null; 1108 return; 1109 } 1110 mBssidAllowlist = new ArrayList<>(bssidAllowlist); 1111 } 1112 1113 /** 1114 * Get a list of BSSIDs specified on this network configuration entry, set by 1115 * {@link #setBssidAllowlist(List)}. 1116 * @return A list of {@link MacAddress} representing BSSID to allow associate, {@code null} for 1117 * allowing all BSSIDs (no restriction). 1118 * @hide 1119 */ 1120 @SuppressLint("NullableCollection") 1121 @SystemApi 1122 @Nullable getBssidAllowlist()1123 public List<MacAddress> getBssidAllowlist() { 1124 if (mBssidAllowlist == null) { 1125 return null; 1126 } 1127 return new ArrayList<>(mBssidAllowlist); 1128 } 1129 1130 /** 1131 * @hide 1132 */ getBssidAllowlistInternal()1133 public List<MacAddress> getBssidAllowlistInternal() { 1134 return mBssidAllowlist; 1135 } 1136 1137 /** @hide */ 1138 @Retention(RetentionPolicy.SOURCE) 1139 @IntDef(prefix = {"AP_BAND_"}, value = { 1140 AP_BAND_2GHZ, 1141 AP_BAND_5GHZ, 1142 AP_BAND_ANY}) 1143 public @interface ApBand {} 1144 1145 /** 1146 * 2GHz band. 1147 * @hide 1148 */ 1149 public static final int AP_BAND_2GHZ = 0; 1150 1151 /** 1152 * 5GHz band. 1153 * @hide 1154 */ 1155 public static final int AP_BAND_5GHZ = 1; 1156 1157 /** 1158 * 60GHz band 1159 * @hide 1160 */ 1161 public static final int AP_BAND_60GHZ = 2; 1162 1163 /** 1164 * Device is allowed to choose the optimal band (2Ghz or 5Ghz) based on device capability, 1165 * operating country code and current radio conditions. 1166 * @hide 1167 */ 1168 public static final int AP_BAND_ANY = -1; 1169 1170 /** 1171 * The band which the AP resides on. 1172 * One of {@link #AP_BAND_2GHZ}, {@link #AP_BAND_5GHZ}, or {@link #AP_BAND_ANY}. 1173 * By default, {@link #AP_BAND_2GHZ} is chosen. 1174 * 1175 * @hide 1176 */ 1177 @UnsupportedAppUsage 1178 @ApBand 1179 public int apBand = AP_BAND_2GHZ; 1180 1181 /** 1182 * The channel which AP resides on,currently, US only 1183 * 2G 1-11 1184 * 5G 36,40,44,48,149,153,157,161,165 1185 * 0 - find a random available channel according to the apBand 1186 * @hide 1187 */ 1188 @UnsupportedAppUsage 1189 public int apChannel = 0; 1190 1191 /** 1192 * Pre-shared key for use with WPA-PSK. Either an ASCII string enclosed in 1193 * double quotation marks (e.g., {@code "abcdefghij"} for PSK passphrase or 1194 * a string of 64 hex digits for raw PSK. 1195 * <p/> 1196 * When the value of this key is read, the actual key is 1197 * not returned, just a "*" if the key has a value, or the null 1198 * string otherwise. 1199 */ 1200 public String preSharedKey; 1201 1202 /** 1203 * Four WEP keys. For each of the four values, provide either an ASCII 1204 * string enclosed in double quotation marks (e.g., {@code "abcdef"}) 1205 * or a string of hex digits (e.g., {@code 0102030405}). 1206 * <p/> 1207 * When the value of one of these keys is read, the actual key is 1208 * not returned, just a "*" if the key has a value, or the null 1209 * string otherwise. 1210 * @deprecated Due to security and performance limitations, use of WEP networks 1211 * is discouraged. 1212 */ 1213 @Deprecated 1214 public String[] wepKeys; 1215 1216 /** Default WEP key index, ranging from 0 to 3. 1217 * @deprecated Due to security and performance limitations, use of WEP networks 1218 * is discouraged. */ 1219 @Deprecated 1220 public int wepTxKeyIndex; 1221 1222 /** 1223 * Priority determines the preference given to a network by {@code wpa_supplicant} 1224 * when choosing an access point with which to associate. 1225 * @deprecated This field does not exist anymore. 1226 */ 1227 @Deprecated 1228 public int priority; 1229 1230 /** 1231 * The deletion priority of this configuration. 1232 * 1233 * Deletion priority is a non-negative value (default 0) indicating the priority for deletion 1234 * when auto-pruning the amount of saved configurations. Networks with a lower value will be 1235 * pruned before networks with a higher value. 1236 */ 1237 private int mDeletionPriority; 1238 1239 /** 1240 * Sets the deletion priority of this configuration. 1241 * 1242 * Deletion priority is a non-negative value (default 0) indicating the priority for deletion 1243 * when auto-pruning the amount of saved configurations. Networks with a lower value will be 1244 * pruned before networks with a higher value. 1245 * 1246 * @param priority non-negative deletion priority 1247 * @hide 1248 */ 1249 @SystemApi setDeletionPriority(int priority)1250 public void setDeletionPriority(int priority) throws IllegalArgumentException { 1251 if (priority < 0) { 1252 throw new IllegalArgumentException("Deletion priority must be non-negative"); 1253 } 1254 mDeletionPriority = priority; 1255 } 1256 1257 /** 1258 * Returns the deletion priority of this configuration. 1259 * 1260 * Deletion priority is a non-negative value (default 0) indicating the priority for deletion 1261 * when auto-pruning the amount of saved configurations. Networks with a lower value will be 1262 * pruned before networks with a higher value. 1263 * 1264 * @hide 1265 */ 1266 @SystemApi getDeletionPriority()1267 public int getDeletionPriority() { 1268 return mDeletionPriority; 1269 } 1270 1271 /** 1272 * This is a network that does not broadcast its SSID, so an 1273 * SSID-specific probe request must be used for scans. 1274 */ 1275 public boolean hiddenSSID; 1276 1277 /** 1278 * True if the network requires Protected Management Frames (PMF), false otherwise. 1279 * @hide 1280 */ 1281 @SystemApi 1282 public boolean requirePmf; 1283 1284 /** 1285 * Update identifier, for Passpoint network. 1286 * @hide 1287 */ 1288 public String updateIdentifier; 1289 1290 /** 1291 * The set of key management protocols supported by this configuration. 1292 * See {@link KeyMgmt} for descriptions of the values. 1293 * Defaults to WPA-PSK WPA-EAP. 1294 */ 1295 @NonNull 1296 public BitSet allowedKeyManagement; 1297 /** 1298 * The set of security protocols supported by this configuration. 1299 * See {@link Protocol} for descriptions of the values. 1300 * Defaults to WPA RSN. 1301 */ 1302 @NonNull 1303 public BitSet allowedProtocols; 1304 /** 1305 * The set of authentication protocols supported by this configuration. 1306 * See {@link AuthAlgorithm} for descriptions of the values. 1307 * Defaults to automatic selection. 1308 */ 1309 @NonNull 1310 public BitSet allowedAuthAlgorithms; 1311 /** 1312 * The set of pairwise ciphers for WPA supported by this configuration. 1313 * See {@link PairwiseCipher} for descriptions of the values. 1314 * Defaults to CCMP TKIP. 1315 */ 1316 @NonNull 1317 public BitSet allowedPairwiseCiphers; 1318 /** 1319 * The set of group ciphers supported by this configuration. 1320 * See {@link GroupCipher} for descriptions of the values. 1321 * Defaults to CCMP TKIP WEP104 WEP40. 1322 */ 1323 @NonNull 1324 public BitSet allowedGroupCiphers; 1325 /** 1326 * The set of group management ciphers supported by this configuration. 1327 * See {@link GroupMgmtCipher} for descriptions of the values. 1328 */ 1329 @NonNull 1330 public BitSet allowedGroupManagementCiphers; 1331 /** 1332 * The set of SuiteB ciphers supported by this configuration. 1333 * To be used for WPA3-Enterprise mode. Set automatically by the framework based on the 1334 * certificate type that is used in this configuration. 1335 */ 1336 @NonNull 1337 public BitSet allowedSuiteBCiphers; 1338 /** 1339 * The enterprise configuration details specifying the EAP method, 1340 * certificates and other settings associated with the EAP. 1341 */ 1342 public WifiEnterpriseConfig enterpriseConfig; 1343 1344 /** 1345 * Fully qualified domain name of a Passpoint configuration 1346 */ 1347 public String FQDN; 1348 1349 /** 1350 * Name of Passpoint credential provider 1351 */ 1352 public String providerFriendlyName; 1353 1354 /** 1355 * Flag indicating if this network is provided by a home Passpoint provider or a roaming 1356 * Passpoint provider. This flag will be {@code true} if this network is provided by 1357 * a home Passpoint provider and {@code false} if is provided by a roaming Passpoint provider 1358 * or is a non-Passpoint network. 1359 */ 1360 public boolean isHomeProviderNetwork; 1361 1362 /** 1363 * Roaming Consortium Id list for Passpoint credential; identifies a set of networks where 1364 * Passpoint credential will be considered valid 1365 */ 1366 public long[] roamingConsortiumIds; 1367 1368 /** 1369 * True if this network configuration is visible to and usable by other users on the 1370 * same device, false otherwise. 1371 * 1372 * @hide 1373 */ 1374 @SystemApi 1375 public boolean shared; 1376 1377 /** 1378 * @hide 1379 */ 1380 @NonNull 1381 @UnsupportedAppUsage 1382 private IpConfiguration mIpConfiguration; 1383 1384 /** 1385 * dhcp server MAC address if known 1386 * @hide 1387 */ 1388 public String dhcpServer; 1389 1390 /** 1391 * default Gateway MAC address if known 1392 * @hide 1393 */ 1394 @UnsupportedAppUsage 1395 public String defaultGwMacAddress; 1396 1397 /** 1398 * last time we connected, this configuration had validated internet access 1399 * @hide 1400 */ 1401 @UnsupportedAppUsage 1402 public boolean validatedInternetAccess; 1403 1404 /** 1405 * The number of beacon intervals between Delivery Traffic Indication Maps (DTIM) 1406 * This value is populated from scan results that contain Beacon Frames, which are infrequent. 1407 * The value is not guaranteed to be set or current (Although it SHOULDNT change once set) 1408 * Valid values are from 1 - 255. Initialized here as 0, use this to check if set. 1409 * @hide 1410 */ 1411 public int dtimInterval = 0; 1412 1413 /** 1414 * Flag indicating if this configuration represents a legacy Passpoint configuration 1415 * (Release N or older). This is used for migrating Passpoint configuration from N to O. 1416 * This will no longer be needed after O. 1417 * @hide 1418 */ 1419 public boolean isLegacyPasspointConfig = false; 1420 /** 1421 * Uid of app creating the configuration 1422 * @hide 1423 */ 1424 @SystemApi 1425 public int creatorUid; 1426 1427 /** 1428 * Uid of last app issuing a connection related command 1429 * @hide 1430 */ 1431 @SystemApi 1432 public int lastConnectUid; 1433 1434 /** 1435 * Uid of last app modifying the configuration 1436 * @hide 1437 */ 1438 @SystemApi 1439 public int lastUpdateUid; 1440 1441 /** 1442 * Universal name for app creating the configuration 1443 * see {@link PackageManager#getNameForUid(int)} 1444 * @hide 1445 */ 1446 @SystemApi 1447 public String creatorName; 1448 1449 /** 1450 * Universal name for app updating the configuration 1451 * see {@link PackageManager#getNameForUid(int)} 1452 * @hide 1453 */ 1454 @SystemApi 1455 public String lastUpdateName; 1456 1457 /** 1458 * The carrier ID identifies the operator who provides this network configuration. 1459 * see {@link TelephonyManager#getSimCarrierId()} 1460 * @hide 1461 */ 1462 @SystemApi 1463 public int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID; 1464 1465 /** 1466 * The subscription ID identifies the SIM card for which this network configuration is valid. 1467 * See {@link SubscriptionInfo#getSubscriptionId()} 1468 * @hide 1469 */ 1470 @SystemApi 1471 public int subscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 1472 1473 @Nullable 1474 private ParcelUuid mSubscriptionGroup = null; 1475 1476 /** 1477 * Auto-join is allowed by user for this network. 1478 * Default true. 1479 * @hide 1480 */ 1481 @SystemApi 1482 public boolean allowAutojoin = true; 1483 1484 /** 1485 * Wi-Fi7 is enabled by user for this network. 1486 * Default true. 1487 */ 1488 private boolean mWifi7Enabled = true; 1489 1490 /** 1491 * @hide 1492 */ setIpProvisioningTimedOut(boolean value)1493 public void setIpProvisioningTimedOut(boolean value) { 1494 mIpProvisioningTimedOut = value; 1495 } 1496 1497 /** 1498 * @hide 1499 */ isIpProvisioningTimedOut()1500 public boolean isIpProvisioningTimedOut() { 1501 return mIpProvisioningTimedOut; 1502 } 1503 1504 /** @hide **/ 1505 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 1506 public static int INVALID_RSSI = -127; 1507 1508 /** 1509 * Number of reports indicating no Internet Access 1510 * @hide 1511 */ 1512 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 1513 public int numNoInternetAccessReports; 1514 1515 /** 1516 * The WiFi configuration had no internet access the last time we connected to it. 1517 * @hide 1518 */ 1519 @SystemApi hasNoInternetAccess()1520 public boolean hasNoInternetAccess() { 1521 return getNetworkSelectionStatus().hasEverConnected() && !validatedInternetAccess; 1522 } 1523 1524 /** 1525 * The WiFi configuration is expected not to have Internet access (e.g., a wireless printer, a 1526 * Chromecast hotspot, etc.). This will be set if the user explicitly confirms a connection to 1527 * this configuration and selects "don't ask again". 1528 * @hide 1529 */ 1530 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 1531 public boolean noInternetAccessExpected; 1532 1533 /** 1534 * The WiFi configuration is expected not to have Internet access (e.g., a wireless printer, a 1535 * Chromecast hotspot, etc.). This will be set if the user explicitly confirms a connection to 1536 * this configuration and selects "don't ask again". 1537 * @hide 1538 */ 1539 @SystemApi isNoInternetAccessExpected()1540 public boolean isNoInternetAccessExpected() { 1541 return noInternetAccessExpected; 1542 } 1543 1544 /** 1545 * This Wifi configuration is expected for OSU(Online Sign Up) of Passpoint Release 2. 1546 * @hide 1547 */ 1548 public boolean osu; 1549 1550 /** 1551 * Last time the system was connected to this configuration represented as the difference, 1552 * measured in milliseconds, between the last connected time and midnight, January 1, 1970 UTC. 1553 * <P> 1554 * Note that this information is only in memory will be cleared (reset to 0) for all 1555 * WifiConfiguration(s) after a reboot. 1556 * @hide 1557 */ 1558 @SuppressLint("MutableBareField") 1559 @SystemApi 1560 public long lastConnected; 1561 1562 /** 1563 * Last time the system was disconnected to this configuration. 1564 * @hide 1565 */ 1566 public long lastDisconnected; 1567 1568 /** 1569 * Last time this configuration was updated or created. 1570 * Note: This field only exists in-memory and is not persisted in WifiConfigStore.xml for 1571 * privacy reasons. 1572 * @hide 1573 */ 1574 public long lastUpdated; 1575 1576 /** 1577 * Number of reboots since this config was last used (either connected or updated). 1578 * @hide 1579 */ 1580 @SuppressLint("MutableBareField") 1581 @SystemApi 1582 public int numRebootsSinceLastUse; 1583 1584 /** 1585 * Set if the configuration was self added by the framework 1586 * This boolean is cleared if we get a connect/save/ update or 1587 * any wifiManager command that indicate the user interacted with the configuration 1588 * since we will now consider that the configuration belong to him. 1589 * @deprecated only kept for @UnsupportedAppUsage 1590 * @hide 1591 */ 1592 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 1593 public boolean selfAdded; 1594 1595 /** 1596 * Peer WifiConfiguration this WifiConfiguration was added for 1597 * @hide 1598 */ 1599 public String peerWifiConfiguration; 1600 1601 /** 1602 * Indicate that a WifiConfiguration is temporary and should not be saved 1603 * nor considered by AutoJoin. 1604 * @hide 1605 */ 1606 public boolean ephemeral; 1607 1608 /** 1609 * Indicate that a WifiConfiguration is temporary and should not be saved 1610 * nor considered by AutoJoin. 1611 * @hide 1612 */ 1613 @SystemApi isEphemeral()1614 public boolean isEphemeral() { 1615 return ephemeral; 1616 } 1617 1618 /** 1619 * Indicate whether the network is trusted or not. Networks are considered trusted 1620 * if the user explicitly allowed this network connection. 1621 * This bit can be used by suggestion network, see 1622 * {@link WifiNetworkSuggestion.Builder#setUntrusted(boolean)} 1623 * @hide 1624 */ 1625 public boolean trusted; 1626 1627 /** 1628 * Indicate whether the network is oem paid or not. Networks are considered oem paid 1629 * if the corresponding connection is only available to system apps. 1630 * 1631 * This bit can only be used by suggestion network, see 1632 * {@link WifiNetworkSuggestion.Builder#setOemPaid(boolean)} 1633 * @hide 1634 */ 1635 public boolean oemPaid; 1636 1637 1638 /** 1639 * Indicate whether the network is oem private or not. Networks are considered oem private 1640 * if the corresponding connection is only available to system apps. 1641 * 1642 * This bit can only be used by suggestion network, see 1643 * {@link WifiNetworkSuggestion.Builder#setOemPrivate(boolean)} 1644 * @hide 1645 */ 1646 public boolean oemPrivate; 1647 1648 /** 1649 * Indicate whether or not the network is a carrier merged network. 1650 * This bit can only be used by suggestion network, see 1651 * {@link WifiNetworkSuggestion.Builder#setCarrierMerged(boolean)} 1652 * @hide 1653 */ 1654 @SystemApi 1655 public boolean carrierMerged; 1656 1657 /** 1658 * True if this Wifi configuration is created from a {@link WifiNetworkSuggestion}, 1659 * false otherwise. 1660 * 1661 * @hide 1662 */ 1663 @SystemApi 1664 public boolean fromWifiNetworkSuggestion; 1665 1666 /** 1667 * True if this Wifi configuration is created from a {@link WifiNetworkSpecifier}, 1668 * false otherwise. 1669 * 1670 * @hide 1671 */ 1672 @SystemApi 1673 public boolean fromWifiNetworkSpecifier; 1674 1675 /** 1676 * True if the creator of this configuration has expressed that it 1677 * should be considered metered, false otherwise. 1678 * 1679 * @see #isMetered(WifiConfiguration, WifiInfo) 1680 * 1681 * @hide 1682 */ 1683 @SystemApi 1684 public boolean meteredHint; 1685 1686 /** 1687 * True if this configuration is intended to be repeater enabled to expand coverage. 1688 */ 1689 private boolean mIsRepeaterEnabled; 1690 1691 /** 1692 * @hide 1693 */ 1694 private boolean mIpProvisioningTimedOut; 1695 1696 /** 1697 * Sets if this configuration is intended to be repeater enabled for expanded coverage. 1698 * 1699 * @param isRepeaterEnabled true if this network is intended to be repeater enabled, 1700 * false otherwise. 1701 * 1702 * This request is only accepted if the caller is holding 1703 * {@link android.Manifest.permission#NETWORK_SETTINGS}. 1704 * 1705 * @hide 1706 */ 1707 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) 1708 @SystemApi setRepeaterEnabled(boolean isRepeaterEnabled)1709 public void setRepeaterEnabled(boolean isRepeaterEnabled) { 1710 mIsRepeaterEnabled = isRepeaterEnabled; 1711 } 1712 1713 /** 1714 * Returns if this configuration is intended to be repeater enabled for expanded coverage. 1715 * 1716 * @return true if this network is intended to be repeater enabled, false otherwise. 1717 * 1718 * @hide 1719 */ 1720 @SystemApi isRepeaterEnabled()1721 public boolean isRepeaterEnabled() { 1722 return mIsRepeaterEnabled; 1723 } 1724 1725 /** 1726 * Indicate whether the network is restricted or not. 1727 * 1728 * This bit can only be used by suggestion network, see 1729 * {@link WifiNetworkSuggestion.Builder#setRestricted(boolean)} 1730 * @hide 1731 */ 1732 public boolean restricted; 1733 1734 /** @hide */ 1735 @Retention(RetentionPolicy.SOURCE) 1736 @IntDef(prefix = {"METERED_OVERRIDE_"}, value = { 1737 METERED_OVERRIDE_NONE, 1738 METERED_OVERRIDE_METERED, 1739 METERED_OVERRIDE_NOT_METERED}) 1740 public @interface MeteredOverride {} 1741 1742 /** 1743 * No metered override. 1744 * @hide 1745 */ 1746 @SystemApi 1747 public static final int METERED_OVERRIDE_NONE = 0; 1748 /** 1749 * Override network to be metered. 1750 * @hide 1751 */ 1752 @SystemApi 1753 public static final int METERED_OVERRIDE_METERED = 1; 1754 /** 1755 * Override network to be unmetered. 1756 * @hide 1757 */ 1758 @SystemApi 1759 public static final int METERED_OVERRIDE_NOT_METERED = 2; 1760 1761 /** 1762 * Indicates if the end user has expressed an explicit opinion about the 1763 * meteredness of this network, such as through the Settings app. 1764 * This value is one of {@link #METERED_OVERRIDE_NONE}, {@link #METERED_OVERRIDE_METERED}, 1765 * or {@link #METERED_OVERRIDE_NOT_METERED}. 1766 * <p> 1767 * This should always override any values from {@link #meteredHint} or 1768 * {@link WifiInfo#getMeteredHint()}. 1769 * 1770 * By default this field is set to {@link #METERED_OVERRIDE_NONE}. 1771 * 1772 * @see #isMetered(WifiConfiguration, WifiInfo) 1773 * @hide 1774 */ 1775 @SystemApi 1776 @MeteredOverride 1777 public int meteredOverride = METERED_OVERRIDE_NONE; 1778 1779 /** 1780 * Blend together all the various opinions to decide if the given network 1781 * should be considered metered or not. 1782 * 1783 * @hide 1784 */ 1785 @SystemApi isMetered(@ullable WifiConfiguration config, @Nullable WifiInfo info)1786 public static boolean isMetered(@Nullable WifiConfiguration config, @Nullable WifiInfo info) { 1787 boolean metered = false; 1788 if (info != null && info.getMeteredHint()) { 1789 metered = true; 1790 } 1791 if (config != null && config.meteredHint) { 1792 metered = true; 1793 } 1794 if (config != null 1795 && config.meteredOverride == WifiConfiguration.METERED_OVERRIDE_METERED) { 1796 metered = true; 1797 } 1798 if (config != null 1799 && config.meteredOverride == WifiConfiguration.METERED_OVERRIDE_NOT_METERED) { 1800 metered = false; 1801 } 1802 return metered; 1803 } 1804 1805 /** Check whether wep keys exist. */ hasWepKeys()1806 private boolean hasWepKeys() { 1807 if (wepKeys == null) return false; 1808 for (int i = 0; i < wepKeys.length; i++) { 1809 if (wepKeys[i] != null) { 1810 return true; 1811 } 1812 } 1813 return false; 1814 } 1815 1816 /** 1817 * Returns true if this WiFi config is for an Open or Enhanced Open network. 1818 * @hide 1819 */ isOpenNetwork()1820 public boolean isOpenNetwork() { 1821 if (hasWepKeys()) { 1822 return false; 1823 } 1824 for (SecurityParams p : mSecurityParamsList) { 1825 if (!p.isOpenSecurityType()) { 1826 return false; 1827 } 1828 } 1829 return true; 1830 } 1831 1832 /** 1833 * Setting this value will force scan results associated with this configuration to 1834 * be included in the bucket of networks that are externally scored. 1835 * If not set, associated scan results will be treated as legacy saved networks and 1836 * will take precedence over networks in the scored category. 1837 * @hide 1838 */ 1839 @SystemApi 1840 public boolean useExternalScores; 1841 1842 /** 1843 * Number of time the scorer overrode a the priority based choice, when comparing two 1844 * WifiConfigurations, note that since comparing WifiConfiguration happens very often 1845 * potentially at every scan, this number might become very large, even on an idle 1846 * system. 1847 * @hide 1848 */ 1849 @SystemApi 1850 public int numScorerOverride; 1851 1852 /** 1853 * Number of time the scorer overrode a the priority based choice, and the comparison 1854 * triggered a network switch 1855 * @hide 1856 */ 1857 @SystemApi 1858 public int numScorerOverrideAndSwitchedNetwork; 1859 1860 /** 1861 * Number of times we associated to this configuration. 1862 * @hide 1863 */ 1864 @SystemApi 1865 public int numAssociation; 1866 1867 /** @hide */ 1868 @Retention(RetentionPolicy.SOURCE) 1869 @IntDef(prefix = {"RANDOMIZATION_"}, value = { 1870 RANDOMIZATION_NONE, 1871 RANDOMIZATION_PERSISTENT, 1872 RANDOMIZATION_NON_PERSISTENT, 1873 RANDOMIZATION_AUTO}) 1874 public @interface MacRandomizationSetting {} 1875 1876 /** 1877 * Use factory MAC when connecting to this network 1878 */ 1879 public static final int RANDOMIZATION_NONE = 0; 1880 1881 /** 1882 * Generate a randomized MAC once and reuse it for all connections to this network 1883 */ 1884 public static final int RANDOMIZATION_PERSISTENT = 1; 1885 1886 /** 1887 * Use a randomly generated MAC address for connections to this network. 1888 * This option does not persist the randomized MAC address. 1889 */ 1890 public static final int RANDOMIZATION_NON_PERSISTENT = 2; 1891 1892 /** 1893 * Let the wifi framework automatically decide the MAC randomization strategy. 1894 */ 1895 public static final int RANDOMIZATION_AUTO = 3; 1896 1897 /** 1898 * Level of MAC randomization for this network. 1899 * One of {@link #RANDOMIZATION_NONE}, {@link #RANDOMIZATION_AUTO}, 1900 * {@link #RANDOMIZATION_PERSISTENT} or {@link #RANDOMIZATION_NON_PERSISTENT}. 1901 * By default this field is set to {@link #RANDOMIZATION_AUTO}. 1902 * @hide 1903 */ 1904 @SystemApi 1905 @MacRandomizationSetting 1906 public int macRandomizationSetting = RANDOMIZATION_AUTO; 1907 1908 /** 1909 * Set the MAC randomization setting for this network. 1910 * <p> 1911 * Caller must satify one of the following conditions: 1912 * </p> 1913 * <ul> 1914 * <li>Have {@code android.Manifest.permission#NETWORK_SETTINGS} permission.</li> 1915 * <li>Have {@code android.Manifest.permission#NETWORK_SETUP_WIZARD} permission.</li> 1916 * <li>Be in Demo Mode.</li> 1917 * <li>Be the creator adding or updating a passpoint network.</li> 1918 * <li>Be an admin updating their own network.</li> 1919 * </ul> 1920 */ setMacRandomizationSetting(@acRandomizationSetting int macRandomizationSetting)1921 public void setMacRandomizationSetting(@MacRandomizationSetting int macRandomizationSetting) { 1922 this.macRandomizationSetting = macRandomizationSetting; 1923 } 1924 1925 /** 1926 * Get the MAC randomization setting for this network. 1927 */ getMacRandomizationSetting()1928 public @MacRandomizationSetting int getMacRandomizationSetting() { 1929 return this.macRandomizationSetting; 1930 } 1931 1932 /** 1933 * Randomized MAC address to use with this particular network 1934 * @hide 1935 */ 1936 @NonNull 1937 private MacAddress mRandomizedMacAddress; 1938 1939 /** 1940 * The wall clock time of when |mRandomizedMacAddress| should be re-randomized in non-persistent 1941 * MAC randomization mode. 1942 * @hide 1943 */ 1944 public long randomizedMacExpirationTimeMs = 0; 1945 1946 /** 1947 * The wall clock time of when |mRandomizedMacAddress| is last modified. 1948 * @hide 1949 */ 1950 public long randomizedMacLastModifiedTimeMs = 0; 1951 1952 /** 1953 * Checks if the given MAC address can be used for Connected Mac Randomization 1954 * by verifying that it is non-null, unicast, locally assigned, and not default mac. 1955 * @param mac MacAddress to check 1956 * @return true if mac is good to use 1957 * @hide 1958 */ isValidMacAddressForRandomization(MacAddress mac)1959 public static boolean isValidMacAddressForRandomization(MacAddress mac) { 1960 return mac != null && !MacAddressUtils.isMulticastAddress(mac) && mac.isLocallyAssigned() 1961 && !MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS).equals(mac); 1962 } 1963 1964 /** 1965 * Returns MAC address set to be the local randomized MAC address. 1966 * Depending on user preference, the device may or may not use the returned MAC address for 1967 * connections to this network. 1968 * <p> 1969 * Information is restricted to Device Owner, Profile Owner, and Carrier apps 1970 * (which will only obtain addresses for configurations which they create). Other callers 1971 * will receive a default "02:00:00:00:00:00" MAC address. 1972 */ getRandomizedMacAddress()1973 public @NonNull MacAddress getRandomizedMacAddress() { 1974 return mRandomizedMacAddress; 1975 } 1976 1977 /** 1978 * @param mac MacAddress to change into 1979 * @hide 1980 */ setRandomizedMacAddress(@onNull MacAddress mac)1981 public void setRandomizedMacAddress(@NonNull MacAddress mac) { 1982 if (mac == null) { 1983 Log.e(TAG, "setRandomizedMacAddress received null MacAddress."); 1984 return; 1985 } 1986 mRandomizedMacAddress = mac; 1987 } 1988 1989 private boolean mIsSendDhcpHostnameEnabled = true; 1990 1991 /** 1992 * Set whether to send the hostname of the device to this network's DHCP server. 1993 * 1994 * @param enabled {@code true} to send the hostname during DHCP, 1995 * {@code false} to not send the hostname during DHCP. 1996 * @hide 1997 */ 1998 @RequiresPermission(anyOf = { 1999 android.Manifest.permission.NETWORK_SETTINGS, 2000 android.Manifest.permission.NETWORK_SETUP_WIZARD}) 2001 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 2002 @SystemApi setSendDhcpHostnameEnabled(boolean enabled)2003 public void setSendDhcpHostnameEnabled(boolean enabled) { 2004 mIsSendDhcpHostnameEnabled = enabled; 2005 } 2006 2007 /** 2008 * Whether to send the hostname of the device to this network's DHCP server. 2009 * @hide 2010 */ 2011 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 2012 @SystemApi isSendDhcpHostnameEnabled()2013 public boolean isSendDhcpHostnameEnabled() { 2014 return mIsSendDhcpHostnameEnabled; 2015 } 2016 2017 /** 2018 * This network supports DPP AKM and the device is configured to 2019 * onboard peer enrollee devices with {@link #SECURITY_TYPE_DPP} 2020 * @hide 2021 */ 2022 private boolean mIsDppConfigurator; 2023 2024 /** 2025 * Private elliptic curve key used by DPP Configurator to generate other DPP Keys 2026 * for DPP-AKM based network configuration. 2027 * @hide 2028 */ 2029 private byte[] mDppPrivateEcKey; 2030 2031 /** 2032 * Signed DPP connector. The connector is used by a pair of Enrollee devices to establish 2033 * a security association using the DPP Introduction Protocol. 2034 * @hide 2035 */ 2036 private byte[] mDppConnector; 2037 2038 /** 2039 * The public signing key of the DPP configurator. 2040 * @hide 2041 */ 2042 private byte[] mDppCSignKey; 2043 2044 /** 2045 * DPP network access key (own private key) 2046 * @hide 2047 */ 2048 private byte[] mDppNetAccessKey; 2049 2050 /** 2051 * Set DPP Connection keys which are used for network access. 2052 * This is required for SECURITY_TYPE_DPP network connection. 2053 * @hide 2054 */ setDppConnectionKeys(byte[] connector, byte[] cSignKey, byte[] netAccessKey)2055 public void setDppConnectionKeys(byte[] connector, byte[] cSignKey, byte[] netAccessKey) { 2056 if (connector == null || cSignKey == null || netAccessKey == null) { 2057 Log.e(TAG, "One of DPP key is null"); 2058 return; 2059 } 2060 mDppConnector = connector.clone(); 2061 mDppCSignKey = cSignKey.clone(); 2062 mDppNetAccessKey = netAccessKey.clone(); 2063 } 2064 2065 /** 2066 * Allow this profile as configurable DPP profile. 2067 * This is required to allow SECURITY_TYPE_DPP profile to be eligible for Configuration 2068 * of DPP-Enrollees. 2069 * @hide 2070 */ setDppConfigurator(byte[] ecKey)2071 public void setDppConfigurator(byte[] ecKey) { 2072 if (ecKey != null) { 2073 mDppPrivateEcKey = ecKey.clone(); 2074 mIsDppConfigurator = true; 2075 } 2076 } 2077 2078 /** 2079 * To check if this WifiConfiguration supports configuring a peer Enrollee device with 2080 * SECURITY_TYPE_DPP 2081 */ isDppConfigurator()2082 public boolean isDppConfigurator() { 2083 return mIsDppConfigurator; 2084 } 2085 2086 /** 2087 * Get private elliptic curve key used by DPP Configurator to generate other DPP Keys 2088 * for DPP-AKM based network configuration. 2089 * @hide 2090 */ 2091 @SystemApi getDppPrivateEcKey()2092 @NonNull public byte[] getDppPrivateEcKey() { 2093 return mDppPrivateEcKey.clone(); 2094 } 2095 2096 /** 2097 * Get DPP signed connector. The connector is used by a pair of Enrollee devices to establish 2098 * a security association using the DPP Introduction Protocol. 2099 * @hide 2100 */ 2101 @SystemApi getDppConnector()2102 @NonNull public byte[] getDppConnector() { 2103 return mDppConnector.clone(); 2104 } 2105 2106 /** 2107 * Get public signing key of the DPP configurator. This key is used by provisioned devices 2108 * to verify Connectors of other devices are signed by the same Configurator. The configurator 2109 * derives and sets the C-sign-key in each DPP Configuration object. 2110 * 2111 * @hide 2112 */ 2113 @SystemApi getDppCSignKey()2114 @NonNull public byte[] getDppCSignKey() { 2115 return mDppCSignKey.clone(); 2116 } 2117 2118 /** 2119 * Get DPP network access key. Own private key used to generate common secret, PMK. 2120 * @hide 2121 */ 2122 @SystemApi getDppNetAccessKey()2123 @NonNull public byte[] getDppNetAccessKey() { 2124 return mDppNetAccessKey.clone(); 2125 } 2126 2127 /** @hide 2128 * Boost given to RSSI on a home network for the purpose of calculating the score 2129 * This adds stickiness to home networks, as defined by: 2130 * - less than 4 known BSSIDs 2131 * - PSK only 2132 * - TODO: add a test to verify that all BSSIDs are behind same gateway 2133 ***/ 2134 public static final int HOME_NETWORK_RSSI_BOOST = 5; 2135 2136 /** 2137 * This class is used to contain all the information and API used for quality network selection. 2138 * @hide 2139 */ 2140 @SystemApi 2141 public static class NetworkSelectionStatus { 2142 /** @hide */ 2143 @Retention(RetentionPolicy.SOURCE) 2144 @IntDef(prefix = "NETWORK_SELECTION_", 2145 value = { 2146 NETWORK_SELECTION_ENABLED, 2147 NETWORK_SELECTION_TEMPORARY_DISABLED, 2148 NETWORK_SELECTION_PERMANENTLY_DISABLED}) 2149 public @interface NetworkEnabledStatus {} 2150 /** 2151 * This network will be considered as a potential candidate to connect to during network 2152 * selection. 2153 */ 2154 public static final int NETWORK_SELECTION_ENABLED = 0; 2155 /** 2156 * This network was temporary disabled. May be re-enabled after a time out. 2157 */ 2158 public static final int NETWORK_SELECTION_TEMPORARY_DISABLED = 1; 2159 /** 2160 * This network was permanently disabled. 2161 */ 2162 public static final int NETWORK_SELECTION_PERMANENTLY_DISABLED = 2; 2163 /** 2164 * Maximum Network selection status 2165 * @hide 2166 */ 2167 public static final int NETWORK_SELECTION_STATUS_MAX = 3; 2168 2169 /** 2170 * Quality network selection status String (for debug purpose). Use Quality network 2171 * selection status value as index to extec the corresponding debug string 2172 * @hide 2173 */ 2174 public static final String[] QUALITY_NETWORK_SELECTION_STATUS = { 2175 "NETWORK_SELECTION_ENABLED", 2176 "NETWORK_SELECTION_TEMPORARY_DISABLED", 2177 "NETWORK_SELECTION_PERMANENTLY_DISABLED"}; 2178 2179 /** @hide */ 2180 @Retention(RetentionPolicy.SOURCE) 2181 @IntDef(prefix = "DISABLED_", value = { 2182 DISABLED_NONE, 2183 DISABLED_ASSOCIATION_REJECTION, 2184 DISABLED_AUTHENTICATION_FAILURE, 2185 DISABLED_DHCP_FAILURE, 2186 DISABLED_NO_INTERNET_TEMPORARY, 2187 DISABLED_AUTHENTICATION_NO_CREDENTIALS, 2188 DISABLED_NO_INTERNET_PERMANENT, 2189 DISABLED_BY_WIFI_MANAGER, 2190 DISABLED_BY_WRONG_PASSWORD, 2191 DISABLED_AUTHENTICATION_NO_SUBSCRIPTION, 2192 DISABLED_AUTHENTICATION_PRIVATE_EAP_ERROR, 2193 DISABLED_NETWORK_NOT_FOUND, 2194 DISABLED_CONSECUTIVE_FAILURES, 2195 DISABLED_UNWANTED_LOW_RSSI, 2196 DISABLED_REPEATED_NUD_FAILURES}) 2197 public @interface NetworkSelectionDisableReason {} 2198 2199 // Quality Network disabled reasons 2200 /** Default value. Means not disabled. */ 2201 public static final int DISABLED_NONE = 0; 2202 /** 2203 * The starting index for network selection disabled reasons. 2204 * @hide 2205 */ 2206 public static final int NETWORK_SELECTION_DISABLED_STARTING_INDEX = 1; 2207 /** This network is temporarily disabled because of multiple association rejections. */ 2208 public static final int DISABLED_ASSOCIATION_REJECTION = 1; 2209 /** This network is temporarily disabled because of multiple authentication failure. */ 2210 public static final int DISABLED_AUTHENTICATION_FAILURE = 2; 2211 /** This network is temporarily disabled because of multiple DHCP failure. */ 2212 public static final int DISABLED_DHCP_FAILURE = 3; 2213 /** This network is temporarily disabled because it has no Internet access. */ 2214 public static final int DISABLED_NO_INTERNET_TEMPORARY = 4; 2215 /** This network is permanently disabled due to absence of user credentials */ 2216 public static final int DISABLED_AUTHENTICATION_NO_CREDENTIALS = 5; 2217 /** 2218 * This network is permanently disabled because it has no Internet access and the user does 2219 * not want to stay connected. 2220 */ 2221 public static final int DISABLED_NO_INTERNET_PERMANENT = 6; 2222 /** This network is permanently disabled due to WifiManager disabling it explicitly. */ 2223 public static final int DISABLED_BY_WIFI_MANAGER = 7; 2224 /** This network is permanently disabled due to wrong password. */ 2225 public static final int DISABLED_BY_WRONG_PASSWORD = 8; 2226 /** This network is permanently disabled because service is not subscribed. */ 2227 public static final int DISABLED_AUTHENTICATION_NO_SUBSCRIPTION = 9; 2228 /** This network is disabled due to provider-specific (private) EAP failure. */ 2229 public static final int DISABLED_AUTHENTICATION_PRIVATE_EAP_ERROR = 10; 2230 /** 2231 * This network is disabled because supplicant failed to find a network in scan result 2232 * which matches the network requested by framework for connection 2233 * (including network capabilities). 2234 */ 2235 public static final int DISABLED_NETWORK_NOT_FOUND = 11; 2236 /** 2237 * This code is used to disable a network when a high number of consecutive connection 2238 * failures are detected. The exact reasons of why these consecutive failures occurred is 2239 * included but not limited to the reasons described by failure codes above. 2240 */ 2241 public static final int DISABLED_CONSECUTIVE_FAILURES = 12; 2242 /** 2243 * This code is used to disable a network when a security params is disabled 2244 * by the transition disable indication. 2245 */ 2246 public static final int DISABLED_TRANSITION_DISABLE_INDICATION = 13; 2247 /** 2248 * This network is temporarily disabled because of unwanted network under sufficient rssi. 2249 */ 2250 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 2251 public static final int DISABLED_UNWANTED_LOW_RSSI = 14; 2252 /** 2253 * This network is temporarily disabled due to repeated IP reachability failures. 2254 * @hide 2255 */ 2256 public static final int DISABLED_REPEATED_NUD_FAILURES = 15; 2257 /** 2258 * All other disable reasons should be strictly less than this value. 2259 * @hide 2260 */ 2261 public static final int NETWORK_SELECTION_DISABLED_MAX = 16; 2262 2263 /** 2264 * Get an integer that is equal to the maximum integer value of all the 2265 * DISABLED_* reasons 2266 * e.g. {@link #DISABLED_NONE}, {@link #DISABLED_ASSOCIATION_REJECTION}, etc. 2267 * 2268 * All DISABLED_* constants will be contiguous in the range 2269 * 0, 1, 2, 3, ..., getMaxNetworkSelectionDisableReasons() 2270 * 2271 * <br /> 2272 * For example, this can be used to iterate through all the network selection 2273 * disable reasons like so: 2274 * <pre>{@code 2275 * for (int reason = 0; reason <= getMaxNetworkSelectionDisableReasons(); reason++) { 2276 * ... 2277 * } 2278 * }</pre> 2279 */ getMaxNetworkSelectionDisableReason()2280 public static int getMaxNetworkSelectionDisableReason() { 2281 return NETWORK_SELECTION_DISABLED_MAX - 1; 2282 } 2283 2284 /** 2285 * Contains info about disable reasons. 2286 * @hide 2287 */ 2288 public static final class DisableReasonInfo { 2289 /** 2290 * A special constant which indicates the network should be permanently disabled. 2291 * @hide 2292 */ 2293 public static final int PERMANENT_DISABLE_TIMEOUT = -1; 2294 /** 2295 * String representation for the disable reason. 2296 * Note that these strings are persisted in 2297 * {@link 2298 * com.android.server.wifi.util.XmlUtil.NetworkSelectionStatusXmlUtil#writeToXml}, 2299 * so do not change the string values to maintain backwards compatibility. 2300 */ 2301 public final String mReasonStr; 2302 /** 2303 * Network Selection disable reason threshold, used to debounce network failures before 2304 * we disable them. 2305 */ 2306 public final int mDisableThreshold; 2307 /** 2308 * Network Selection disable timeout for the error. After the timeout milliseconds, 2309 * enable the network again. 2310 * If this is set to PERMANENT_DISABLE_TIMEOUT, the network will be permanently disabled 2311 * until the next time the user manually connects to it. 2312 */ 2313 public final int mDisableTimeoutMillis; 2314 2315 /** 2316 * Constructor 2317 * @param reasonStr string representation of the error 2318 * @param disableThreshold number of failures before we disable the network 2319 * @param disableTimeoutMillis the timeout, in milliseconds, before we re-enable the 2320 * network after disabling it 2321 */ DisableReasonInfo(String reasonStr, int disableThreshold, int disableTimeoutMillis)2322 public DisableReasonInfo(String reasonStr, int disableThreshold, 2323 int disableTimeoutMillis) { 2324 mReasonStr = reasonStr; 2325 mDisableThreshold = disableThreshold; 2326 mDisableTimeoutMillis = disableTimeoutMillis; 2327 } 2328 } 2329 2330 /** 2331 * Quality network selection disable reason infos. 2332 * @hide 2333 */ 2334 public static final SparseArray<DisableReasonInfo> DISABLE_REASON_INFOS = 2335 buildDisableReasonInfos(); 2336 buildDisableReasonInfos()2337 private static SparseArray<DisableReasonInfo> buildDisableReasonInfos() { 2338 SparseArray<DisableReasonInfo> reasons = new SparseArray<>(); 2339 2340 // Note that some of these disable thresholds are overridden in 2341 // WifiBlocklistMonitor#loadCustomConfigsForDisableReasonInfos using overlays. 2342 // TODO(b/180148727): For a few of these disable reasons, we provide defaults here 2343 // and in the overlay XML, which is confusing. Clean this up so we only define the 2344 // default in one place. 2345 2346 reasons.append(DISABLED_NONE, 2347 new DisableReasonInfo( 2348 // Note that these strings are persisted in 2349 // XmlUtil.NetworkSelectionStatusXmlUtil#writeToXml, 2350 // so do not change the string values to maintain backwards 2351 // compatibility. 2352 "NETWORK_SELECTION_ENABLE", 2353 -1, 2354 0)); 2355 2356 reasons.append(DISABLED_ASSOCIATION_REJECTION, 2357 new DisableReasonInfo( 2358 // Note that there is a space at the end of this string. Cannot fix 2359 // since this string is persisted. 2360 "NETWORK_SELECTION_DISABLED_ASSOCIATION_REJECTION ", 2361 3, 2362 5 * 60 * 1000)); 2363 2364 reasons.append(DISABLED_AUTHENTICATION_FAILURE, 2365 new DisableReasonInfo( 2366 "NETWORK_SELECTION_DISABLED_AUTHENTICATION_FAILURE", 2367 3, 2368 5 * 60 * 1000)); 2369 2370 reasons.append(DISABLED_DHCP_FAILURE, 2371 new DisableReasonInfo( 2372 "NETWORK_SELECTION_DISABLED_DHCP_FAILURE", 2373 2, 2374 5 * 60 * 1000)); 2375 2376 reasons.append(DISABLED_NO_INTERNET_TEMPORARY, 2377 new DisableReasonInfo( 2378 "NETWORK_SELECTION_DISABLED_NO_INTERNET_TEMPORARY", 2379 1, 2380 10 * 60 * 1000)); 2381 2382 reasons.append(DISABLED_AUTHENTICATION_NO_CREDENTIALS, 2383 new DisableReasonInfo( 2384 "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_CREDENTIALS", 2385 3, 2386 DisableReasonInfo.PERMANENT_DISABLE_TIMEOUT)); 2387 2388 reasons.append(DISABLED_NO_INTERNET_PERMANENT, 2389 new DisableReasonInfo( 2390 "NETWORK_SELECTION_DISABLED_NO_INTERNET_PERMANENT", 2391 1, 2392 DisableReasonInfo.PERMANENT_DISABLE_TIMEOUT)); 2393 2394 reasons.append(DISABLED_BY_WIFI_MANAGER, 2395 new DisableReasonInfo( 2396 "NETWORK_SELECTION_DISABLED_BY_WIFI_MANAGER", 2397 1, 2398 DisableReasonInfo.PERMANENT_DISABLE_TIMEOUT)); 2399 2400 reasons.append(DISABLED_BY_WRONG_PASSWORD, 2401 new DisableReasonInfo( 2402 "NETWORK_SELECTION_DISABLED_BY_WRONG_PASSWORD", 2403 1, 2404 DisableReasonInfo.PERMANENT_DISABLE_TIMEOUT)); 2405 2406 reasons.append(DISABLED_AUTHENTICATION_NO_SUBSCRIPTION, 2407 new DisableReasonInfo( 2408 "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_SUBSCRIPTION", 2409 1, 2410 DisableReasonInfo.PERMANENT_DISABLE_TIMEOUT)); 2411 2412 reasons.append(DISABLED_AUTHENTICATION_PRIVATE_EAP_ERROR, 2413 new DisableReasonInfo( 2414 "NETWORK_SELECTION_DISABLED_AUTHENTICATION_PRIVATE_EAP_ERROR", 2415 1, 2416 DisableReasonInfo.PERMANENT_DISABLE_TIMEOUT)); 2417 2418 reasons.append(DISABLED_NETWORK_NOT_FOUND, 2419 new DisableReasonInfo( 2420 "NETWORK_SELECTION_DISABLED_NETWORK_NOT_FOUND", 2421 2, 2422 5 * 60 * 1000)); 2423 2424 reasons.append(DISABLED_CONSECUTIVE_FAILURES, 2425 new DisableReasonInfo("NETWORK_SELECTION_DISABLED_CONSECUTIVE_FAILURES", 2426 1, 2427 5 * 60 * 1000)); 2428 2429 reasons.append(DISABLED_TRANSITION_DISABLE_INDICATION, 2430 new DisableReasonInfo( 2431 "NETWORK_SELECTION_DISABLED_TRANSITION_DISABLE_INDICATION", 2432 1, 2433 DisableReasonInfo.PERMANENT_DISABLE_TIMEOUT)); 2434 2435 reasons.append(DISABLED_UNWANTED_LOW_RSSI, 2436 new DisableReasonInfo("NETWORK_SELECTION_DISABLED_UNWANTED_LOW_RSSI", 2437 1, 2438 30 * 1000)); 2439 reasons.append(DISABLED_REPEATED_NUD_FAILURES, 2440 new DisableReasonInfo("NETWORK_SELECTION_DISABLED_REPEATED_NUD_FAILURES", 2441 1, 2442 15 * 60 * 1000)); 2443 return reasons; 2444 } 2445 2446 /** 2447 * Get the {@link NetworkSelectionDisableReason} int code by its string value. 2448 * @return the NetworkSelectionDisableReason int code corresponding to the reason string, 2449 * or -1 if the reason string is unrecognized. 2450 * @hide 2451 */ 2452 @NetworkSelectionDisableReason getDisableReasonByString(@onNull String reasonString)2453 public static int getDisableReasonByString(@NonNull String reasonString) { 2454 for (int i = 0; i < DISABLE_REASON_INFOS.size(); i++) { 2455 int key = DISABLE_REASON_INFOS.keyAt(i); 2456 DisableReasonInfo value = DISABLE_REASON_INFOS.valueAt(i); 2457 if (value != null && TextUtils.equals(reasonString, value.mReasonStr)) { 2458 return key; 2459 } 2460 } 2461 Log.e(TAG, "Unrecognized network disable reason: " + reasonString); 2462 return -1; 2463 } 2464 2465 /** 2466 * Invalid time stamp for network selection disable 2467 * @hide 2468 */ 2469 public static final long INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP = -1L; 2470 2471 /** 2472 * This constant indicates the current configuration has connect choice set 2473 */ 2474 private static final int CONNECT_CHOICE_EXISTS = 1; 2475 2476 /** 2477 * This constant indicates the current configuration does not have connect choice set 2478 */ 2479 private static final int CONNECT_CHOICE_NOT_EXISTS = -1; 2480 2481 // fields for QualityNetwork Selection 2482 /** 2483 * Network selection status, should be in one of three status: enable, temporaily disabled 2484 * or permanently disabled 2485 */ 2486 @NetworkEnabledStatus 2487 private int mStatus; 2488 2489 /** 2490 * Reason for disable this network 2491 */ 2492 @NetworkSelectionDisableReason 2493 private int mNetworkSelectionDisableReason; 2494 2495 /** 2496 * Last time we temporarily disabled the configuration 2497 */ 2498 private long mTemporarilyDisabledTimestamp = INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP; 2499 2500 private long mTemporarilyDisabledEndTime = INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP; 2501 2502 /** 2503 * counter for each Network selection disable reason 2504 */ 2505 private int[] mNetworkSeclectionDisableCounter = new int[NETWORK_SELECTION_DISABLED_MAX]; 2506 2507 /** 2508 * Connect Choice over this configuration 2509 * 2510 * When current wifi configuration is visible to the user but user explicitly choose to 2511 * connect to another network X, the another networks X's configure key will be stored here. 2512 * We will consider user has a preference of X over this network. And in the future, 2513 * network selection will always give X a higher preference over this configuration. 2514 * configKey is : "SSID"-WEP-WPA_PSK-WPA_EAP 2515 */ 2516 private String mConnectChoice; 2517 2518 /** 2519 * The RSSI when the user made the connectChoice. 2520 */ 2521 private int mConnectChoiceRssi; 2522 2523 /** 2524 * Used to cache the temporary candidate during the network selection procedure. It will be 2525 * kept updating once a new scan result has a higher score than current one 2526 */ 2527 private ScanResult mCandidate; 2528 2529 /** 2530 * Used to cache the score of the current temporary candidate during the network 2531 * selection procedure. 2532 */ 2533 private int mCandidateScore; 2534 2535 /** 2536 * Used to cache the select security params from the candidate. 2537 */ 2538 private SecurityParams mCandidateSecurityParams; 2539 2540 /** 2541 * Used to cache the last used security params for the candidate. 2542 */ 2543 private SecurityParams mLastUsedSecurityParams; 2544 2545 /** 2546 * Indicate whether this network is visible in latest Qualified Network Selection. This 2547 * means there is scan result found related to this Configuration and meet the minimum 2548 * requirement. The saved network need not join latest Qualified Network Selection. For 2549 * example, it is disabled. True means network is visible in latest Qualified Network 2550 * Selection and false means network is invisible 2551 */ 2552 private boolean mSeenInLastQualifiedNetworkSelection; 2553 2554 /** 2555 * Boolean indicating if we have ever successfully connected to this network. 2556 * 2557 * This value will be set to true upon a successful connection. 2558 * This value will be set to false if a previous value was not stored in the config or if 2559 * the credentials are updated (ex. a password change). 2560 */ 2561 private boolean mHasEverConnected; 2562 2563 /** 2564 * Boolean indicating if captive portal has never been detected on this network. 2565 * 2566 * This should be true by default, for newly created WifiConfigurations until a captive 2567 * portal is detected. 2568 */ 2569 private boolean mHasNeverDetectedCaptivePortal = true; 2570 2571 2572 /** 2573 * Boolean tracking whether internet validation have ever completed successfully on this 2574 * WifiConfiguration. 2575 */ 2576 private boolean mHasEverValidatedInternetAccess; 2577 2578 /** 2579 * set whether this network is visible in latest Qualified Network Selection 2580 * @param seen value set to candidate 2581 * @hide 2582 */ setSeenInLastQualifiedNetworkSelection(boolean seen)2583 public void setSeenInLastQualifiedNetworkSelection(boolean seen) { 2584 mSeenInLastQualifiedNetworkSelection = seen; 2585 } 2586 2587 /** 2588 * get whether this network is visible in latest Qualified Network Selection 2589 * @return returns true -- network is visible in latest Qualified Network Selection 2590 * false -- network is invisible in latest Qualified Network Selection 2591 * @hide 2592 */ getSeenInLastQualifiedNetworkSelection()2593 public boolean getSeenInLastQualifiedNetworkSelection() { 2594 return mSeenInLastQualifiedNetworkSelection; 2595 } 2596 /** 2597 * set the temporary candidate of current network selection procedure 2598 * @param scanCandidate {@link ScanResult} the candidate set to mCandidate 2599 * @hide 2600 */ setCandidate(ScanResult scanCandidate)2601 public void setCandidate(ScanResult scanCandidate) { 2602 mCandidate = scanCandidate; 2603 } 2604 2605 /** 2606 * get the temporary candidate of current network selection procedure 2607 * @return returns {@link ScanResult} temporary candidate of current network selection 2608 * procedure 2609 * @hide 2610 */ getCandidate()2611 public ScanResult getCandidate() { 2612 return mCandidate; 2613 } 2614 2615 /** 2616 * set the score of the temporary candidate of current network selection procedure 2617 * @param score value set to mCandidateScore 2618 * @hide 2619 */ setCandidateScore(int score)2620 public void setCandidateScore(int score) { 2621 mCandidateScore = score; 2622 } 2623 2624 /** 2625 * get the score of the temporary candidate of current network selection procedure 2626 * @return returns score of the temporary candidate of current network selection procedure 2627 * @hide 2628 */ getCandidateScore()2629 public int getCandidateScore() { 2630 return mCandidateScore; 2631 } 2632 2633 /** 2634 * set the security type of the temporary candidate of current network selection procedure 2635 * @param params value to set to mCandidateSecurityParams 2636 * @hide 2637 */ setCandidateSecurityParams(SecurityParams params)2638 public void setCandidateSecurityParams(SecurityParams params) { 2639 mCandidateSecurityParams = params; 2640 } 2641 2642 /** 2643 * get the security type of the temporary candidate of current network selection procedure 2644 * @return return the security params 2645 * @hide 2646 */ getCandidateSecurityParams()2647 public SecurityParams getCandidateSecurityParams() { 2648 return mCandidateSecurityParams; 2649 } 2650 2651 /** 2652 * set the last used security type of the network 2653 * @param params value to set to mLastUsedSecurityParams 2654 * @hide 2655 */ setLastUsedSecurityParams(SecurityParams params)2656 public void setLastUsedSecurityParams(SecurityParams params) { 2657 mLastUsedSecurityParams = params; 2658 } 2659 2660 /** 2661 * get the last used security type of the network 2662 * @return return the security params 2663 * @hide 2664 */ getLastUsedSecurityParams()2665 public SecurityParams getLastUsedSecurityParams() { 2666 return mLastUsedSecurityParams; 2667 } 2668 2669 /** 2670 * get user preferred choice over this configuration 2671 * @return returns configKey of user preferred choice over this configuration 2672 * @hide 2673 */ getConnectChoice()2674 public String getConnectChoice() { 2675 return mConnectChoice; 2676 } 2677 2678 /** 2679 * set user preferred choice over this configuration 2680 * @param newConnectChoice, the configKey of user preferred choice over this configuration 2681 * @hide 2682 */ setConnectChoice(String newConnectChoice)2683 public void setConnectChoice(String newConnectChoice) { 2684 mConnectChoice = newConnectChoice; 2685 } 2686 2687 /** 2688 * Associate a RSSI with the user connect choice network. 2689 * @param rssi signal strength 2690 * @hide 2691 */ setConnectChoiceRssi(int rssi)2692 public void setConnectChoiceRssi(int rssi) { 2693 mConnectChoiceRssi = rssi; 2694 } 2695 2696 /** 2697 * @return returns the RSSI of the last time the user made the connect choice. 2698 * @hide 2699 */ getConnectChoiceRssi()2700 public int getConnectChoiceRssi() { 2701 return mConnectChoiceRssi; 2702 } 2703 2704 /** Get the current Quality network selection status as a String (for debugging). */ 2705 @NonNull getNetworkStatusString()2706 public String getNetworkStatusString() { 2707 return QUALITY_NETWORK_SELECTION_STATUS[mStatus]; 2708 } 2709 2710 /** @hide */ setHasEverConnected(boolean value)2711 public void setHasEverConnected(boolean value) { 2712 mHasEverConnected = value; 2713 } 2714 2715 /** True if the device has ever connected to this network, false otherwise. */ hasEverConnected()2716 public boolean hasEverConnected() { 2717 return mHasEverConnected; 2718 } 2719 2720 /** 2721 * Set whether a captive portal has never been detected on this network. 2722 * @hide 2723 */ setHasNeverDetectedCaptivePortal(boolean value)2724 public void setHasNeverDetectedCaptivePortal(boolean value) { 2725 mHasNeverDetectedCaptivePortal = value; 2726 } 2727 2728 /** @hide */ 2729 @Keep hasNeverDetectedCaptivePortal()2730 public boolean hasNeverDetectedCaptivePortal() { 2731 return mHasNeverDetectedCaptivePortal; 2732 } 2733 2734 2735 /** 2736 * Get whether internet validation was ever successful on this WifiConfiguration. 2737 * @hide 2738 */ hasEverValidatedInternetAccess()2739 public boolean hasEverValidatedInternetAccess() { 2740 return mHasEverValidatedInternetAccess; 2741 } 2742 2743 /** 2744 * @hide 2745 */ setHasEverValidatedInternetAccess(boolean everValidated)2746 public void setHasEverValidatedInternetAccess(boolean everValidated) { 2747 mHasEverValidatedInternetAccess = everValidated; 2748 } 2749 2750 /** @hide */ NetworkSelectionStatus()2751 public NetworkSelectionStatus() { 2752 // previously stored configs will not have this parameter, so we default to false. 2753 mHasEverConnected = false; 2754 } 2755 2756 /** 2757 * NetworkSelectionStatus exports an immutable public API. 2758 * However, test code has a need to construct a NetworkSelectionStatus in a specific state. 2759 * (Note that mocking using Mockito does not work if the object needs to be parceled and 2760 * unparceled.) 2761 * Export a @SystemApi Builder to allow tests to construct a NetworkSelectionStatus object 2762 * in the desired state, without sacrificing NetworkSelectionStatus's immutability. 2763 */ 2764 @VisibleForTesting 2765 public static final class Builder { 2766 private final NetworkSelectionStatus mNetworkSelectionStatus = 2767 new NetworkSelectionStatus(); 2768 2769 /** 2770 * Set the current network selection status. 2771 * One of: 2772 * {@link #NETWORK_SELECTION_ENABLED}, 2773 * {@link #NETWORK_SELECTION_TEMPORARY_DISABLED}, 2774 * {@link #NETWORK_SELECTION_PERMANENTLY_DISABLED} 2775 * @see NetworkSelectionStatus#getNetworkSelectionStatus() 2776 */ 2777 @NonNull setNetworkSelectionStatus(@etworkEnabledStatus int status)2778 public Builder setNetworkSelectionStatus(@NetworkEnabledStatus int status) { 2779 mNetworkSelectionStatus.setNetworkSelectionStatus(status); 2780 return this; 2781 } 2782 2783 /** 2784 * 2785 * Set the current network's disable reason. 2786 * One of the {@link #DISABLED_NONE} or DISABLED_* constants. 2787 * e.g. {@link #DISABLED_ASSOCIATION_REJECTION}. 2788 * @see NetworkSelectionStatus#getNetworkSelectionDisableReason() 2789 */ 2790 @NonNull setNetworkSelectionDisableReason( @etworkSelectionDisableReason int reason)2791 public Builder setNetworkSelectionDisableReason( 2792 @NetworkSelectionDisableReason int reason) { 2793 mNetworkSelectionStatus.setNetworkSelectionDisableReason(reason); 2794 return this; 2795 } 2796 2797 /** 2798 * Build a NetworkSelectionStatus object. 2799 */ 2800 @NonNull build()2801 public NetworkSelectionStatus build() { 2802 NetworkSelectionStatus status = new NetworkSelectionStatus(); 2803 status.copy(mNetworkSelectionStatus); 2804 return status; 2805 } 2806 } 2807 2808 /** 2809 * Get the network disable reason string for a reason code (for debugging). 2810 * @param reason specific error reason. One of the {@link #DISABLED_NONE} or 2811 * DISABLED_* constants e.g. {@link #DISABLED_ASSOCIATION_REJECTION}. 2812 * @return network disable reason string, or null if the reason is invalid. 2813 */ 2814 @Nullable getNetworkSelectionDisableReasonString( @etworkSelectionDisableReason int reason)2815 public static String getNetworkSelectionDisableReasonString( 2816 @NetworkSelectionDisableReason int reason) { 2817 DisableReasonInfo info = DISABLE_REASON_INFOS.get(reason); 2818 if (info == null) { 2819 return null; 2820 } else { 2821 return info.mReasonStr; 2822 } 2823 } 2824 /** 2825 * get current network disable reason 2826 * @return current network disable reason in String (for debug purpose) 2827 * @hide 2828 */ getNetworkSelectionDisableReasonString()2829 public String getNetworkSelectionDisableReasonString() { 2830 return getNetworkSelectionDisableReasonString(mNetworkSelectionDisableReason); 2831 } 2832 2833 /** 2834 * Get the current network network selection status. 2835 * One of: 2836 * {@link #NETWORK_SELECTION_ENABLED}, 2837 * {@link #NETWORK_SELECTION_TEMPORARY_DISABLED}, 2838 * {@link #NETWORK_SELECTION_PERMANENTLY_DISABLED} 2839 */ 2840 @NetworkEnabledStatus getNetworkSelectionStatus()2841 public int getNetworkSelectionStatus() { 2842 return mStatus; 2843 } 2844 2845 /** 2846 * True if the current network is enabled to join network selection, false otherwise. 2847 * @hide 2848 */ isNetworkEnabled()2849 public boolean isNetworkEnabled() { 2850 return mStatus == NETWORK_SELECTION_ENABLED; 2851 } 2852 2853 /** 2854 * @return whether current network is temporary disabled 2855 * @hide 2856 */ isNetworkTemporaryDisabled()2857 public boolean isNetworkTemporaryDisabled() { 2858 return mStatus == NETWORK_SELECTION_TEMPORARY_DISABLED; 2859 } 2860 2861 /** 2862 * True if the current network is permanently disabled, false otherwise. 2863 * @hide 2864 */ isNetworkPermanentlyDisabled()2865 public boolean isNetworkPermanentlyDisabled() { 2866 return mStatus == NETWORK_SELECTION_PERMANENTLY_DISABLED; 2867 } 2868 2869 /** 2870 * set current network selection status 2871 * @param status network selection status to set 2872 * @hide 2873 */ setNetworkSelectionStatus(int status)2874 public void setNetworkSelectionStatus(int status) { 2875 if (status >= 0 && status < NETWORK_SELECTION_STATUS_MAX) { 2876 mStatus = status; 2877 } 2878 } 2879 2880 /** 2881 * Returns the current network's disable reason. 2882 * One of the {@link #DISABLED_NONE} or DISABLED_* constants 2883 * e.g. {@link #DISABLED_ASSOCIATION_REJECTION}. 2884 */ 2885 @NetworkSelectionDisableReason getNetworkSelectionDisableReason()2886 public int getNetworkSelectionDisableReason() { 2887 return mNetworkSelectionDisableReason; 2888 } 2889 2890 /** 2891 * set Network disable reason 2892 * @param reason Network disable reason 2893 * @hide 2894 */ setNetworkSelectionDisableReason(@etworkSelectionDisableReason int reason)2895 public void setNetworkSelectionDisableReason(@NetworkSelectionDisableReason int reason) { 2896 if (reason >= 0 && reason < NETWORK_SELECTION_DISABLED_MAX) { 2897 mNetworkSelectionDisableReason = reason; 2898 } else { 2899 throw new IllegalArgumentException("Illegal reason value: " + reason); 2900 } 2901 } 2902 2903 /** 2904 * @param timeStamp Set when current network is disabled in millisecond since boot. 2905 * @hide 2906 */ setDisableTime(long timeStamp)2907 public void setDisableTime(long timeStamp) { 2908 mTemporarilyDisabledTimestamp = timeStamp; 2909 } 2910 2911 /** 2912 * Returns when the current network was disabled, in milliseconds since boot. 2913 */ getDisableTime()2914 public long getDisableTime() { 2915 return mTemporarilyDisabledTimestamp; 2916 } 2917 2918 /** 2919 * Set the expected time for this WifiConfiguration to get re-enabled. 2920 * Timestamp is in milliseconds since boot. 2921 * @hide 2922 */ setDisableEndTime(long timestamp)2923 public void setDisableEndTime(long timestamp) { 2924 mTemporarilyDisabledEndTime = timestamp; 2925 } 2926 2927 /** 2928 * Returns the expected time for this WifiConfiguration to get re-enabled. 2929 * Timestamp is in milliseconds since boot. 2930 * @hide 2931 */ getDisableEndTime()2932 public long getDisableEndTime() { 2933 return mTemporarilyDisabledEndTime; 2934 } 2935 2936 /** 2937 * Get the disable counter of a specific reason. 2938 * @param reason specific failure reason. One of the {@link #DISABLED_NONE} or 2939 * DISABLED_* constants e.g. {@link #DISABLED_ASSOCIATION_REJECTION}. 2940 * @exception IllegalArgumentException for invalid reason 2941 * @return counter number for specific error reason. 2942 */ getDisableReasonCounter(@etworkSelectionDisableReason int reason)2943 public int getDisableReasonCounter(@NetworkSelectionDisableReason int reason) { 2944 if (reason >= DISABLED_NONE && reason < NETWORK_SELECTION_DISABLED_MAX) { 2945 return mNetworkSeclectionDisableCounter[reason]; 2946 } else { 2947 throw new IllegalArgumentException("Illegal reason value: " + reason); 2948 } 2949 } 2950 2951 /** 2952 * set the counter of a specific failure reason 2953 * @param reason reason for disable error 2954 * @param value the counter value for this specific reason 2955 * @exception throw IllegalArgumentException for illegal input 2956 * @hide 2957 */ setDisableReasonCounter(int reason, int value)2958 public void setDisableReasonCounter(int reason, int value) { 2959 if (reason >= DISABLED_NONE && reason < NETWORK_SELECTION_DISABLED_MAX) { 2960 mNetworkSeclectionDisableCounter[reason] = value; 2961 } else { 2962 throw new IllegalArgumentException("Illegal reason value: " + reason); 2963 } 2964 } 2965 2966 /** 2967 * increment the counter of a specific failure reason 2968 * @param reason a specific failure reason 2969 * @exception throw IllegalArgumentException for illegal input 2970 * @hide 2971 */ incrementDisableReasonCounter(int reason)2972 public void incrementDisableReasonCounter(int reason) { 2973 if (reason >= DISABLED_NONE && reason < NETWORK_SELECTION_DISABLED_MAX) { 2974 mNetworkSeclectionDisableCounter[reason]++; 2975 } else { 2976 throw new IllegalArgumentException("Illegal reason value: " + reason); 2977 } 2978 } 2979 2980 /** 2981 * clear the counter of a specific failure reason 2982 * @param reason a specific failure reason 2983 * @exception throw IllegalArgumentException for illegal input 2984 * @hide 2985 */ clearDisableReasonCounter(int reason)2986 public void clearDisableReasonCounter(int reason) { 2987 if (reason >= DISABLED_NONE && reason < NETWORK_SELECTION_DISABLED_MAX) { 2988 mNetworkSeclectionDisableCounter[reason] = DISABLED_NONE; 2989 } else { 2990 throw new IllegalArgumentException("Illegal reason value: " + reason); 2991 } 2992 } 2993 2994 /** 2995 * clear all the failure reason counters 2996 * @hide 2997 */ clearDisableReasonCounter()2998 public void clearDisableReasonCounter() { 2999 Arrays.fill(mNetworkSeclectionDisableCounter, DISABLED_NONE); 3000 } 3001 3002 /** 3003 * BSSID for connection to this network (through network selection procedure) 3004 */ 3005 private String mNetworkSelectionBSSID; 3006 3007 /** 3008 * get current network Selection BSSID 3009 * @return current network Selection BSSID 3010 * @hide 3011 */ getNetworkSelectionBSSID()3012 public String getNetworkSelectionBSSID() { 3013 return mNetworkSelectionBSSID; 3014 } 3015 3016 /** 3017 * set network Selection BSSID 3018 * @param bssid The target BSSID for assocaition 3019 * @hide 3020 */ setNetworkSelectionBSSID(String bssid)3021 public void setNetworkSelectionBSSID(String bssid) { 3022 mNetworkSelectionBSSID = bssid; 3023 } 3024 3025 /** @hide */ copy(NetworkSelectionStatus source)3026 public void copy(NetworkSelectionStatus source) { 3027 mStatus = source.mStatus; 3028 mNetworkSelectionDisableReason = source.mNetworkSelectionDisableReason; 3029 mNetworkSeclectionDisableCounter = Arrays.copyOf( 3030 source.mNetworkSeclectionDisableCounter, 3031 source.mNetworkSeclectionDisableCounter.length); 3032 mTemporarilyDisabledTimestamp = source.mTemporarilyDisabledTimestamp; 3033 mTemporarilyDisabledEndTime = source.mTemporarilyDisabledEndTime; 3034 mNetworkSelectionBSSID = source.mNetworkSelectionBSSID; 3035 setSeenInLastQualifiedNetworkSelection(source.getSeenInLastQualifiedNetworkSelection()); 3036 setCandidate(source.getCandidate()); 3037 setCandidateScore(source.getCandidateScore()); 3038 setCandidateSecurityParams(source.getCandidateSecurityParams()); 3039 setLastUsedSecurityParams(source.getLastUsedSecurityParams()); 3040 setConnectChoice(source.getConnectChoice()); 3041 setConnectChoiceRssi(source.getConnectChoiceRssi()); 3042 setHasEverConnected(source.hasEverConnected()); 3043 setHasNeverDetectedCaptivePortal(source.hasNeverDetectedCaptivePortal()); 3044 setHasEverValidatedInternetAccess(source.hasEverValidatedInternetAccess()); 3045 } 3046 3047 /** @hide */ writeToParcel(Parcel dest, int flags)3048 public void writeToParcel(Parcel dest, int flags) { 3049 dest.writeInt(getNetworkSelectionStatus()); 3050 dest.writeInt(getNetworkSelectionDisableReason()); 3051 for (int index = DISABLED_NONE; index < NETWORK_SELECTION_DISABLED_MAX; 3052 index++) { 3053 dest.writeInt(getDisableReasonCounter(index)); 3054 } 3055 dest.writeLong(getDisableTime()); 3056 dest.writeLong(getDisableEndTime()); 3057 dest.writeString(getNetworkSelectionBSSID()); 3058 if (getConnectChoice() != null) { 3059 dest.writeInt(CONNECT_CHOICE_EXISTS); 3060 dest.writeString(getConnectChoice()); 3061 dest.writeInt(getConnectChoiceRssi()); 3062 } else { 3063 dest.writeInt(CONNECT_CHOICE_NOT_EXISTS); 3064 } 3065 dest.writeInt(hasEverConnected() ? 1 : 0); 3066 dest.writeInt(hasNeverDetectedCaptivePortal() ? 1 : 0); 3067 dest.writeBoolean(hasEverValidatedInternetAccess()); 3068 dest.writeParcelable(getCandidateSecurityParams(), flags); 3069 dest.writeParcelable(getLastUsedSecurityParams(), flags); 3070 } 3071 3072 /** @hide */ readFromParcel(Parcel in)3073 public void readFromParcel(Parcel in) { 3074 setNetworkSelectionStatus(in.readInt()); 3075 setNetworkSelectionDisableReason(in.readInt()); 3076 for (int index = DISABLED_NONE; index < NETWORK_SELECTION_DISABLED_MAX; 3077 index++) { 3078 setDisableReasonCounter(index, in.readInt()); 3079 } 3080 setDisableTime(in.readLong()); 3081 setDisableEndTime(in.readLong()); 3082 setNetworkSelectionBSSID(in.readString()); 3083 if (in.readInt() == CONNECT_CHOICE_EXISTS) { 3084 setConnectChoice(in.readString()); 3085 setConnectChoiceRssi(in.readInt()); 3086 } else { 3087 setConnectChoice(null); 3088 } 3089 setHasEverConnected(in.readInt() != 0); 3090 setHasNeverDetectedCaptivePortal(in.readInt() != 0); 3091 setHasEverValidatedInternetAccess(in.readBoolean()); 3092 setCandidateSecurityParams((SecurityParams) in.readParcelable(null)); 3093 setLastUsedSecurityParams((SecurityParams) in.readParcelable(null)); 3094 } 3095 } 3096 3097 /** 3098 * network selection related member 3099 * @hide 3100 */ 3101 private NetworkSelectionStatus mNetworkSelectionStatus = new NetworkSelectionStatus(); 3102 3103 /** 3104 * This class is intended to store extra failure reason information for the most recent 3105 * connection attempt, so that it may be surfaced to the settings UI 3106 * @hide 3107 */ 3108 // TODO(b/148626966): called by SUW via reflection, remove once SUW is updated 3109 public static class RecentFailure { 3110 RecentFailure()3111 private RecentFailure() {} 3112 3113 /** 3114 * Association Rejection Status code (NONE for success/non-association-rejection-fail) 3115 */ 3116 @RecentFailureReason 3117 private int mAssociationStatus = RECENT_FAILURE_NONE; 3118 private long mLastUpdateTimeSinceBootMillis; 3119 3120 /** 3121 * @param status the association status code for the recent failure 3122 */ setAssociationStatus(@ecentFailureReason int status, long updateTimeSinceBootMs)3123 public void setAssociationStatus(@RecentFailureReason int status, 3124 long updateTimeSinceBootMs) { 3125 mAssociationStatus = status; 3126 mLastUpdateTimeSinceBootMillis = updateTimeSinceBootMs; 3127 } 3128 /** 3129 * Sets the RecentFailure to NONE 3130 */ clear()3131 public void clear() { 3132 mAssociationStatus = RECENT_FAILURE_NONE; 3133 mLastUpdateTimeSinceBootMillis = 0; 3134 } 3135 /** 3136 * Get the recent failure code. One of {@link #RECENT_FAILURE_NONE}, 3137 * {@link #RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA}, 3138 * {@link #RECENT_FAILURE_REFUSED_TEMPORARILY}, 3139 * {@link #RECENT_FAILURE_POOR_CHANNEL_CONDITIONS}. 3140 * {@link #RECENT_FAILURE_DISCONNECTION_AP_BUSY} 3141 */ 3142 @RecentFailureReason getAssociationStatus()3143 public int getAssociationStatus() { 3144 return mAssociationStatus; 3145 } 3146 3147 /** 3148 * Get the timestamp the failure status is last updated, in milliseconds since boot. 3149 */ getLastUpdateTimeSinceBootMillis()3150 public long getLastUpdateTimeSinceBootMillis() { 3151 return mLastUpdateTimeSinceBootMillis; 3152 } 3153 } 3154 3155 /** 3156 * RecentFailure member 3157 * @hide 3158 */ 3159 // TODO(b/148626966): called by SUW via reflection, once SUW is updated, make private and 3160 // rename to mRecentFailure 3161 @NonNull 3162 public final RecentFailure recentFailure = new RecentFailure(); 3163 3164 /** @hide */ 3165 @Retention(RetentionPolicy.SOURCE) 3166 @IntDef(prefix = "RECENT_FAILURE_", value = { 3167 RECENT_FAILURE_NONE, 3168 RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA, 3169 RECENT_FAILURE_REFUSED_TEMPORARILY, 3170 RECENT_FAILURE_POOR_CHANNEL_CONDITIONS, 3171 RECENT_FAILURE_DISCONNECTION_AP_BUSY, 3172 RECENT_FAILURE_MBO_ASSOC_DISALLOWED_UNSPECIFIED, 3173 RECENT_FAILURE_MBO_ASSOC_DISALLOWED_MAX_NUM_STA_ASSOCIATED, 3174 RECENT_FAILURE_MBO_ASSOC_DISALLOWED_AIR_INTERFACE_OVERLOADED, 3175 RECENT_FAILURE_MBO_ASSOC_DISALLOWED_AUTH_SERVER_OVERLOADED, 3176 RECENT_FAILURE_MBO_ASSOC_DISALLOWED_INSUFFICIENT_RSSI, 3177 RECENT_FAILURE_OCE_RSSI_BASED_ASSOCIATION_REJECTION, 3178 RECENT_FAILURE_NETWORK_NOT_FOUND 3179 3180 }) 3181 public @interface RecentFailureReason {} 3182 3183 /** 3184 * No recent failure, or no specific reason given for the recent connection failure 3185 * @hide 3186 */ 3187 @SystemApi 3188 public static final int RECENT_FAILURE_NONE = 0; 3189 /** 3190 * Connection to this network recently failed due to Association Rejection Status 17 3191 * (AP is full) 3192 * @hide 3193 */ 3194 @SystemApi 3195 public static final int RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA = 17; 3196 3197 /** 3198 * Failed to connect because the association is rejected by the AP. 3199 * IEEE 802.11 association status code 30. 3200 * @hide 3201 */ 3202 @SystemApi 3203 public static final int RECENT_FAILURE_REFUSED_TEMPORARILY = 1002; 3204 3205 /** 3206 * Failed to connect because of excess frame loss and/or poor channel conditions. 3207 * IEEE 802.11 association status code 34. 3208 * @hide 3209 */ 3210 @SystemApi 3211 public static final int RECENT_FAILURE_POOR_CHANNEL_CONDITIONS = 1003; 3212 3213 /** 3214 * Disconnected by the AP because the AP can't handle all the associated stations. 3215 * IEEE 802.11 disconnection reason code 5. 3216 * @hide 3217 */ 3218 @SystemApi 3219 public static final int RECENT_FAILURE_DISCONNECTION_AP_BUSY = 1004; 3220 3221 /** 3222 * Failed to connect because the association is rejected by the AP with 3223 * MBO association disallowed Reason code: 1 - Unspecified or 0/6-255 - Reserved. 3224 * Details in MBO spec v1.2, 4.2.4 Table 13: MBO Association Disallowed attribute 3225 * @hide 3226 */ 3227 @SystemApi 3228 public static final int RECENT_FAILURE_MBO_ASSOC_DISALLOWED_UNSPECIFIED = 1005; 3229 3230 /** 3231 * Failed to connect because the association is rejected by the AP with 3232 * MBO association disallowed Reason code: 2 - Maximum number of associated stations reached. 3233 * Details in MBO spec v1.2, 4.2.4 Table 13: MBO Association Disallowed attribute 3234 * @hide 3235 */ 3236 @SystemApi 3237 public static final int RECENT_FAILURE_MBO_ASSOC_DISALLOWED_MAX_NUM_STA_ASSOCIATED = 1006; 3238 3239 /** 3240 * Failed to connect because the association is rejected by the AP with 3241 * MBO association disallowed Reason code: 3 - Air interface is overloaded. 3242 * Details in MBO spec v1.2, 4.2.4 Table 13: MBO Association Disallowed attribute 3243 * @hide 3244 */ 3245 @SystemApi 3246 public static final int RECENT_FAILURE_MBO_ASSOC_DISALLOWED_AIR_INTERFACE_OVERLOADED = 1007; 3247 3248 /** 3249 * Failed to connect because the association is rejected by the AP with 3250 * MBO association disallowed Reason code: 4 - Authentication server overloaded. 3251 * Details in MBO spec v1.2, 4.2.4 Table 13: MBO Association Disallowed attribute 3252 * @hide 3253 */ 3254 @SystemApi 3255 public static final int RECENT_FAILURE_MBO_ASSOC_DISALLOWED_AUTH_SERVER_OVERLOADED = 1008; 3256 3257 /** 3258 * Failed to connect because the association is rejected by the AP with 3259 * MBO association disallowed Reason code: 5 - Insufficient RSSI. 3260 * Details in MBO spec v1.2, 4.2.4 Table 13: MBO Association Disallowed attribute 3261 * @hide 3262 */ 3263 @SystemApi 3264 public static final int RECENT_FAILURE_MBO_ASSOC_DISALLOWED_INSUFFICIENT_RSSI = 1009; 3265 3266 /** 3267 * Failed to connect because the association is rejected by the AP with 3268 * OCE rssi based association rejection attribute. 3269 * Details in OCE spec v1.0, 3.14 Presence of OCE rssi based association rejection attribute. 3270 * @hide 3271 */ 3272 @SystemApi 3273 public static final int RECENT_FAILURE_OCE_RSSI_BASED_ASSOCIATION_REJECTION = 1010; 3274 3275 /** 3276 * Failed to connect because supplicant failed to find a network in scan result which 3277 * matches the network requested by framework for connection (including network capabilities). 3278 * @hide 3279 */ 3280 @SystemApi 3281 public static final int RECENT_FAILURE_NETWORK_NOT_FOUND = 1011; 3282 3283 /** 3284 * Get the failure reason for the most recent connection attempt, or 3285 * {@link #RECENT_FAILURE_NONE} if there was no failure. 3286 * 3287 * Failure reasons include: 3288 * {@link #RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA} 3289 * {@link #RECENT_FAILURE_REFUSED_TEMPORARILY} 3290 * {@link #RECENT_FAILURE_POOR_CHANNEL_CONDITIONS} 3291 * {@link #RECENT_FAILURE_DISCONNECTION_AP_BUSY} 3292 * {@link #RECENT_FAILURE_MBO_ASSOC_DISALLOWED_UNSPECIFIED} 3293 * {@link #RECENT_FAILURE_MBO_ASSOC_DISALLOWED_MAX_NUM_STA_ASSOCIATED} 3294 * {@link #RECENT_FAILURE_MBO_ASSOC_DISALLOWED_AIR_INTERFACE_OVERLOADED} 3295 * {@link #RECENT_FAILURE_MBO_ASSOC_DISALLOWED_AUTH_SERVER_OVERLOADED} 3296 * {@link #RECENT_FAILURE_MBO_ASSOC_DISALLOWED_INSUFFICIENT_RSSI} 3297 * {@link #RECENT_FAILURE_OCE_RSSI_BASED_ASSOCIATION_REJECTION} 3298 * {@link #RECENT_FAILURE_NETWORK_NOT_FOUND} 3299 * @hide 3300 */ 3301 @RecentFailureReason 3302 @SystemApi getRecentFailureReason()3303 public int getRecentFailureReason() { 3304 return recentFailure.getAssociationStatus(); 3305 } 3306 3307 /** 3308 * Get the network selection status. 3309 * @hide 3310 */ 3311 @NonNull 3312 @SystemApi getNetworkSelectionStatus()3313 public NetworkSelectionStatus getNetworkSelectionStatus() { 3314 return mNetworkSelectionStatus; 3315 } 3316 3317 /** 3318 * Set the network selection status. 3319 * @hide 3320 */ 3321 @SystemApi setNetworkSelectionStatus(@onNull NetworkSelectionStatus status)3322 public void setNetworkSelectionStatus(@NonNull NetworkSelectionStatus status) { 3323 mNetworkSelectionStatus = status; 3324 } 3325 3326 /** 3327 * Linked Configurations: represent the set of Wificonfigurations that are equivalent 3328 * regarding roaming and auto-joining. 3329 * The linked configuration may or may not have same SSID, and may or may not have same 3330 * credentials. 3331 * For instance, linked configurations will have same defaultGwMacAddress or same dhcp server. 3332 * @hide 3333 */ 3334 public HashMap<String, Integer> linkedConfigurations; 3335 3336 /** List of {@link OuiKeyedData} providing vendor-specific configuration data. */ 3337 private @NonNull List<OuiKeyedData> mVendorData; 3338 WifiConfiguration()3339 public WifiConfiguration() { 3340 networkId = INVALID_NETWORK_ID; 3341 SSID = null; 3342 BSSID = null; 3343 FQDN = null; 3344 roamingConsortiumIds = new long[0]; 3345 priority = 0; 3346 mDeletionPriority = 0; 3347 hiddenSSID = false; 3348 allowedKeyManagement = new BitSet(); 3349 allowedProtocols = new BitSet(); 3350 allowedAuthAlgorithms = new BitSet(); 3351 allowedPairwiseCiphers = new BitSet(); 3352 allowedGroupCiphers = new BitSet(); 3353 allowedGroupManagementCiphers = new BitSet(); 3354 allowedSuiteBCiphers = new BitSet(); 3355 wepKeys = new String[4]; 3356 for (int i = 0; i < wepKeys.length; i++) { 3357 wepKeys[i] = null; 3358 } 3359 enterpriseConfig = new WifiEnterpriseConfig(); 3360 ephemeral = false; 3361 osu = false; 3362 trusted = true; // Networks are considered trusted by default. 3363 oemPaid = false; 3364 oemPrivate = false; 3365 carrierMerged = false; 3366 fromWifiNetworkSuggestion = false; 3367 fromWifiNetworkSpecifier = false; 3368 meteredHint = false; 3369 mIsRepeaterEnabled = false; 3370 meteredOverride = METERED_OVERRIDE_NONE; 3371 useExternalScores = false; 3372 validatedInternetAccess = false; 3373 mIpConfiguration = new IpConfiguration(); 3374 lastUpdateUid = -1; 3375 creatorUid = -1; 3376 shared = true; 3377 dtimInterval = 0; 3378 mRandomizedMacAddress = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS); 3379 numRebootsSinceLastUse = 0; 3380 restricted = false; 3381 mBssidAllowlist = null; 3382 mIsDppConfigurator = false; 3383 mDppPrivateEcKey = new byte[0]; 3384 mDppConnector = new byte[0]; 3385 mDppCSignKey = new byte[0]; 3386 mDppNetAccessKey = new byte[0]; 3387 mHasPreSharedKeyChanged = false; 3388 mEncryptedPreSharedKey = new byte[0]; 3389 mEncryptedPreSharedKeyIv = new byte[0]; 3390 mIpProvisioningTimedOut = false; 3391 mVendorData = Collections.emptyList(); 3392 } 3393 3394 /** 3395 * Identify if this configuration represents a Passpoint network 3396 */ isPasspoint()3397 public boolean isPasspoint() { 3398 return !TextUtils.isEmpty(FQDN) 3399 && !TextUtils.isEmpty(providerFriendlyName) 3400 && enterpriseConfig != null 3401 && enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE 3402 && !TextUtils.isEmpty(mPasspointUniqueId); 3403 } 3404 3405 /** 3406 * Helper function, identify if a configuration is linked 3407 * @hide 3408 */ isLinked(WifiConfiguration config)3409 public boolean isLinked(WifiConfiguration config) { 3410 if (config != null) { 3411 if (config.linkedConfigurations != null && linkedConfigurations != null) { 3412 if (config.linkedConfigurations.get(getKey()) != null 3413 && linkedConfigurations.get(config.getKey()) != null) { 3414 return true; 3415 } 3416 } 3417 } 3418 return false; 3419 } 3420 3421 /** 3422 * Helper function, idenfity if a configuration should be treated as an enterprise network 3423 * @hide 3424 */ 3425 @UnsupportedAppUsage isEnterprise()3426 public boolean isEnterprise() { 3427 if (enterpriseConfig == null 3428 || enterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.NONE) { 3429 return false; 3430 } 3431 for (SecurityParams p : mSecurityParamsList) { 3432 if (p.isEnterpriseSecurityType()) { 3433 return true; 3434 } 3435 } 3436 return false; 3437 } 3438 logTimeOfDay(long millis)3439 private static String logTimeOfDay(long millis) { 3440 Calendar c = Calendar.getInstance(); 3441 if (millis >= 0) { 3442 LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), 3443 ZoneId.systemDefault()); 3444 return localDateTime.toString(); 3445 } else { 3446 return Long.toString(millis); 3447 } 3448 } 3449 3450 @Override toString()3451 public String toString() { 3452 StringBuilder sbuf = new StringBuilder(); 3453 if (this.status == WifiConfiguration.Status.CURRENT) { 3454 sbuf.append("* "); 3455 } else if (this.status == WifiConfiguration.Status.DISABLED) { 3456 sbuf.append("- DSBLE "); 3457 } 3458 sbuf.append("ID: ").append(this.networkId).append(" SSID: ").append(this.SSID). 3459 append(" PROVIDER-NAME: ").append(this.providerFriendlyName). 3460 append(" BSSID: ").append(this.BSSID).append(" FQDN: ").append(this.FQDN) 3461 .append(" HOME-PROVIDER-NETWORK: ").append(this.isHomeProviderNetwork) 3462 .append(" PRIO: ").append(this.priority) 3463 .append(" HIDDEN: ").append(this.hiddenSSID) 3464 .append(" PMF: ").append(this.requirePmf) 3465 .append(" CarrierId: ").append(this.carrierId) 3466 .append(" SubscriptionId: ").append(this.subscriptionId) 3467 .append(" SubscriptionGroup: ").append(this.mSubscriptionGroup) 3468 .append(" Currently Connected: ").append(this.isCurrentlyConnected) 3469 .append(" User Selected: ").append(this.mIsUserSelected) 3470 .append('\n'); 3471 3472 3473 sbuf.append(" NetworkSelectionStatus ") 3474 .append(mNetworkSelectionStatus.getNetworkStatusString()) 3475 .append("\n"); 3476 if (mNetworkSelectionStatus.getNetworkSelectionDisableReason() > 0) { 3477 sbuf.append(" mNetworkSelectionDisableReason ") 3478 .append(mNetworkSelectionStatus.getNetworkSelectionDisableReasonString()) 3479 .append("\n"); 3480 3481 for (int index = NetworkSelectionStatus.DISABLED_NONE; 3482 index < NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX; index++) { 3483 if (mNetworkSelectionStatus.getDisableReasonCounter(index) != 0) { 3484 sbuf.append( 3485 NetworkSelectionStatus.getNetworkSelectionDisableReasonString(index)) 3486 .append(" counter:") 3487 .append(mNetworkSelectionStatus.getDisableReasonCounter(index)) 3488 .append("\n"); 3489 } 3490 } 3491 } 3492 if (mNetworkSelectionStatus.getConnectChoice() != null) { 3493 sbuf.append(" connect choice: ").append(mNetworkSelectionStatus.getConnectChoice()); 3494 sbuf.append(" connect choice rssi: ") 3495 .append(mNetworkSelectionStatus.getConnectChoiceRssi()); 3496 } 3497 sbuf.append(" hasEverConnected: ") 3498 .append(mNetworkSelectionStatus.hasEverConnected()).append("\n"); 3499 sbuf.append(" hasNeverDetectedCaptivePortal: ") 3500 .append(mNetworkSelectionStatus.hasNeverDetectedCaptivePortal()).append("\n"); 3501 sbuf.append(" hasEverValidatedInternetAccess: ") 3502 .append(mNetworkSelectionStatus.hasEverValidatedInternetAccess()).append("\n"); 3503 sbuf.append(" mCandidateSecurityParams: ") 3504 .append(mNetworkSelectionStatus.getCandidateSecurityParams()); 3505 sbuf.append(" mLastUsedSecurityParams: ") 3506 .append(mNetworkSelectionStatus.getLastUsedSecurityParams()); 3507 3508 if (this.numAssociation > 0) { 3509 sbuf.append(" numAssociation ").append(this.numAssociation).append("\n"); 3510 } 3511 if (this.numNoInternetAccessReports > 0) { 3512 sbuf.append(" numNoInternetAccessReports "); 3513 sbuf.append(this.numNoInternetAccessReports).append("\n"); 3514 } 3515 if (this.validatedInternetAccess) sbuf.append(" validatedInternetAccess"); 3516 if (this.shared) { 3517 sbuf.append(" shared"); 3518 } else { 3519 sbuf.append(" not-shared"); 3520 } 3521 if (this.ephemeral) sbuf.append(" ephemeral"); 3522 if (this.osu) sbuf.append(" osu"); 3523 if (this.trusted) sbuf.append(" trusted"); 3524 if (this.restricted) sbuf.append(" restricted"); 3525 if (this.oemPaid) sbuf.append(" oemPaid"); 3526 if (this.oemPrivate) sbuf.append(" oemPrivate"); 3527 if (this.carrierMerged) sbuf.append(" carrierMerged"); 3528 if (this.fromWifiNetworkSuggestion) sbuf.append(" fromWifiNetworkSuggestion"); 3529 if (this.fromWifiNetworkSpecifier) sbuf.append(" fromWifiNetworkSpecifier"); 3530 if (this.meteredHint) sbuf.append(" meteredHint"); 3531 if (this.mIsRepeaterEnabled) sbuf.append(" repeaterEnabled"); 3532 if (this.useExternalScores) sbuf.append(" useExternalScores"); 3533 if (this.validatedInternetAccess || this.ephemeral || this.trusted || this.oemPaid 3534 || this.oemPrivate || this.carrierMerged || this.fromWifiNetworkSuggestion 3535 || this.fromWifiNetworkSpecifier || this.meteredHint || this.useExternalScores 3536 || this.restricted) { 3537 sbuf.append("\n"); 3538 } 3539 if (this.meteredOverride != METERED_OVERRIDE_NONE) { 3540 sbuf.append(" meteredOverride ").append(meteredOverride).append("\n"); 3541 } 3542 sbuf.append(" macRandomizationSetting: ").append(macRandomizationSetting).append("\n"); 3543 sbuf.append(" mRandomizedMacAddress: ").append(mRandomizedMacAddress).append("\n"); 3544 sbuf.append(" randomizedMacExpirationTimeMs: ") 3545 .append(randomizedMacExpirationTimeMs == 0 ? "<none>" 3546 : logTimeOfDay(randomizedMacExpirationTimeMs)).append("\n"); 3547 sbuf.append(" randomizedMacLastModifiedTimeMs: ") 3548 .append(randomizedMacLastModifiedTimeMs == 0 ? "<none>" 3549 : logTimeOfDay(randomizedMacLastModifiedTimeMs)).append("\n"); 3550 sbuf.append(" mIsSendDhcpHostnameEnabled: ").append(mIsSendDhcpHostnameEnabled) 3551 .append("\n"); 3552 sbuf.append(" deletionPriority: ").append(mDeletionPriority).append("\n"); 3553 sbuf.append(" KeyMgmt:"); 3554 for (int k = 0; k < this.allowedKeyManagement.size(); k++) { 3555 if (this.allowedKeyManagement.get(k)) { 3556 sbuf.append(" "); 3557 if (k < KeyMgmt.strings.length) { 3558 sbuf.append(KeyMgmt.strings[k]); 3559 } else { 3560 sbuf.append("??"); 3561 } 3562 } 3563 } 3564 sbuf.append(" Protocols:"); 3565 for (int p = 0; p < this.allowedProtocols.size(); p++) { 3566 if (this.allowedProtocols.get(p)) { 3567 sbuf.append(" "); 3568 if (p < Protocol.strings.length) { 3569 sbuf.append(Protocol.strings[p]); 3570 } else { 3571 sbuf.append("??"); 3572 } 3573 } 3574 } 3575 sbuf.append('\n'); 3576 sbuf.append(" AuthAlgorithms:"); 3577 for (int a = 0; a < this.allowedAuthAlgorithms.size(); a++) { 3578 if (this.allowedAuthAlgorithms.get(a)) { 3579 sbuf.append(" "); 3580 if (a < AuthAlgorithm.strings.length) { 3581 sbuf.append(AuthAlgorithm.strings[a]); 3582 } else { 3583 sbuf.append("??"); 3584 } 3585 } 3586 } 3587 sbuf.append('\n'); 3588 sbuf.append(" PairwiseCiphers:"); 3589 for (int pc = 0; pc < this.allowedPairwiseCiphers.size(); pc++) { 3590 if (this.allowedPairwiseCiphers.get(pc)) { 3591 sbuf.append(" "); 3592 if (pc < PairwiseCipher.strings.length) { 3593 sbuf.append(PairwiseCipher.strings[pc]); 3594 } else { 3595 sbuf.append("??"); 3596 } 3597 } 3598 } 3599 sbuf.append('\n'); 3600 sbuf.append(" GroupCiphers:"); 3601 for (int gc = 0; gc < this.allowedGroupCiphers.size(); gc++) { 3602 if (this.allowedGroupCiphers.get(gc)) { 3603 sbuf.append(" "); 3604 if (gc < GroupCipher.strings.length) { 3605 sbuf.append(GroupCipher.strings[gc]); 3606 } else { 3607 sbuf.append("??"); 3608 } 3609 } 3610 } 3611 sbuf.append('\n'); 3612 sbuf.append(" GroupMgmtCiphers:"); 3613 for (int gmc = 0; gmc < this.allowedGroupManagementCiphers.size(); gmc++) { 3614 if (this.allowedGroupManagementCiphers.get(gmc)) { 3615 sbuf.append(" "); 3616 if (gmc < GroupMgmtCipher.strings.length) { 3617 sbuf.append(GroupMgmtCipher.strings[gmc]); 3618 } else { 3619 sbuf.append("??"); 3620 } 3621 } 3622 } 3623 sbuf.append('\n'); 3624 sbuf.append(" SuiteBCiphers:"); 3625 for (int sbc = 0; sbc < this.allowedSuiteBCiphers.size(); sbc++) { 3626 if (this.allowedSuiteBCiphers.get(sbc)) { 3627 sbuf.append(" "); 3628 if (sbc < SuiteBCipher.strings.length) { 3629 sbuf.append(SuiteBCipher.strings[sbc]); 3630 } else { 3631 sbuf.append("??"); 3632 } 3633 } 3634 } 3635 sbuf.append('\n').append(" PSK/SAE: "); 3636 if (this.preSharedKey != null) { 3637 sbuf.append('*'); 3638 } 3639 3640 sbuf.append("\nSecurityParams List:\n"); 3641 mSecurityParamsList.forEach(params -> sbuf.append(params.toString())); 3642 3643 sbuf.append("\nEnterprise config:\n"); 3644 sbuf.append(enterpriseConfig); 3645 3646 sbuf.append("IP config:\n"); 3647 sbuf.append(mIpConfiguration.toString()); 3648 3649 if (mNetworkSelectionStatus.getNetworkSelectionBSSID() != null) { 3650 sbuf.append(" networkSelectionBSSID=").append( 3651 mNetworkSelectionStatus.getNetworkSelectionBSSID()); 3652 } 3653 long now_ms = SystemClock.elapsedRealtime(); 3654 if (mNetworkSelectionStatus.getDisableTime() != NetworkSelectionStatus 3655 .INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP) { 3656 sbuf.append('\n'); 3657 long diff = now_ms - mNetworkSelectionStatus.getDisableTime(); 3658 if (diff <= 0) { 3659 sbuf.append(" blackListed since <incorrect>"); 3660 } else { 3661 sbuf.append(" blackListed: ").append(Long.toString(diff / 1000)).append("sec "); 3662 } 3663 } 3664 if (mNetworkSelectionStatus.getDisableEndTime() 3665 != NetworkSelectionStatus.INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP) { 3666 sbuf.append('\n'); 3667 long diff = mNetworkSelectionStatus.getDisableEndTime() - now_ms; 3668 if (diff <= 0) { 3669 sbuf.append(" blockListed remaining time <incorrect>"); 3670 } else { 3671 sbuf.append(" blocklist end in: ").append(Long.toString(diff / 1000)) 3672 .append("sec "); 3673 } 3674 } 3675 if (creatorUid != 0) sbuf.append(" cuid=").append(creatorUid); 3676 if (creatorName != null) sbuf.append(" cname=").append(creatorName); 3677 if (lastUpdateUid != 0) sbuf.append(" luid=").append(lastUpdateUid); 3678 if (lastUpdateName != null) sbuf.append(" lname=").append(lastUpdateName); 3679 if (updateIdentifier != null) sbuf.append(" updateIdentifier=").append(updateIdentifier); 3680 sbuf.append(" lcuid=").append(lastConnectUid); 3681 sbuf.append(" allowAutojoin=").append(allowAutojoin); 3682 sbuf.append(" noInternetAccessExpected=").append(noInternetAccessExpected); 3683 sbuf.append(" mostRecentlyConnected=").append(isMostRecentlyConnected); 3684 3685 sbuf.append(" "); 3686 3687 if (this.lastConnected != 0) { 3688 sbuf.append('\n'); 3689 sbuf.append("lastConnected: ").append(logTimeOfDay(this.lastConnected)); 3690 sbuf.append(" "); 3691 } 3692 sbuf.append('\n'); 3693 if (this.lastUpdated != 0) { 3694 sbuf.append('\n'); 3695 sbuf.append("lastUpdated: ").append(logTimeOfDay(this.lastUpdated)); 3696 sbuf.append(" "); 3697 } 3698 sbuf.append('\n'); 3699 sbuf.append("numRebootsSinceLastUse: ").append(numRebootsSinceLastUse).append('\n'); 3700 if (this.linkedConfigurations != null) { 3701 for (String key : this.linkedConfigurations.keySet()) { 3702 sbuf.append(" linked: ").append(key); 3703 sbuf.append('\n'); 3704 } 3705 } 3706 sbuf.append("recentFailure: ").append("Association Rejection code: ") 3707 .append(recentFailure.getAssociationStatus()).append(", last update time: ") 3708 .append(recentFailure.getLastUpdateTimeSinceBootMillis()).append("\n"); 3709 if (mBssidAllowlist != null) { 3710 sbuf.append("bssidAllowList: ["); 3711 for (MacAddress bssid : mBssidAllowlist) { 3712 sbuf.append(bssid).append(", "); 3713 } 3714 sbuf.append("]"); 3715 } else { 3716 sbuf.append("bssidAllowlist unset"); 3717 } 3718 sbuf.append("\n"); 3719 if (mVendorData != null && !mVendorData.isEmpty()) { 3720 sbuf.append("vendorData: ").append(mVendorData); 3721 } else { 3722 sbuf.append("vendorData unset"); 3723 } 3724 sbuf.append("\n"); 3725 sbuf.append("IsDppConfigurator: ").append(this.mIsDppConfigurator).append("\n"); 3726 sbuf.append("HasEncryptedPreSharedKey: ").append(hasEncryptedPreSharedKey()).append("\n"); 3727 sbuf.append(" setWifi7Enabled=").append(mWifi7Enabled); 3728 return sbuf.toString(); 3729 } 3730 3731 /** 3732 * Get the SSID in a human-readable format, with all additional formatting removed 3733 * e.g. quotation marks around the SSID, "P" prefix 3734 * @hide 3735 */ 3736 @NonNull 3737 @SystemApi getPrintableSsid()3738 public String getPrintableSsid() { 3739 // TODO(b/136480579): Handle SSIDs with non-UTF-8 encodings. 3740 return WifiInfo.removeDoubleQuotes(SSID); 3741 } 3742 3743 /** 3744 * Get an identifier for associating credentials with this config 3745 * @param current configuration contains values for additional fields 3746 * that are not part of this configuration. Used 3747 * when a config with some fields is passed by an application. 3748 * @throws IllegalStateException if config is invalid for key id generation 3749 * @hide 3750 */ getKeyIdForCredentials(WifiConfiguration current)3751 public String getKeyIdForCredentials(WifiConfiguration current) { 3752 String keyMgmt = ""; 3753 3754 try { 3755 // Get current config details for fields that are not initialized 3756 if (TextUtils.isEmpty(SSID)) SSID = current.SSID; 3757 if (allowedKeyManagement.cardinality() == 0) { 3758 allowedKeyManagement = current.allowedKeyManagement; 3759 } 3760 if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) { 3761 keyMgmt += KeyMgmt.strings[KeyMgmt.WPA_EAP]; 3762 } 3763 if (allowedKeyManagement.get(KeyMgmt.OSEN)) { 3764 keyMgmt += KeyMgmt.strings[KeyMgmt.OSEN]; 3765 } 3766 if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) { 3767 keyMgmt += KeyMgmt.strings[KeyMgmt.IEEE8021X]; 3768 } 3769 if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) { 3770 keyMgmt += KeyMgmt.strings[KeyMgmt.SUITE_B_192]; 3771 } 3772 if (allowedKeyManagement.get(KeyMgmt.WAPI_CERT)) { 3773 keyMgmt += KeyMgmt.strings[KeyMgmt.WAPI_CERT]; 3774 } 3775 3776 if (TextUtils.isEmpty(keyMgmt)) { 3777 throw new IllegalStateException("Not an EAP network"); 3778 } 3779 String keyId = (!TextUtils.isEmpty(SSID) && SSID.charAt(0) != '\"' 3780 ? SSID.toLowerCase() : SSID) + "_" + keyMgmt + "_" 3781 + trimStringForKeyId(enterpriseConfig.getKeyId(current != null 3782 ? current.enterpriseConfig : null)); 3783 3784 if (!fromWifiNetworkSuggestion) { 3785 return keyId; 3786 } 3787 return keyId + "_" + trimStringForKeyId(BSSID) + "_" + trimStringForKeyId(creatorName); 3788 } catch (NullPointerException e) { 3789 throw new IllegalStateException("Invalid config details"); 3790 } 3791 } 3792 trimStringForKeyId(String string)3793 private String trimStringForKeyId(String string) { 3794 if (string == null) { 3795 return ""; 3796 } 3797 // Remove quotes and spaces 3798 return string.replace("\"", "").replace(" ", ""); 3799 } 3800 readBitSet(Parcel src)3801 private static BitSet readBitSet(Parcel src) { 3802 int cardinality = src.readInt(); 3803 3804 BitSet set = new BitSet(); 3805 for (int i = 0; i < cardinality; i++) { 3806 set.set(src.readInt()); 3807 } 3808 3809 return set; 3810 } 3811 writeBitSet(Parcel dest, BitSet set)3812 private static void writeBitSet(Parcel dest, BitSet set) { 3813 int nextSetBit = -1; 3814 3815 dest.writeInt(set.cardinality()); 3816 3817 while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1) { 3818 dest.writeInt(nextSetBit); 3819 } 3820 } 3821 3822 /** 3823 * Get the authentication type of the network. 3824 * @return One of the {@link KeyMgmt} constants. e.g. {@link KeyMgmt#WPA2_PSK}. 3825 * @throws IllegalStateException if config is invalid for authentication type. 3826 * @hide 3827 */ 3828 @SystemApi 3829 @KeyMgmt.KeyMgmtScheme getAuthType()3830 public int getAuthType() { 3831 if (allowedKeyManagement.cardinality() > 1) { 3832 if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) { 3833 if (allowedKeyManagement.cardinality() == 2 3834 && allowedKeyManagement.get(KeyMgmt.IEEE8021X)) { 3835 return KeyMgmt.WPA_EAP; 3836 } 3837 if (allowedKeyManagement.cardinality() == 3 3838 && allowedKeyManagement.get(KeyMgmt.IEEE8021X) 3839 && allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) { 3840 return KeyMgmt.SUITE_B_192; 3841 } 3842 } 3843 throw new IllegalStateException("Invalid auth type set: " + allowedKeyManagement); 3844 } 3845 if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) { 3846 return KeyMgmt.WPA_PSK; 3847 } else if (allowedKeyManagement.get(KeyMgmt.WPA2_PSK)) { 3848 return KeyMgmt.WPA2_PSK; 3849 } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) { 3850 return KeyMgmt.WPA_EAP; 3851 } else if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) { 3852 return KeyMgmt.IEEE8021X; 3853 } else if (allowedKeyManagement.get(KeyMgmt.SAE)) { 3854 return KeyMgmt.SAE; 3855 } else if (allowedKeyManagement.get(KeyMgmt.OWE)) { 3856 return KeyMgmt.OWE; 3857 } else if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) { 3858 return KeyMgmt.SUITE_B_192; 3859 } else if (allowedKeyManagement.get(KeyMgmt.WAPI_PSK)) { 3860 return KeyMgmt.WAPI_PSK; 3861 } else if (allowedKeyManagement.get(KeyMgmt.WAPI_CERT)) { 3862 return KeyMgmt.WAPI_CERT; 3863 } else if (allowedKeyManagement.get(KeyMgmt.DPP)) { 3864 return KeyMgmt.DPP; 3865 } 3866 return KeyMgmt.NONE; 3867 } 3868 3869 /** 3870 * Return a String that can be used to uniquely identify this WifiConfiguration. 3871 * <br /> 3872 * Note: Do not persist this value! This value is not guaranteed to remain backwards compatible. 3873 */ 3874 @NonNull getKey()3875 public String getKey() { 3876 // Passpoint ephemeral networks have their unique identifier set. Return it as is to be 3877 // able to match internally. 3878 if (mPasspointUniqueId != null) { 3879 return mPasspointUniqueId; 3880 } 3881 3882 String key = getSsidAndSecurityTypeString(); 3883 if (!shared) { 3884 key += "-" + UserHandle.getUserHandleForUid(creatorUid).getIdentifier(); 3885 } 3886 3887 return key; 3888 } 3889 3890 /** 3891 * Get a unique key which represent this Wi-Fi network. If two profiles are for 3892 * the same Wi-Fi network, but from different provider, they would have the same key. 3893 * @hide 3894 */ getNetworkKey()3895 public String getNetworkKey() { 3896 // Passpoint ephemeral networks have their unique identifier set. Return it as is to be 3897 // able to match internally. 3898 if (mPasspointUniqueId != null) { 3899 return mPasspointUniqueId; 3900 } 3901 3902 String key = getSsidAndSecurityTypeString(); 3903 if (!shared) { 3904 key += "-" + UserHandle.getUserHandleForUid(creatorUid).getIdentifier(); 3905 } 3906 3907 return key; 3908 } 3909 3910 /** @hide 3911 * return the SSID + security type in String format. 3912 */ getSsidAndSecurityTypeString()3913 public String getSsidAndSecurityTypeString() { 3914 return (!TextUtils.isEmpty(SSID) && SSID.charAt(0) != '\"' ? SSID.toLowerCase() : SSID) 3915 + getDefaultSecurityType(); 3916 } 3917 3918 /** 3919 * Get the IpConfiguration object associated with this WifiConfiguration. 3920 * @hide 3921 */ 3922 @NonNull 3923 @SystemApi getIpConfiguration()3924 public IpConfiguration getIpConfiguration() { 3925 return new IpConfiguration(mIpConfiguration); 3926 } 3927 3928 /** 3929 * Set the {@link IpConfiguration} for this network. 3930 * 3931 * @param ipConfiguration a {@link IpConfiguration} to use for this Wi-Fi configuration, or 3932 * {@code null} to use the default configuration. 3933 */ setIpConfiguration(@ullable IpConfiguration ipConfiguration)3934 public void setIpConfiguration(@Nullable IpConfiguration ipConfiguration) { 3935 if (ipConfiguration == null) ipConfiguration = new IpConfiguration(); 3936 mIpConfiguration = ipConfiguration; 3937 } 3938 3939 /** 3940 * Get the {@link StaticIpConfiguration} for this network. 3941 * @return the {@link StaticIpConfiguration}, or null if unset. 3942 * @hide 3943 */ 3944 @Nullable 3945 @UnsupportedAppUsage getStaticIpConfiguration()3946 public StaticIpConfiguration getStaticIpConfiguration() { 3947 return mIpConfiguration.getStaticIpConfiguration(); 3948 } 3949 3950 /** @hide */ 3951 @UnsupportedAppUsage 3952 @Keep setStaticIpConfiguration(StaticIpConfiguration staticIpConfiguration)3953 public void setStaticIpConfiguration(StaticIpConfiguration staticIpConfiguration) { 3954 mIpConfiguration.setStaticIpConfiguration(staticIpConfiguration); 3955 } 3956 3957 /** 3958 * Get the {@link IpConfiguration.IpAssignment} for this network. 3959 * @hide 3960 */ 3961 @NonNull 3962 @UnsupportedAppUsage 3963 @Keep getIpAssignment()3964 public IpConfiguration.IpAssignment getIpAssignment() { 3965 return mIpConfiguration.getIpAssignment(); 3966 } 3967 3968 /** @hide */ 3969 @UnsupportedAppUsage 3970 @Keep setIpAssignment(IpConfiguration.IpAssignment ipAssignment)3971 public void setIpAssignment(IpConfiguration.IpAssignment ipAssignment) { 3972 mIpConfiguration.setIpAssignment(ipAssignment); 3973 } 3974 3975 /** 3976 * Get the {@link IpConfiguration.ProxySettings} for this network. 3977 * @hide 3978 */ 3979 @NonNull 3980 @UnsupportedAppUsage getProxySettings()3981 public IpConfiguration.ProxySettings getProxySettings() { 3982 return mIpConfiguration.getProxySettings(); 3983 } 3984 3985 /** @hide */ 3986 @UnsupportedAppUsage setProxySettings(IpConfiguration.ProxySettings proxySettings)3987 public void setProxySettings(IpConfiguration.ProxySettings proxySettings) { 3988 mIpConfiguration.setProxySettings(proxySettings); 3989 } 3990 3991 /** 3992 * Returns the HTTP proxy used by this object. 3993 * @return a {@link ProxyInfo httpProxy} representing the proxy specified by this 3994 * WifiConfiguration, or {@code null} if no proxy is specified. 3995 */ getHttpProxy()3996 public ProxyInfo getHttpProxy() { 3997 if (mIpConfiguration.getProxySettings() == IpConfiguration.ProxySettings.NONE) { 3998 return null; 3999 } 4000 return new ProxyInfo(mIpConfiguration.getHttpProxy()); 4001 } 4002 4003 /** 4004 * Set the {@link ProxyInfo} for this WifiConfiguration. This method should only be used by a 4005 * device owner or profile owner. When other apps attempt to save a {@link WifiConfiguration} 4006 * with modified proxy settings, the methods {@link WifiManager#addNetwork} and 4007 * {@link WifiManager#updateNetwork} fail and return {@code -1}. 4008 * 4009 * @param httpProxy {@link ProxyInfo} representing the httpProxy to be used by this 4010 * WifiConfiguration. Setting this to {@code null} will explicitly set no 4011 * proxy, removing any proxy that was previously set. 4012 */ setHttpProxy(ProxyInfo httpProxy)4013 public void setHttpProxy(ProxyInfo httpProxy) { 4014 if (httpProxy == null) { 4015 mIpConfiguration.setProxySettings(IpConfiguration.ProxySettings.NONE); 4016 mIpConfiguration.setHttpProxy(null); 4017 return; 4018 } 4019 ProxyInfo httpProxyCopy; 4020 ProxySettings proxySettingCopy; 4021 if (!Uri.EMPTY.equals(httpProxy.getPacFileUrl())) { 4022 proxySettingCopy = IpConfiguration.ProxySettings.PAC; 4023 // Construct a new PAC URL Proxy 4024 httpProxyCopy = ProxyInfo.buildPacProxy(httpProxy.getPacFileUrl(), httpProxy.getPort()); 4025 } else { 4026 proxySettingCopy = IpConfiguration.ProxySettings.STATIC; 4027 // Construct a new HTTP Proxy 4028 String[] exclusionList = httpProxy.getExclusionList(); 4029 if (exclusionList == null) { 4030 exclusionList = new String[0]; 4031 } 4032 httpProxyCopy = ProxyInfo.buildDirectProxy(httpProxy.getHost(), httpProxy.getPort(), 4033 Arrays.asList(exclusionList)); 4034 } 4035 if (!httpProxyCopy.isValid()) { 4036 Log.w(TAG, "ProxyInfo is not valid: " + httpProxyCopy); 4037 } 4038 mIpConfiguration.setProxySettings(proxySettingCopy); 4039 mIpConfiguration.setHttpProxy(httpProxyCopy); 4040 } 4041 4042 /** 4043 * Set the {@link ProxySettings} and {@link ProxyInfo} for this network. 4044 * @hide 4045 */ 4046 @UnsupportedAppUsage setProxy(@onNull ProxySettings settings, @NonNull ProxyInfo proxy)4047 public void setProxy(@NonNull ProxySettings settings, @NonNull ProxyInfo proxy) { 4048 mIpConfiguration.setProxySettings(settings); 4049 mIpConfiguration.setHttpProxy(proxy); 4050 } 4051 4052 /** Implement the Parcelable interface {@hide} */ describeContents()4053 public int describeContents() { 4054 return 0; 4055 } 4056 4057 /** @hide */ setPasspointManagementObjectTree(String passpointManagementObjectTree)4058 public void setPasspointManagementObjectTree(String passpointManagementObjectTree) { 4059 mPasspointManagementObjectTree = passpointManagementObjectTree; 4060 } 4061 4062 /** @hide */ getMoTree()4063 public String getMoTree() { 4064 return mPasspointManagementObjectTree; 4065 } 4066 4067 /** Copy constructor */ WifiConfiguration(@onNull WifiConfiguration source)4068 public WifiConfiguration(@NonNull WifiConfiguration source) { 4069 if (source != null) { 4070 networkId = source.networkId; 4071 status = source.status; 4072 SSID = source.SSID; 4073 BSSID = source.BSSID; 4074 FQDN = source.FQDN; 4075 roamingConsortiumIds = source.roamingConsortiumIds.clone(); 4076 providerFriendlyName = source.providerFriendlyName; 4077 isHomeProviderNetwork = source.isHomeProviderNetwork; 4078 preSharedKey = source.preSharedKey; 4079 4080 mNetworkSelectionStatus.copy(source.getNetworkSelectionStatus()); 4081 apBand = source.apBand; 4082 apChannel = source.apChannel; 4083 4084 wepKeys = new String[4]; 4085 for (int i = 0; i < wepKeys.length; i++) { 4086 wepKeys[i] = source.wepKeys[i]; 4087 } 4088 4089 wepTxKeyIndex = source.wepTxKeyIndex; 4090 priority = source.priority; 4091 mDeletionPriority = source.mDeletionPriority; 4092 hiddenSSID = source.hiddenSSID; 4093 allowedKeyManagement = (BitSet) source.allowedKeyManagement.clone(); 4094 allowedProtocols = (BitSet) source.allowedProtocols.clone(); 4095 allowedAuthAlgorithms = (BitSet) source.allowedAuthAlgorithms.clone(); 4096 allowedPairwiseCiphers = (BitSet) source.allowedPairwiseCiphers.clone(); 4097 allowedGroupCiphers = (BitSet) source.allowedGroupCiphers.clone(); 4098 allowedGroupManagementCiphers = (BitSet) source.allowedGroupManagementCiphers.clone(); 4099 allowedSuiteBCiphers = (BitSet) source.allowedSuiteBCiphers.clone(); 4100 mSecurityParamsList = new ArrayList<>(source.mSecurityParamsList.size()); 4101 source.mSecurityParamsList.forEach(p -> mSecurityParamsList.add(new SecurityParams(p))); 4102 enterpriseConfig = new WifiEnterpriseConfig(source.enterpriseConfig); 4103 4104 defaultGwMacAddress = source.defaultGwMacAddress; 4105 4106 mIpConfiguration = new IpConfiguration(source.mIpConfiguration); 4107 4108 if ((source.linkedConfigurations != null) 4109 && (source.linkedConfigurations.size() > 0)) { 4110 linkedConfigurations = new HashMap<String, Integer>(); 4111 linkedConfigurations.putAll(source.linkedConfigurations); 4112 } 4113 validatedInternetAccess = source.validatedInternetAccess; 4114 isLegacyPasspointConfig = source.isLegacyPasspointConfig; 4115 ephemeral = source.ephemeral; 4116 osu = source.osu; 4117 trusted = source.trusted; 4118 restricted = source.restricted; 4119 oemPaid = source.oemPaid; 4120 oemPrivate = source.oemPrivate; 4121 carrierMerged = source.carrierMerged; 4122 fromWifiNetworkSuggestion = source.fromWifiNetworkSuggestion; 4123 fromWifiNetworkSpecifier = source.fromWifiNetworkSpecifier; 4124 meteredHint = source.meteredHint; 4125 mIsRepeaterEnabled = source.mIsRepeaterEnabled; 4126 meteredOverride = source.meteredOverride; 4127 useExternalScores = source.useExternalScores; 4128 4129 lastConnectUid = source.lastConnectUid; 4130 lastUpdateUid = source.lastUpdateUid; 4131 creatorUid = source.creatorUid; 4132 creatorName = source.creatorName; 4133 lastUpdateName = source.lastUpdateName; 4134 peerWifiConfiguration = source.peerWifiConfiguration; 4135 4136 lastConnected = source.lastConnected; 4137 lastDisconnected = source.lastDisconnected; 4138 lastUpdated = source.lastUpdated; 4139 numRebootsSinceLastUse = source.numRebootsSinceLastUse; 4140 numScorerOverride = source.numScorerOverride; 4141 numScorerOverrideAndSwitchedNetwork = source.numScorerOverrideAndSwitchedNetwork; 4142 numAssociation = source.numAssociation; 4143 allowAutojoin = source.allowAutojoin; 4144 numNoInternetAccessReports = source.numNoInternetAccessReports; 4145 noInternetAccessExpected = source.noInternetAccessExpected; 4146 shared = source.shared; 4147 recentFailure.setAssociationStatus(source.recentFailure.getAssociationStatus(), 4148 source.recentFailure.getLastUpdateTimeSinceBootMillis()); 4149 mRandomizedMacAddress = source.mRandomizedMacAddress; 4150 macRandomizationSetting = source.macRandomizationSetting; 4151 randomizedMacExpirationTimeMs = source.randomizedMacExpirationTimeMs; 4152 randomizedMacLastModifiedTimeMs = source.randomizedMacLastModifiedTimeMs; 4153 mIsSendDhcpHostnameEnabled = source.mIsSendDhcpHostnameEnabled; 4154 requirePmf = source.requirePmf; 4155 updateIdentifier = source.updateIdentifier; 4156 carrierId = source.carrierId; 4157 subscriptionId = source.subscriptionId; 4158 mPasspointUniqueId = source.mPasspointUniqueId; 4159 mSubscriptionGroup = source.mSubscriptionGroup; 4160 if (source.mBssidAllowlist != null) { 4161 mBssidAllowlist = new ArrayList<>(source.mBssidAllowlist); 4162 } else { 4163 mBssidAllowlist = null; 4164 } 4165 mIsDppConfigurator = source.mIsDppConfigurator; 4166 mDppPrivateEcKey = source.mDppPrivateEcKey.clone(); 4167 mDppConnector = source.mDppConnector.clone(); 4168 mDppCSignKey = source.mDppCSignKey.clone(); 4169 mDppNetAccessKey = source.mDppNetAccessKey.clone(); 4170 isCurrentlyConnected = source.isCurrentlyConnected; 4171 mIsUserSelected = source.mIsUserSelected; 4172 mHasPreSharedKeyChanged = source.hasPreSharedKeyChanged(); 4173 mEncryptedPreSharedKey = source.mEncryptedPreSharedKey != null 4174 ? source.mEncryptedPreSharedKey.clone() : new byte[0]; 4175 mEncryptedPreSharedKeyIv = source.mEncryptedPreSharedKeyIv != null 4176 ? source.mEncryptedPreSharedKeyIv.clone() : new byte[0]; 4177 mIpProvisioningTimedOut = source.mIpProvisioningTimedOut; 4178 mVendorData = new ArrayList<>(source.mVendorData); 4179 mWifi7Enabled = source.mWifi7Enabled; 4180 } 4181 } 4182 4183 /** Implement the Parcelable interface {@hide} */ 4184 @Override writeToParcel(Parcel dest, int flags)4185 public void writeToParcel(Parcel dest, int flags) { 4186 dest.writeInt(networkId); 4187 dest.writeInt(status); 4188 mNetworkSelectionStatus.writeToParcel(dest, flags); 4189 dest.writeString(SSID); 4190 dest.writeString(BSSID); 4191 dest.writeInt(apBand); 4192 dest.writeInt(apChannel); 4193 dest.writeString(FQDN); 4194 dest.writeString(providerFriendlyName); 4195 dest.writeInt(isHomeProviderNetwork ? 1 : 0); 4196 dest.writeInt(roamingConsortiumIds.length); 4197 for (long roamingConsortiumId : roamingConsortiumIds) { 4198 dest.writeLong(roamingConsortiumId); 4199 } 4200 dest.writeString(preSharedKey); 4201 for (String wepKey : wepKeys) { 4202 dest.writeString(wepKey); 4203 } 4204 dest.writeInt(wepTxKeyIndex); 4205 dest.writeInt(priority); 4206 dest.writeInt(mDeletionPriority); 4207 dest.writeInt(hiddenSSID ? 1 : 0); 4208 dest.writeInt(requirePmf ? 1 : 0); 4209 dest.writeString(updateIdentifier); 4210 4211 writeBitSet(dest, allowedKeyManagement); 4212 writeBitSet(dest, allowedProtocols); 4213 writeBitSet(dest, allowedAuthAlgorithms); 4214 writeBitSet(dest, allowedPairwiseCiphers); 4215 writeBitSet(dest, allowedGroupCiphers); 4216 writeBitSet(dest, allowedGroupManagementCiphers); 4217 writeBitSet(dest, allowedSuiteBCiphers); 4218 4219 dest.writeInt(mSecurityParamsList.size()); 4220 mSecurityParamsList.forEach(params -> dest.writeParcelable(params, flags)); 4221 4222 dest.writeParcelable(enterpriseConfig, flags); 4223 4224 dest.writeParcelable(mIpConfiguration, flags); 4225 dest.writeString(dhcpServer); 4226 dest.writeString(defaultGwMacAddress); 4227 dest.writeInt(validatedInternetAccess ? 1 : 0); 4228 dest.writeInt(isLegacyPasspointConfig ? 1 : 0); 4229 dest.writeInt(ephemeral ? 1 : 0); 4230 dest.writeInt(trusted ? 1 : 0); 4231 dest.writeInt(oemPaid ? 1 : 0); 4232 dest.writeInt(oemPrivate ? 1 : 0); 4233 dest.writeInt(carrierMerged ? 1 : 0); 4234 dest.writeInt(fromWifiNetworkSuggestion ? 1 : 0); 4235 dest.writeInt(fromWifiNetworkSpecifier ? 1 : 0); 4236 dest.writeInt(meteredHint ? 1 : 0); 4237 dest.writeBoolean(mIsRepeaterEnabled); 4238 dest.writeInt(meteredOverride); 4239 dest.writeInt(useExternalScores ? 1 : 0); 4240 dest.writeInt(creatorUid); 4241 dest.writeInt(lastConnectUid); 4242 dest.writeInt(lastUpdateUid); 4243 dest.writeString(creatorName); 4244 dest.writeString(lastUpdateName); 4245 dest.writeInt(numScorerOverride); 4246 dest.writeInt(numScorerOverrideAndSwitchedNetwork); 4247 dest.writeInt(numAssociation); 4248 dest.writeBoolean(allowAutojoin); 4249 dest.writeInt(numNoInternetAccessReports); 4250 dest.writeInt(noInternetAccessExpected ? 1 : 0); 4251 dest.writeInt(shared ? 1 : 0); 4252 dest.writeString(mPasspointManagementObjectTree); 4253 dest.writeInt(recentFailure.getAssociationStatus()); 4254 dest.writeLong(recentFailure.getLastUpdateTimeSinceBootMillis()); 4255 dest.writeParcelable(mRandomizedMacAddress, flags); 4256 dest.writeInt(macRandomizationSetting); 4257 dest.writeBoolean(mIsSendDhcpHostnameEnabled); 4258 dest.writeInt(osu ? 1 : 0); 4259 dest.writeLong(randomizedMacExpirationTimeMs); 4260 dest.writeLong(randomizedMacLastModifiedTimeMs); 4261 dest.writeInt(carrierId); 4262 dest.writeString(mPasspointUniqueId); 4263 dest.writeInt(subscriptionId); 4264 dest.writeBoolean(restricted); 4265 dest.writeParcelable(mSubscriptionGroup, flags); 4266 dest.writeList(mBssidAllowlist); 4267 dest.writeBoolean(mIsDppConfigurator); 4268 dest.writeByteArray(mDppPrivateEcKey); 4269 dest.writeByteArray(mDppConnector); 4270 dest.writeByteArray(mDppCSignKey); 4271 dest.writeByteArray(mDppNetAccessKey); 4272 dest.writeBoolean(isCurrentlyConnected); 4273 dest.writeBoolean(mIsUserSelected); 4274 dest.writeBoolean(mHasPreSharedKeyChanged); 4275 dest.writeByteArray(mEncryptedPreSharedKey); 4276 dest.writeByteArray(mEncryptedPreSharedKeyIv); 4277 dest.writeBoolean(mIpProvisioningTimedOut); 4278 dest.writeList(mVendorData); 4279 dest.writeBoolean(mWifi7Enabled); 4280 } 4281 4282 /** Implement the Parcelable interface {@hide} */ 4283 @SystemApi 4284 public static final @android.annotation.NonNull Creator<WifiConfiguration> CREATOR = 4285 new Creator<WifiConfiguration>() { 4286 public WifiConfiguration createFromParcel(Parcel in) { 4287 WifiConfiguration config = new WifiConfiguration(); 4288 config.networkId = in.readInt(); 4289 config.status = in.readInt(); 4290 config.mNetworkSelectionStatus.readFromParcel(in); 4291 config.SSID = in.readString(); 4292 config.BSSID = in.readString(); 4293 config.apBand = in.readInt(); 4294 config.apChannel = in.readInt(); 4295 config.FQDN = in.readString(); 4296 config.providerFriendlyName = in.readString(); 4297 config.isHomeProviderNetwork = in.readInt() != 0; 4298 int numRoamingConsortiumIds = in.readInt(); 4299 config.roamingConsortiumIds = new long[numRoamingConsortiumIds]; 4300 for (int i = 0; i < numRoamingConsortiumIds; i++) { 4301 config.roamingConsortiumIds[i] = in.readLong(); 4302 } 4303 config.preSharedKey = in.readString(); 4304 for (int i = 0; i < config.wepKeys.length; i++) { 4305 config.wepKeys[i] = in.readString(); 4306 } 4307 config.wepTxKeyIndex = in.readInt(); 4308 config.priority = in.readInt(); 4309 config.mDeletionPriority = in.readInt(); 4310 config.hiddenSSID = in.readInt() != 0; 4311 config.requirePmf = in.readInt() != 0; 4312 config.updateIdentifier = in.readString(); 4313 4314 config.allowedKeyManagement = readBitSet(in); 4315 config.allowedProtocols = readBitSet(in); 4316 config.allowedAuthAlgorithms = readBitSet(in); 4317 config.allowedPairwiseCiphers = readBitSet(in); 4318 config.allowedGroupCiphers = readBitSet(in); 4319 config.allowedGroupManagementCiphers = readBitSet(in); 4320 config.allowedSuiteBCiphers = readBitSet(in); 4321 4322 int numSecurityParams = in.readInt(); 4323 for (int i = 0; i < numSecurityParams; i++) { 4324 config.mSecurityParamsList.add( 4325 in.readParcelable(SecurityParams.class.getClassLoader())); 4326 } 4327 4328 config.enterpriseConfig = in.readParcelable( 4329 WifiEnterpriseConfig.class.getClassLoader()); 4330 config.setIpConfiguration( 4331 in.readParcelable(IpConfiguration.class.getClassLoader())); 4332 config.dhcpServer = in.readString(); 4333 config.defaultGwMacAddress = in.readString(); 4334 config.validatedInternetAccess = in.readInt() != 0; 4335 config.isLegacyPasspointConfig = in.readInt() != 0; 4336 config.ephemeral = in.readInt() != 0; 4337 config.trusted = in.readInt() != 0; 4338 config.oemPaid = in.readInt() != 0; 4339 config.oemPrivate = in.readInt() != 0; 4340 config.carrierMerged = in.readInt() != 0; 4341 config.fromWifiNetworkSuggestion = in.readInt() != 0; 4342 config.fromWifiNetworkSpecifier = in.readInt() != 0; 4343 config.meteredHint = in.readInt() != 0; 4344 config.mIsRepeaterEnabled = in.readBoolean(); 4345 config.meteredOverride = in.readInt(); 4346 config.useExternalScores = in.readInt() != 0; 4347 config.creatorUid = in.readInt(); 4348 config.lastConnectUid = in.readInt(); 4349 config.lastUpdateUid = in.readInt(); 4350 config.creatorName = in.readString(); 4351 config.lastUpdateName = in.readString(); 4352 config.numScorerOverride = in.readInt(); 4353 config.numScorerOverrideAndSwitchedNetwork = in.readInt(); 4354 config.numAssociation = in.readInt(); 4355 config.allowAutojoin = in.readBoolean(); 4356 config.numNoInternetAccessReports = in.readInt(); 4357 config.noInternetAccessExpected = in.readInt() != 0; 4358 config.shared = in.readInt() != 0; 4359 config.mPasspointManagementObjectTree = in.readString(); 4360 config.recentFailure.setAssociationStatus(in.readInt(), in.readLong()); 4361 config.mRandomizedMacAddress = in.readParcelable( 4362 MacAddress.class.getClassLoader()); 4363 config.macRandomizationSetting = in.readInt(); 4364 config.mIsSendDhcpHostnameEnabled = in.readBoolean(); 4365 config.osu = in.readInt() != 0; 4366 config.randomizedMacExpirationTimeMs = in.readLong(); 4367 config.randomizedMacLastModifiedTimeMs = in.readLong(); 4368 config.carrierId = in.readInt(); 4369 config.mPasspointUniqueId = in.readString(); 4370 config.subscriptionId = in.readInt(); 4371 config.restricted = in.readBoolean(); 4372 config.mSubscriptionGroup = in.readParcelable( 4373 ParcelUuid.class.getClassLoader()); 4374 config.mBssidAllowlist = in.readArrayList(MacAddress.class.getClassLoader()); 4375 config.mIsDppConfigurator = in.readBoolean(); 4376 config.mDppPrivateEcKey = in.createByteArray(); 4377 if (config.mDppPrivateEcKey == null) { 4378 config.mDppPrivateEcKey = new byte[0]; 4379 } 4380 config.mDppConnector = in.createByteArray(); 4381 if (config.mDppConnector == null) { 4382 config.mDppConnector = new byte[0]; 4383 } 4384 config.mDppCSignKey = in.createByteArray(); 4385 if (config.mDppCSignKey == null) { 4386 config.mDppCSignKey = new byte[0]; 4387 } 4388 config.mDppNetAccessKey = in.createByteArray(); 4389 if (config.mDppNetAccessKey == null) { 4390 config.mDppNetAccessKey = new byte[0]; 4391 } 4392 config.isCurrentlyConnected = in.readBoolean(); 4393 config.mIsUserSelected = in.readBoolean(); 4394 config.mHasPreSharedKeyChanged = in.readBoolean(); 4395 config.mEncryptedPreSharedKey = in.createByteArray(); 4396 if (config.mEncryptedPreSharedKey == null) { 4397 config.mEncryptedPreSharedKey = new byte[0]; 4398 } 4399 config.mEncryptedPreSharedKeyIv = in.createByteArray(); 4400 if (config.mEncryptedPreSharedKeyIv == null) { 4401 config.mEncryptedPreSharedKeyIv = new byte[0]; 4402 } 4403 config.mIpProvisioningTimedOut = in.readBoolean(); 4404 config.mVendorData = ParcelUtil.readOuiKeyedDataList(in); 4405 config.mWifi7Enabled = in.readBoolean(); 4406 return config; 4407 } 4408 4409 public WifiConfiguration[] newArray(int size) { 4410 return new WifiConfiguration[size]; 4411 } 4412 }; 4413 4414 /** 4415 * Passpoint Unique identifier 4416 * @hide 4417 */ 4418 private String mPasspointUniqueId = null; 4419 4420 /** 4421 * Set the Passpoint unique identifier 4422 * @param uniqueId Passpoint unique identifier to be set 4423 * @hide 4424 */ setPasspointUniqueId(String uniqueId)4425 public void setPasspointUniqueId(String uniqueId) { 4426 mPasspointUniqueId = uniqueId; 4427 } 4428 4429 /** 4430 * Set the Passpoint unique identifier 4431 * @hide 4432 */ getPasspointUniqueId()4433 public String getPasspointUniqueId() { 4434 return mPasspointUniqueId; 4435 } 4436 4437 /** 4438 * If network is one of the most recently connected. 4439 * For framework internal use only. Do not parcel. 4440 * @hide 4441 */ 4442 public boolean isMostRecentlyConnected = false; 4443 4444 /** 4445 * Whether the network is currently connected or not. 4446 * Note: May be true even if {@link #status} is not CURRENT, since a config 4447 * can be connected, but disabled for network selection. 4448 * TODO (b/235236813): This field may be redundant, since we have information 4449 * like {@link #status} and quality network selection status. May need 4450 * to clean up the fields used for network selection. 4451 * @hide 4452 */ 4453 public boolean isCurrentlyConnected = false; 4454 4455 private boolean mIsUserSelected = false; 4456 4457 /** 4458 * Sets whether the network is connected by user selection or not. 4459 * @hide 4460 */ setIsUserSelected(boolean isUserSelected)4461 public boolean setIsUserSelected(boolean isUserSelected) { 4462 return mIsUserSelected = isUserSelected; 4463 } 4464 4465 /** 4466 * Whether the network is connected by user selection or not. 4467 * @hide 4468 */ isUserSelected()4469 public boolean isUserSelected() { 4470 return mIsUserSelected; 4471 } 4472 4473 /** 4474 * Whether the key mgmt indicates if the WifiConfiguration needs a preSharedKey or not. 4475 * @return true if preSharedKey is needed, false otherwise. 4476 * @hide 4477 */ 4478 @Keep needsPreSharedKey()4479 public boolean needsPreSharedKey() { 4480 for (SecurityParams params : mSecurityParamsList) { 4481 if (params.isSecurityType(SECURITY_TYPE_PSK) 4482 || params.isSecurityType(SECURITY_TYPE_SAE) 4483 || params.isSecurityType(SECURITY_TYPE_WAPI_PSK)) { 4484 return true; 4485 } 4486 } 4487 return false; 4488 } 4489 4490 /** 4491 * Return if the encrypted data is present 4492 * @return true if encrypted data is present 4493 * @hide 4494 */ hasEncryptedPreSharedKey()4495 public boolean hasEncryptedPreSharedKey() { 4496 if (mEncryptedPreSharedKey == null || mEncryptedPreSharedKeyIv == null) return false; 4497 return !(mEncryptedPreSharedKey.length == 0 && mEncryptedPreSharedKeyIv.length == 0); 4498 } 4499 4500 /** 4501 * Set the encrypted data for preSharedKey 4502 * @param encryptedPreSharedKey encrypted preSharedKey 4503 * @param encryptedPreSharedKeyIv encrypted preSharedKey 4504 * @hide 4505 */ setEncryptedPreSharedKey(byte[] encryptedPreSharedKey, byte[] encryptedPreSharedKeyIv)4506 public void setEncryptedPreSharedKey(byte[] encryptedPreSharedKey, 4507 byte[] encryptedPreSharedKeyIv) { 4508 mEncryptedPreSharedKey = encryptedPreSharedKey; 4509 mEncryptedPreSharedKeyIv = encryptedPreSharedKeyIv; 4510 } 4511 4512 /** 4513 * Get the encrypted data 4514 * 4515 * @return encrypted data of the WifiConfiguration 4516 * @hide 4517 */ getEncryptedPreSharedKey()4518 public byte[] getEncryptedPreSharedKey() { 4519 return mEncryptedPreSharedKey; 4520 } 4521 4522 /** 4523 * Get the encrypted data IV 4524 * 4525 * @return encrypted data IV of the WifiConfiguration 4526 * @hide 4527 */ getEncryptedPreSharedKeyIv()4528 public byte[] getEncryptedPreSharedKeyIv() { 4529 return mEncryptedPreSharedKeyIv; 4530 } 4531 4532 /** 4533 * Check whether the configuration's password has changed. 4534 * If true, the encrypted data is no longer valid. 4535 * 4536 * @return true if preSharedKey encryption is needed, false otherwise. 4537 * @hide 4538 */ 4539 @Keep hasPreSharedKeyChanged()4540 public boolean hasPreSharedKeyChanged() { 4541 return mHasPreSharedKeyChanged; 4542 } 4543 4544 /** 4545 * Set whether the WifiConfiguration needs a preSharedKey encryption. 4546 * 4547 * @param changed true if preSharedKey is changed, false otherwise. 4548 * @hide 4549 */ setHasPreSharedKeyChanged(boolean changed)4550 public void setHasPreSharedKeyChanged(boolean changed) { 4551 mHasPreSharedKeyChanged = changed; 4552 if (mHasPreSharedKeyChanged) { 4553 mEncryptedPreSharedKey = new byte[0]; 4554 mEncryptedPreSharedKeyIv = new byte[0]; 4555 } 4556 } 4557 4558 /** 4559 * Get a unique key which represent this Wi-Fi configuration profile. If two profiles are for 4560 * the same Wi-Fi network, but from different providers (apps, carriers, or data subscriptions), 4561 * they would have different keys. 4562 * @return a unique key which represent this profile. 4563 * @hide 4564 */ 4565 @SystemApi getProfileKey()4566 @NonNull public String getProfileKey() { 4567 if (!SdkLevel.isAtLeastS()) { 4568 return getKey(); 4569 } 4570 if (mPasspointUniqueId != null) { 4571 return mPasspointUniqueId; 4572 } 4573 4574 String key = getSsidAndSecurityTypeString(); 4575 if (!shared) { 4576 key += "-" + UserHandle.getUserHandleForUid(creatorUid).getIdentifier(); 4577 } 4578 if (fromWifiNetworkSuggestion) { 4579 key += "_" + creatorName + "-" + carrierId + "-" + subscriptionId; 4580 } 4581 4582 return key; 4583 } 4584 4585 /** 4586 * Get the default security type string. 4587 * @hide 4588 */ getDefaultSecurityType()4589 public String getDefaultSecurityType() { 4590 String key; 4591 if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) { 4592 key = KeyMgmt.strings[KeyMgmt.WPA_PSK]; 4593 } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP) 4594 || allowedKeyManagement.get(KeyMgmt.IEEE8021X)) { 4595 if (isWpa3EnterpriseConfiguration()) { 4596 key = "WPA3_EAP"; 4597 } else { 4598 key = KeyMgmt.strings[KeyMgmt.WPA_EAP]; 4599 } 4600 } else if (wepTxKeyIndex >= 0 && wepTxKeyIndex < wepKeys.length 4601 && wepKeys[wepTxKeyIndex] != null) { 4602 key = "WEP"; 4603 } else if (allowedKeyManagement.get(KeyMgmt.OWE)) { 4604 key = KeyMgmt.strings[KeyMgmt.OWE]; 4605 } else if (allowedKeyManagement.get(KeyMgmt.SAE)) { 4606 key = KeyMgmt.strings[KeyMgmt.SAE]; 4607 } else if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) { 4608 key = KeyMgmt.strings[KeyMgmt.SUITE_B_192]; 4609 } else if (allowedKeyManagement.get(KeyMgmt.WAPI_PSK)) { 4610 key = KeyMgmt.strings[KeyMgmt.WAPI_PSK]; 4611 } else if (allowedKeyManagement.get(KeyMgmt.WAPI_CERT)) { 4612 key = KeyMgmt.strings[KeyMgmt.WAPI_CERT]; 4613 } else if (allowedKeyManagement.get(KeyMgmt.OSEN)) { 4614 key = KeyMgmt.strings[KeyMgmt.OSEN]; 4615 } else if (allowedKeyManagement.get(KeyMgmt.DPP)) { 4616 key = KeyMgmt.strings[KeyMgmt.DPP]; 4617 } else { 4618 key = KeyMgmt.strings[KeyMgmt.NONE]; 4619 } 4620 return key; 4621 } 4622 4623 /** 4624 * Get the security type name. 4625 * 4626 * @param securityType One of the following security types: 4627 * {@link #SECURITY_TYPE_OPEN}, 4628 * {@link #SECURITY_TYPE_WEP}, 4629 * {@link #SECURITY_TYPE_PSK}, 4630 * {@link #SECURITY_TYPE_EAP}, 4631 * {@link #SECURITY_TYPE_SAE}, 4632 * {@link #SECURITY_TYPE_OWE}, 4633 * {@link #SECURITY_TYPE_WAPI_PSK}, 4634 * {@link #SECURITY_TYPE_WAPI_CERT}, 4635 * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE}, 4636 * {@link #SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT}, 4637 * {@link #SECURITY_TYPE_PASSPOINT_R1_R2}, 4638 * {@link #SECURITY_TYPE_PASSPOINT_R3}, 4639 * or {@link #SECURITY_TYPE_DPP}. 4640 * @return the name of the given type. 4641 * @hide 4642 */ getSecurityTypeName(@ecurityType int securityType)4643 public static String getSecurityTypeName(@SecurityType int securityType) { 4644 if (securityType < SECURITY_TYPE_OPEN || SECURITY_TYPE_NUM < securityType) { 4645 return "unknown"; 4646 } 4647 return SECURITY_TYPE_NAMES[securityType]; 4648 } 4649 4650 /** 4651 * Returns the key for storing the data usage bucket. 4652 * 4653 * Note: DO NOT change this function. It is used to be a key to store Wi-Fi data usage data. 4654 * Create a new function if we plan to change the key for Wi-Fi data usage and add the new key 4655 * to {@link #getAllNetworkKeys()}. 4656 * 4657 * @param securityType the security type corresponding to the target network. 4658 * @hide 4659 */ getNetworkKeyFromSecurityType(@ecurityType int securityType)4660 public String getNetworkKeyFromSecurityType(@SecurityType int securityType) { 4661 if (mPasspointUniqueId != null) { 4662 // It might happen that there are two connections which use the same passpoint 4663 // coniguration but different sim card (maybe same carriers?). Add subscriptionId to be 4664 // the part of key to separate data in usage bucket. 4665 // But now we only show one WifiConfiguration entry in Wifi picker for this case. 4666 // It means that user only have a way to query usage with configuration on default SIM. 4667 // (We always connect to network with default SIM). So returns the key with associated 4668 // subscriptionId (the default one) first. 4669 return subscriptionId + "-" + mPasspointUniqueId; 4670 } else { 4671 String key = (!TextUtils.isEmpty(SSID) && SSID.charAt(0) != '\"' 4672 ? SSID.toLowerCase() : SSID) + getSecurityTypeName(securityType); 4673 if (!shared) { 4674 key += "-" + UserHandle.getUserHandleForUid(creatorUid).getIdentifier(); 4675 } 4676 if (fromWifiNetworkSuggestion) { 4677 key += "_" + creatorName + "-" + carrierId + "-" + subscriptionId; 4678 } 4679 return key; 4680 } 4681 } 4682 4683 /** 4684 * Returns a list of all persistable network keys corresponding to this configuration. 4685 * There may be multiple keys since they are security-type specific and a configuration may 4686 * support multiple security types. The persistable key of a specific network connection may 4687 * be obtained from {@link WifiInfo#getNetworkKey()}. 4688 * An example of usage of such persistable network keys is to query the Wi-Fi data usage 4689 * corresponding to this configuration. See {@code NetworkTemplate} to know the detail. 4690 * 4691 * @hide 4692 */ 4693 @SystemApi 4694 @NonNull getAllNetworkKeys()4695 public Set<String> getAllNetworkKeys() { 4696 Set<String> keys = new HashSet<>(); 4697 for (SecurityParams securityParam : mSecurityParamsList) { 4698 keys.add(getNetworkKeyFromSecurityType(securityParam.getSecurityType())); 4699 } 4700 return keys; 4701 } 4702 4703 /** 4704 * Set the subscription group uuid associated with current configuration. 4705 * @hide 4706 */ setSubscriptionGroup(@ullable ParcelUuid subscriptionGroup)4707 public void setSubscriptionGroup(@Nullable ParcelUuid subscriptionGroup) { 4708 this.mSubscriptionGroup = subscriptionGroup; 4709 } 4710 4711 /** 4712 * Get the subscription group uuid associated with current configuration. 4713 * @hide 4714 */ getSubscriptionGroup()4715 public @Nullable ParcelUuid getSubscriptionGroup() { 4716 return this.mSubscriptionGroup; 4717 } 4718 4719 /** 4720 * Return the vendor-provided configuration data, if it exists. See also {@link 4721 * #setVendorData(List)} 4722 * 4723 * @return Vendor configuration data, or empty list if it does not exist. 4724 * @hide 4725 */ 4726 @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) 4727 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 4728 @NonNull 4729 @SystemApi getVendorData()4730 public List<OuiKeyedData> getVendorData() { 4731 if (!SdkLevel.isAtLeastV()) { 4732 throw new UnsupportedOperationException(); 4733 } 4734 return mVendorData; 4735 } 4736 4737 /** 4738 * Set additional vendor-provided configuration data. 4739 * 4740 * Setting this field requires the MANAGE_WIFI_NETWORK_SELECTION permission. Otherwise, 4741 * if this data is set, the configuration will be rejected upon add or update. 4742 * 4743 * @param vendorData List of {@link OuiKeyedData} containing the vendor-provided 4744 * configuration data. Note that multiple elements with the same OUI are allowed. 4745 * @hide 4746 */ 4747 @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) 4748 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 4749 @SystemApi setVendorData(@onNull List<OuiKeyedData> vendorData)4750 public void setVendorData(@NonNull List<OuiKeyedData> vendorData) { 4751 if (!SdkLevel.isAtLeastV()) { 4752 throw new UnsupportedOperationException(); 4753 } 4754 Objects.requireNonNull(vendorData); 4755 mVendorData = new ArrayList<>(vendorData); 4756 } 4757 4758 /** 4759 * Whether Wi-Fi 7 is enabled for this network. 4760 * 4761 * @return true if enabled; false otherwise 4762 * @hide 4763 */ 4764 @SystemApi 4765 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) isWifi7Enabled()4766 public boolean isWifi7Enabled() { 4767 return mWifi7Enabled; 4768 } 4769 4770 /** 4771 * Sets whether Wi-Fi 7 is enabled for this network. 4772 * 4773 * @param enabled true if enabled; false otherwise 4774 * @hide 4775 */ 4776 @SystemApi 4777 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) setWifi7Enabled(boolean enabled)4778 public void setWifi7Enabled(boolean enabled) { 4779 mWifi7Enabled = enabled; 4780 } 4781 } 4782