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