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