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