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