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.SystemApi; 22 import android.compat.annotation.UnsupportedAppUsage; 23 import android.content.pm.PackageManager; 24 import android.net.IpConfiguration; 25 import android.net.IpConfiguration.ProxySettings; 26 import android.net.MacAddress; 27 import android.net.NetworkSpecifier; 28 import android.net.ProxyInfo; 29 import android.net.StaticIpConfiguration; 30 import android.net.Uri; 31 import android.net.util.MacAddressUtils; 32 import android.os.Build; 33 import android.os.Parcel; 34 import android.os.Parcelable; 35 import android.os.SystemClock; 36 import android.os.UserHandle; 37 import android.text.TextUtils; 38 import android.util.BackupUtils; 39 import android.util.Log; 40 import android.util.TimeUtils; 41 42 import java.io.ByteArrayOutputStream; 43 import java.io.DataInputStream; 44 import java.io.DataOutputStream; 45 import java.io.IOException; 46 import java.lang.annotation.Retention; 47 import java.lang.annotation.RetentionPolicy; 48 import java.util.Arrays; 49 import java.util.BitSet; 50 import java.util.HashMap; 51 52 /** 53 * A class representing a configured Wi-Fi network, including the 54 * security configuration. 55 * 56 * @deprecated Use {@link WifiNetworkSpecifier.Builder} to create {@link NetworkSpecifier} and 57 * {@link WifiNetworkSuggestion.Builder} to create {@link WifiNetworkSuggestion}. This will become a 58 * system use only object in the future. 59 */ 60 @Deprecated 61 public class WifiConfiguration implements Parcelable { 62 private static final String TAG = "WifiConfiguration"; 63 /** 64 * Current Version of the Backup Serializer. 65 */ 66 private static final int BACKUP_VERSION = 3; 67 /** {@hide} */ 68 public static final String ssidVarName = "ssid"; 69 /** {@hide} */ 70 public static final String bssidVarName = "bssid"; 71 /** {@hide} */ 72 public static final String pskVarName = "psk"; 73 /** {@hide} */ 74 @Deprecated 75 @UnsupportedAppUsage 76 public static final String[] wepKeyVarNames = { "wep_key0", "wep_key1", "wep_key2", "wep_key3" }; 77 /** {@hide} */ 78 @Deprecated 79 public static final String wepTxKeyIdxVarName = "wep_tx_keyidx"; 80 /** {@hide} */ 81 public static final String priorityVarName = "priority"; 82 /** {@hide} */ 83 public static final String hiddenSSIDVarName = "scan_ssid"; 84 /** {@hide} */ 85 public static final String pmfVarName = "ieee80211w"; 86 /** {@hide} */ 87 public static final String updateIdentiferVarName = "update_identifier"; 88 /** {@hide} */ 89 public static final int INVALID_NETWORK_ID = -1; 90 /** {@hide} */ 91 public static final int LOCAL_ONLY_NETWORK_ID = -2; 92 93 /** {@hide} */ 94 private String mPasspointManagementObjectTree; 95 /** {@hide} */ 96 private static final int MAXIMUM_RANDOM_MAC_GENERATION_RETRY = 3; 97 98 /** 99 * Recognized key management schemes. 100 */ 101 public static class KeyMgmt { KeyMgmt()102 private KeyMgmt() { } 103 104 /** WPA is not used; plaintext or static WEP could be used. */ 105 public static final int NONE = 0; 106 /** WPA pre-shared key (requires {@code preSharedKey} to be specified). */ 107 public static final int WPA_PSK = 1; 108 /** WPA using EAP authentication. Generally used with an external authentication server. */ 109 public static final int WPA_EAP = 2; 110 /** IEEE 802.1X using EAP authentication and (optionally) dynamically 111 * generated WEP keys. */ 112 public static final int IEEE8021X = 3; 113 114 /** WPA2 pre-shared key for use with soft access point 115 * (requires {@code preSharedKey} to be specified). 116 * @hide 117 */ 118 @SystemApi 119 public static final int WPA2_PSK = 4; 120 /** 121 * Hotspot 2.0 r2 OSEN: 122 * @hide 123 */ 124 public static final int OSEN = 5; 125 126 /** 127 * IEEE 802.11r Fast BSS Transition with PSK authentication. 128 * @hide 129 */ 130 public static final int FT_PSK = 6; 131 132 /** 133 * IEEE 802.11r Fast BSS Transition with EAP authentication. 134 * @hide 135 */ 136 public static final int FT_EAP = 7; 137 138 /** 139 * Simultaneous Authentication of Equals 140 */ 141 public static final int SAE = 8; 142 143 /** 144 * Opportunististic Wireless Encryption 145 */ 146 public static final int OWE = 9; 147 148 /** 149 * SUITE_B_192 192 bit level 150 */ 151 public static final int SUITE_B_192 = 10; 152 153 /** 154 * WPA pre-shared key with stronger SHA256-based algorithms. 155 * @hide 156 */ 157 public static final int WPA_PSK_SHA256 = 11; 158 159 /** 160 * WPA using EAP authentication with stronger SHA256-based algorithms. 161 * @hide 162 */ 163 public static final int WPA_EAP_SHA256 = 12; 164 165 public static final String varName = "key_mgmt"; 166 167 public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP", 168 "IEEE8021X", "WPA2_PSK", "OSEN", "FT_PSK", "FT_EAP", 169 "SAE", "OWE", "SUITE_B_192", "WPA_PSK_SHA256", "WPA_EAP_SHA256" }; 170 } 171 172 /** 173 * Recognized security protocols. 174 */ 175 public static class Protocol { Protocol()176 private Protocol() { } 177 178 /** WPA/IEEE 802.11i/D3.0 179 * @deprecated Due to security and performance limitations, use of WPA-1 networks 180 * is discouraged. WPA-2 (RSN) should be used instead. */ 181 @Deprecated 182 public static final int WPA = 0; 183 /** RSN WPA2/WPA3/IEEE 802.11i */ 184 public static final int RSN = 1; 185 /** HS2.0 r2 OSEN 186 * @hide 187 */ 188 public static final int OSEN = 2; 189 190 public static final String varName = "proto"; 191 192 public static final String[] strings = { "WPA", "RSN", "OSEN" }; 193 } 194 195 /** 196 * Recognized IEEE 802.11 authentication algorithms. 197 */ 198 public static class AuthAlgorithm { AuthAlgorithm()199 private AuthAlgorithm() { } 200 201 /** Open System authentication (required for WPA/WPA2) */ 202 public static final int OPEN = 0; 203 /** Shared Key authentication (requires static WEP keys) 204 * @deprecated Due to security and performance limitations, use of WEP networks 205 * is discouraged. */ 206 @Deprecated 207 public static final int SHARED = 1; 208 /** LEAP/Network EAP (only used with LEAP) */ 209 public static final int LEAP = 2; 210 211 public static final String varName = "auth_alg"; 212 213 public static final String[] strings = { "OPEN", "SHARED", "LEAP" }; 214 } 215 216 /** 217 * Recognized pairwise ciphers for WPA. 218 */ 219 public static class PairwiseCipher { PairwiseCipher()220 private PairwiseCipher() { } 221 222 /** Use only Group keys (deprecated) */ 223 public static final int NONE = 0; 224 /** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] 225 * @deprecated Due to security and performance limitations, use of WPA-1 networks 226 * is discouraged. WPA-2 (RSN) should be used instead. */ 227 @Deprecated 228 public static final int TKIP = 1; 229 /** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */ 230 public static final int CCMP = 2; 231 /** 232 * AES in Galois/Counter Mode 233 */ 234 public static final int GCMP_256 = 3; 235 236 public static final String varName = "pairwise"; 237 238 public static final String[] strings = { "NONE", "TKIP", "CCMP", "GCMP_256" }; 239 } 240 241 /** 242 * Recognized group ciphers. 243 * <pre> 244 * CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] 245 * TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] 246 * WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key 247 * WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11) 248 * GCMP_256 = AES in Galois/Counter Mode 249 * </pre> 250 */ 251 public static class GroupCipher { GroupCipher()252 private GroupCipher() { } 253 254 /** WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11) 255 * @deprecated Due to security and performance limitations, use of WEP networks 256 * is discouraged. */ 257 @Deprecated 258 public static final int WEP40 = 0; 259 /** WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key 260 * @deprecated Due to security and performance limitations, use of WEP networks 261 * is discouraged. */ 262 @Deprecated 263 public static final int WEP104 = 1; 264 /** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] */ 265 public static final int TKIP = 2; 266 /** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */ 267 public static final int CCMP = 3; 268 /** Hotspot 2.0 r2 OSEN 269 * @hide 270 */ 271 public static final int GTK_NOT_USED = 4; 272 /** 273 * AES in Galois/Counter Mode 274 */ 275 public static final int GCMP_256 = 5; 276 277 public static final String varName = "group"; 278 279 public static final String[] strings = 280 { /* deprecated */ "WEP40", /* deprecated */ "WEP104", 281 "TKIP", "CCMP", "GTK_NOT_USED", "GCMP_256" }; 282 } 283 284 /** 285 * Recognized group management ciphers. 286 * <pre> 287 * BIP_CMAC_256 = Cipher-based Message Authentication Code 256 bits 288 * BIP_GMAC_128 = Galois Message Authentication Code 128 bits 289 * BIP_GMAC_256 = Galois Message Authentication Code 256 bits 290 * </pre> 291 */ 292 public static class GroupMgmtCipher { GroupMgmtCipher()293 private GroupMgmtCipher() { } 294 295 /** CMAC-256 = Cipher-based Message Authentication Code */ 296 public static final int BIP_CMAC_256 = 0; 297 298 /** GMAC-128 = Galois Message Authentication Code */ 299 public static final int BIP_GMAC_128 = 1; 300 301 /** GMAC-256 = Galois Message Authentication Code */ 302 public static final int BIP_GMAC_256 = 2; 303 304 private static final String varName = "groupMgmt"; 305 306 private static final String[] strings = { "BIP_CMAC_256", 307 "BIP_GMAC_128", "BIP_GMAC_256"}; 308 } 309 310 /** 311 * Recognized suiteB ciphers. 312 * <pre> 313 * ECDHE_ECDSA 314 * ECDHE_RSA 315 * </pre> 316 * @hide 317 */ 318 public static class SuiteBCipher { SuiteBCipher()319 private SuiteBCipher() { } 320 321 /** Diffie-Hellman with Elliptic Curve_ECDSA signature */ 322 public static final int ECDHE_ECDSA = 0; 323 324 /** Diffie-Hellman with_RSA signature */ 325 public static final int ECDHE_RSA = 1; 326 327 private static final String varName = "SuiteB"; 328 329 private static final String[] strings = { "ECDHE_ECDSA", "ECDHE_RSA" }; 330 } 331 332 /** Possible status of a network configuration. */ 333 public static class Status { Status()334 private Status() { } 335 336 /** this is the network we are currently connected to */ 337 public static final int CURRENT = 0; 338 /** supplicant will not attempt to use this network */ 339 public static final int DISABLED = 1; 340 /** supplicant will consider this network available for association */ 341 public static final int ENABLED = 2; 342 343 public static final String[] strings = { "current", "disabled", "enabled" }; 344 } 345 346 /** 347 * Security types we support. 348 */ 349 /** @hide */ 350 public static final int SECURITY_TYPE_OPEN = 0; 351 /** @hide */ 352 public static final int SECURITY_TYPE_WEP = 1; 353 /** @hide */ 354 public static final int SECURITY_TYPE_PSK = 2; 355 /** @hide */ 356 public static final int SECURITY_TYPE_EAP = 3; 357 /** @hide */ 358 public static final int SECURITY_TYPE_SAE = 4; 359 /** @hide */ 360 public static final int SECURITY_TYPE_EAP_SUITE_B = 5; 361 /** @hide */ 362 public static final int SECURITY_TYPE_OWE = 6; 363 364 /** @hide */ 365 @Retention(RetentionPolicy.SOURCE) 366 @IntDef(prefix = { "SECURITY_TYPE_" }, value = { 367 SECURITY_TYPE_OPEN, 368 SECURITY_TYPE_WEP, 369 SECURITY_TYPE_PSK, 370 SECURITY_TYPE_EAP, 371 SECURITY_TYPE_SAE, 372 SECURITY_TYPE_EAP_SUITE_B, 373 SECURITY_TYPE_OWE 374 }) 375 public @interface SecurityType {} 376 377 /** 378 * @hide 379 * Set security params (sets the various bitsets exposed in WifiConfiguration). 380 * 381 * @param securityType One of the security types from {@link SecurityType}. 382 */ setSecurityParams(@ecurityType int securityType)383 public void setSecurityParams(@SecurityType int securityType) { 384 // Clear all the bitsets. 385 allowedKeyManagement.clear(); 386 allowedProtocols.clear(); 387 allowedAuthAlgorithms.clear(); 388 allowedPairwiseCiphers.clear(); 389 allowedGroupCiphers.clear(); 390 allowedGroupManagementCiphers.clear(); 391 allowedSuiteBCiphers.clear(); 392 393 switch (securityType) { 394 case SECURITY_TYPE_OPEN: 395 allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 396 break; 397 case SECURITY_TYPE_WEP: 398 allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 399 allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); 400 allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED); 401 break; 402 case SECURITY_TYPE_PSK: 403 allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); 404 break; 405 case SECURITY_TYPE_EAP: 406 allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP); 407 allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X); 408 break; 409 case SECURITY_TYPE_SAE: 410 allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE); 411 requirePMF = true; 412 break; 413 case SECURITY_TYPE_EAP_SUITE_B: 414 allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192); 415 allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256); 416 allowedGroupManagementCiphers.set(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256); 417 // Note: allowedSuiteBCiphers bitset will be set by the service once the 418 // certificates are attached to this profile 419 requirePMF = true; 420 break; 421 case SECURITY_TYPE_OWE: 422 allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OWE); 423 requirePMF = true; 424 break; 425 default: 426 throw new IllegalArgumentException("unknown security type " + securityType); 427 } 428 } 429 430 /** @hide */ 431 public static final int UNKNOWN_UID = -1; 432 433 /** 434 * The ID number that the supplicant uses to identify this 435 * network configuration entry. This must be passed as an argument 436 * to most calls into the supplicant. 437 */ 438 public int networkId; 439 440 // Fixme We need remove this field to use only Quality network selection status only 441 /** 442 * The current status of this network configuration entry. 443 * @see Status 444 */ 445 public int status; 446 447 /** 448 * The network's SSID. Can either be a UTF-8 string, 449 * which must be enclosed in double quotation marks 450 * (e.g., {@code "MyNetwork"}), or a string of 451 * hex digits, which are not enclosed in quotes 452 * (e.g., {@code 01a243f405}). 453 */ 454 public String SSID; 455 456 /** 457 * When set, this network configuration entry should only be used when 458 * associating with the AP having the specified BSSID. The value is 459 * a string in the format of an Ethernet MAC address, e.g., 460 * <code>XX:XX:XX:XX:XX:XX</code> where each <code>X</code> is a hex digit. 461 */ 462 public String BSSID; 463 464 /** 465 * 2GHz band. 466 * @hide 467 */ 468 public static final int AP_BAND_2GHZ = 0; 469 470 /** 471 * 5GHz band. 472 * @hide 473 */ 474 public static final int AP_BAND_5GHZ = 1; 475 476 /** 477 * Device is allowed to choose the optimal band (2Ghz or 5Ghz) based on device capability, 478 * operating country code and current radio conditions. 479 * @hide 480 */ 481 public static final int AP_BAND_ANY = -1; 482 483 /** 484 * The band which AP resides on 485 * -1:Any 0:2G 1:5G 486 * By default, 2G is chosen 487 * @hide 488 */ 489 @UnsupportedAppUsage 490 public int apBand = AP_BAND_2GHZ; 491 492 /** 493 * The channel which AP resides on,currently, US only 494 * 2G 1-11 495 * 5G 36,40,44,48,149,153,157,161,165 496 * 0 - find a random available channel according to the apBand 497 * @hide 498 */ 499 @UnsupportedAppUsage 500 public int apChannel = 0; 501 502 /** 503 * Pre-shared key for use with WPA-PSK. Either an ASCII string enclosed in 504 * double quotation marks (e.g., {@code "abcdefghij"} for PSK passphrase or 505 * a string of 64 hex digits for raw PSK. 506 * <p/> 507 * When the value of this key is read, the actual key is 508 * not returned, just a "*" if the key has a value, or the null 509 * string otherwise. 510 */ 511 public String preSharedKey; 512 513 /** 514 * Four WEP keys. For each of the four values, provide either an ASCII 515 * string enclosed in double quotation marks (e.g., {@code "abcdef"}), 516 * a string of hex digits (e.g., {@code 0102030405}), or an empty string 517 * (e.g., {@code ""}). 518 * <p/> 519 * When the value of one of these keys is read, the actual key is 520 * not returned, just a "*" if the key has a value, or the null 521 * string otherwise. 522 * @deprecated Due to security and performance limitations, use of WEP networks 523 * is discouraged. 524 */ 525 @Deprecated 526 public String[] wepKeys; 527 528 /** Default WEP key index, ranging from 0 to 3. 529 * @deprecated Due to security and performance limitations, use of WEP networks 530 * is discouraged. */ 531 @Deprecated 532 public int wepTxKeyIndex; 533 534 /** 535 * Priority determines the preference given to a network by {@code wpa_supplicant} 536 * when choosing an access point with which to associate. 537 * @deprecated This field does not exist anymore. 538 */ 539 @Deprecated 540 public int priority; 541 542 /** 543 * This is a network that does not broadcast its SSID, so an 544 * SSID-specific probe request must be used for scans. 545 */ 546 public boolean hiddenSSID; 547 548 /** 549 * This is a network that requries Protected Management Frames (PMF). 550 * @hide 551 */ 552 public boolean requirePMF; 553 554 /** 555 * Update identifier, for Passpoint network. 556 * @hide 557 */ 558 public String updateIdentifier; 559 560 /** 561 * The set of key management protocols supported by this configuration. 562 * See {@link KeyMgmt} for descriptions of the values. 563 * Defaults to WPA-PSK WPA-EAP. 564 */ 565 @NonNull 566 public BitSet allowedKeyManagement; 567 /** 568 * The set of security protocols supported by this configuration. 569 * See {@link Protocol} for descriptions of the values. 570 * Defaults to WPA RSN. 571 */ 572 @NonNull 573 public BitSet allowedProtocols; 574 /** 575 * The set of authentication protocols supported by this configuration. 576 * See {@link AuthAlgorithm} for descriptions of the values. 577 * Defaults to automatic selection. 578 */ 579 @NonNull 580 public BitSet allowedAuthAlgorithms; 581 /** 582 * The set of pairwise ciphers for WPA supported by this configuration. 583 * See {@link PairwiseCipher} for descriptions of the values. 584 * Defaults to CCMP TKIP. 585 */ 586 @NonNull 587 public BitSet allowedPairwiseCiphers; 588 /** 589 * The set of group ciphers supported by this configuration. 590 * See {@link GroupCipher} for descriptions of the values. 591 * Defaults to CCMP TKIP WEP104 WEP40. 592 */ 593 @NonNull 594 public BitSet allowedGroupCiphers; 595 /** 596 * The set of group management ciphers supported by this configuration. 597 * See {@link GroupMgmtCipher} for descriptions of the values. 598 */ 599 @NonNull 600 public BitSet allowedGroupManagementCiphers; 601 /** 602 * The set of SuiteB ciphers supported by this configuration. 603 * To be used for WPA3-Enterprise mode. 604 * See {@link SuiteBCipher} for descriptions of the values. 605 */ 606 @NonNull 607 public BitSet allowedSuiteBCiphers; 608 /** 609 * The enterprise configuration details specifying the EAP method, 610 * certificates and other settings associated with the EAP. 611 */ 612 public WifiEnterpriseConfig enterpriseConfig; 613 614 /** 615 * Fully qualified domain name of a Passpoint configuration 616 */ 617 public String FQDN; 618 619 /** 620 * Name of Passpoint credential provider 621 */ 622 public String providerFriendlyName; 623 624 /** 625 * Flag indicating if this network is provided by a home Passpoint provider or a roaming 626 * Passpoint provider. This flag will be {@code true} if this network is provided by 627 * a home Passpoint provider and {@code false} if is provided by a roaming Passpoint provider 628 * or is a non-Passpoint network. 629 */ 630 public boolean isHomeProviderNetwork; 631 632 /** 633 * Roaming Consortium Id list for Passpoint credential; identifies a set of networks where 634 * Passpoint credential will be considered valid 635 */ 636 public long[] roamingConsortiumIds; 637 638 /** 639 * @hide 640 * This network configuration is visible to and usable by other users on the 641 * same device. 642 */ 643 @UnsupportedAppUsage 644 public boolean shared; 645 646 /** 647 * @hide 648 */ 649 @NonNull 650 @UnsupportedAppUsage 651 private IpConfiguration mIpConfiguration; 652 653 /** 654 * @hide 655 * dhcp server MAC address if known 656 */ 657 public String dhcpServer; 658 659 /** 660 * @hide 661 * default Gateway MAC address if known 662 */ 663 @UnsupportedAppUsage 664 public String defaultGwMacAddress; 665 666 /** 667 * @hide 668 * last time we connected, this configuration had validated internet access 669 */ 670 @UnsupportedAppUsage 671 public boolean validatedInternetAccess; 672 673 /** 674 * @hide 675 * The number of beacon intervals between Delivery Traffic Indication Maps (DTIM) 676 * This value is populated from scan results that contain Beacon Frames, which are infrequent. 677 * The value is not guaranteed to be set or current (Although it SHOULDNT change once set) 678 * Valid values are from 1 - 255. Initialized here as 0, use this to check if set. 679 */ 680 public int dtimInterval = 0; 681 682 /** 683 * Flag indicating if this configuration represents a legacy Passpoint configuration 684 * (Release N or older). This is used for migrating Passpoint configuration from N to O. 685 * This will no longer be needed after O. 686 * @hide 687 */ 688 public boolean isLegacyPasspointConfig = false; 689 /** 690 * @hide 691 * Uid of app creating the configuration 692 */ 693 @SystemApi 694 public int creatorUid; 695 696 /** 697 * @hide 698 * Uid of last app issuing a connection related command 699 */ 700 @UnsupportedAppUsage 701 public int lastConnectUid; 702 703 /** 704 * @hide 705 * Uid of last app modifying the configuration 706 */ 707 @SystemApi 708 public int lastUpdateUid; 709 710 /** 711 * @hide 712 * Universal name for app creating the configuration 713 * see {@link PackageManager#getNameForUid(int)} 714 */ 715 @SystemApi 716 public String creatorName; 717 718 /** 719 * @hide 720 * Universal name for app updating the configuration 721 * see {@link PackageManager#getNameForUid(int)} 722 */ 723 @SystemApi 724 public String lastUpdateName; 725 726 /** 727 * @hide 728 * Status of user approval for connection 729 */ 730 public int userApproved = USER_UNSPECIFIED; 731 732 /** The Below RSSI thresholds are used to configure AutoJoin 733 * - GOOD/LOW/BAD thresholds are used so as to calculate link score 734 * - UNWANTED_SOFT are used by the blacklisting logic so as to handle 735 * the unwanted network message coming from CS 736 * - UNBLACKLIST thresholds are used so as to tweak the speed at which 737 * the network is unblacklisted (i.e. if 738 * it is seen with good RSSI, it is blacklisted faster) 739 * - INITIAL_AUTOJOIN_ATTEMPT, used to determine how close from 740 * the network we need to be before autojoin kicks in 741 */ 742 /** @hide **/ 743 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 744 public static int INVALID_RSSI = -127; 745 746 // States for the userApproved field 747 /** 748 * @hide 749 * User hasn't specified if connection is okay 750 */ 751 public static final int USER_UNSPECIFIED = 0; 752 /** 753 * @hide 754 * User has approved this for connection 755 */ 756 public static final int USER_APPROVED = 1; 757 /** 758 * @hide 759 * User has banned this from connection 760 */ 761 public static final int USER_BANNED = 2; 762 /** 763 * @hide 764 * Waiting for user input 765 */ 766 public static final int USER_PENDING = 3; 767 768 /** 769 * @hide 770 * Number of reports indicating no Internet Access 771 */ 772 @UnsupportedAppUsage 773 public int numNoInternetAccessReports; 774 775 /** 776 * @hide 777 * For debug: date at which the config was last updated 778 */ 779 public String updateTime; 780 781 /** 782 * @hide 783 * For debug: date at which the config was last updated 784 */ 785 public String creationTime; 786 787 /** 788 * @hide 789 * The WiFi configuration is considered to have no internet access for purpose of autojoining 790 * if there has been a report of it having no internet access, and, it never have had 791 * internet access in the past. 792 */ 793 @SystemApi hasNoInternetAccess()794 public boolean hasNoInternetAccess() { 795 return numNoInternetAccessReports > 0 && !validatedInternetAccess; 796 } 797 798 /** 799 * The WiFi configuration is expected not to have Internet access (e.g., a wireless printer, a 800 * Chromecast hotspot, etc.). This will be set if the user explicitly confirms a connection to 801 * this configuration and selects "don't ask again". 802 * @hide 803 */ 804 @UnsupportedAppUsage 805 public boolean noInternetAccessExpected; 806 807 /** 808 * The WiFi configuration is expected not to have Internet access (e.g., a wireless printer, a 809 * Chromecast hotspot, etc.). This will be set if the user explicitly confirms a connection to 810 * this configuration and selects "don't ask again". 811 * @hide 812 */ 813 @SystemApi isNoInternetAccessExpected()814 public boolean isNoInternetAccessExpected() { 815 return noInternetAccessExpected; 816 } 817 818 /** 819 * This Wifi configuration is expected for OSU(Online Sign Up) of Passpoint Release 2. 820 * @hide 821 */ 822 public boolean osu; 823 824 /** 825 * @hide 826 * Last time the system was connected to this configuration. 827 */ 828 public long lastConnected; 829 830 /** 831 * @hide 832 * Last time the system was disconnected to this configuration. 833 */ 834 public long lastDisconnected; 835 836 /** 837 * Set if the configuration was self added by the framework 838 * This boolean is cleared if we get a connect/save/ update or 839 * any wifiManager command that indicate the user interacted with the configuration 840 * since we will now consider that the configuration belong to him. 841 * @hide 842 */ 843 @UnsupportedAppUsage 844 public boolean selfAdded; 845 846 /** 847 * Set if the configuration was self added by the framework 848 * This boolean is set once and never cleared. It is used 849 * so as we never loose track of who created the 850 * configuration in the first place. 851 * @hide 852 */ 853 public boolean didSelfAdd; 854 855 /** 856 * Peer WifiConfiguration this WifiConfiguration was added for 857 * @hide 858 */ 859 public String peerWifiConfiguration; 860 861 /** 862 * @hide 863 * Indicate that a WifiConfiguration is temporary and should not be saved 864 * nor considered by AutoJoin. 865 */ 866 public boolean ephemeral; 867 868 /** 869 * @hide 870 * Indicate that a WifiConfiguration is temporary and should not be saved 871 * nor considered by AutoJoin. 872 */ 873 @SystemApi isEphemeral()874 public boolean isEphemeral() { 875 return ephemeral; 876 } 877 878 /** 879 * Indicate whther the network is trusted or not. Networks are considered trusted 880 * if the user explicitly allowed this network connection. 881 * @hide 882 */ 883 public boolean trusted; 884 885 /** 886 * This Wifi configuration is created from a {@link WifiNetworkSuggestion} 887 * @hide 888 */ 889 public boolean fromWifiNetworkSuggestion; 890 891 /** 892 * This Wifi configuration is created from a {@link WifiNetworkSpecifier} 893 * @hide 894 */ 895 public boolean fromWifiNetworkSpecifier; 896 897 /** 898 * Indicates if the creator of this configuration has expressed that it 899 * should be considered metered. 900 * 901 * @see #isMetered(WifiConfiguration, WifiInfo) 902 * @hide 903 */ 904 @SystemApi 905 public boolean meteredHint; 906 907 /** {@hide} */ 908 public static final int METERED_OVERRIDE_NONE = 0; 909 /** {@hide} */ 910 public static final int METERED_OVERRIDE_METERED = 1; 911 /** {@hide} */ 912 public static final int METERED_OVERRIDE_NOT_METERED = 2; 913 914 /** 915 * Indicates if the end user has expressed an explicit opinion about the 916 * meteredness of this network, such as through the Settings app. 917 * <p> 918 * This should always override any values from {@link #meteredHint} or 919 * {@link WifiInfo#getMeteredHint()}. 920 * 921 * @see #isMetered(WifiConfiguration, WifiInfo) 922 * @hide 923 */ 924 public int meteredOverride = METERED_OVERRIDE_NONE; 925 926 /** 927 * Blend together all the various opinions to decide if the given network 928 * should be considered metered or not. 929 * 930 * @hide 931 */ isMetered(WifiConfiguration config, WifiInfo info)932 public static boolean isMetered(WifiConfiguration config, WifiInfo info) { 933 boolean metered = false; 934 if (info != null && info.getMeteredHint()) { 935 metered = true; 936 } 937 if (config != null && config.meteredHint) { 938 metered = true; 939 } 940 if (config != null 941 && config.meteredOverride == WifiConfiguration.METERED_OVERRIDE_METERED) { 942 metered = true; 943 } 944 if (config != null 945 && config.meteredOverride == WifiConfiguration.METERED_OVERRIDE_NOT_METERED) { 946 metered = false; 947 } 948 return metered; 949 } 950 951 /** 952 * @hide 953 * Returns true if this WiFi config is for an open network. 954 */ isOpenNetwork()955 public boolean isOpenNetwork() { 956 final int cardinality = allowedKeyManagement.cardinality(); 957 final boolean hasNoKeyMgmt = cardinality == 0 958 || (cardinality == 1 && (allowedKeyManagement.get(KeyMgmt.NONE) 959 || allowedKeyManagement.get(KeyMgmt.OWE))); 960 961 boolean hasNoWepKeys = true; 962 if (wepKeys != null) { 963 for (int i = 0; i < wepKeys.length; i++) { 964 if (wepKeys[i] != null) { 965 hasNoWepKeys = false; 966 break; 967 } 968 } 969 } 970 971 return hasNoKeyMgmt && hasNoWepKeys; 972 } 973 974 /** 975 * @hide 976 * Setting this value will force scan results associated with this configuration to 977 * be included in the bucket of networks that are externally scored. 978 * If not set, associated scan results will be treated as legacy saved networks and 979 * will take precedence over networks in the scored category. 980 */ 981 @SystemApi 982 public boolean useExternalScores; 983 984 /** 985 * @hide 986 * Number of time the scorer overrode a the priority based choice, when comparing two 987 * WifiConfigurations, note that since comparing WifiConfiguration happens very often 988 * potentially at every scan, this number might become very large, even on an idle 989 * system. 990 */ 991 @SystemApi 992 public int numScorerOverride; 993 994 /** 995 * @hide 996 * Number of time the scorer overrode a the priority based choice, and the comparison 997 * triggered a network switch 998 */ 999 @SystemApi 1000 public int numScorerOverrideAndSwitchedNetwork; 1001 1002 /** 1003 * @hide 1004 * Number of time we associated to this configuration. 1005 */ 1006 @SystemApi 1007 public int numAssociation; 1008 1009 /** 1010 * @hide 1011 * Use factory MAC when connecting to this network 1012 */ 1013 public static final int RANDOMIZATION_NONE = 0; 1014 /** 1015 * @hide 1016 * Generate a randomized MAC once and reuse it for all connections to this network 1017 */ 1018 public static final int RANDOMIZATION_PERSISTENT = 1; 1019 1020 /** 1021 * @hide 1022 * Level of MAC randomization for this network 1023 */ 1024 public int macRandomizationSetting = RANDOMIZATION_PERSISTENT; 1025 1026 /** 1027 * @hide 1028 * Randomized MAC address to use with this particular network 1029 */ 1030 @NonNull 1031 private MacAddress mRandomizedMacAddress; 1032 1033 /** 1034 * @hide 1035 * Checks if the given MAC address can be used for Connected Mac Randomization 1036 * by verifying that it is non-null, unicast, locally assigned, and not default mac. 1037 * @param mac MacAddress to check 1038 * @return true if mac is good to use 1039 */ isValidMacAddressForRandomization(MacAddress mac)1040 public static boolean isValidMacAddressForRandomization(MacAddress mac) { 1041 return mac != null && !MacAddressUtils.isMulticastAddress(mac) && mac.isLocallyAssigned() 1042 && !MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS).equals(mac); 1043 } 1044 1045 /** 1046 * @hide 1047 * Returns Randomized MAC address to use with the network. 1048 * If it is not set/valid, creates a new randomized address. 1049 * If it can't generate a valid mac, returns the default MAC. 1050 */ getOrCreateRandomizedMacAddress()1051 public @NonNull MacAddress getOrCreateRandomizedMacAddress() { 1052 int randomMacGenerationCount = 0; 1053 while (!isValidMacAddressForRandomization(mRandomizedMacAddress) 1054 && randomMacGenerationCount < MAXIMUM_RANDOM_MAC_GENERATION_RETRY) { 1055 mRandomizedMacAddress = MacAddressUtils.createRandomUnicastAddress(); 1056 randomMacGenerationCount++; 1057 } 1058 1059 if (!isValidMacAddressForRandomization(mRandomizedMacAddress)) { 1060 mRandomizedMacAddress = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS); 1061 } 1062 return mRandomizedMacAddress; 1063 } 1064 1065 /** 1066 * Returns MAC address set to be the local randomized MAC address. 1067 * Depending on user preference, the device may or may not use the returned MAC address for 1068 * connections to this network. 1069 * <p> 1070 * Information is restricted to Device Owner, Profile Owner, and Carrier apps 1071 * (which will only obtain addresses for configurations which they create). Other callers 1072 * will receive a default "02:00:00:00:00:00" MAC address. 1073 */ getRandomizedMacAddress()1074 public @NonNull MacAddress getRandomizedMacAddress() { 1075 return mRandomizedMacAddress; 1076 } 1077 1078 /** 1079 * @hide 1080 * @param mac MacAddress to change into 1081 */ setRandomizedMacAddress(@onNull MacAddress mac)1082 public void setRandomizedMacAddress(@NonNull MacAddress mac) { 1083 if (mac == null) { 1084 Log.e(TAG, "setRandomizedMacAddress received null MacAddress."); 1085 return; 1086 } 1087 mRandomizedMacAddress = mac; 1088 } 1089 1090 /** @hide 1091 * Boost given to RSSI on a home network for the purpose of calculating the score 1092 * This adds stickiness to home networks, as defined by: 1093 * - less than 4 known BSSIDs 1094 * - PSK only 1095 * - TODO: add a test to verify that all BSSIDs are behind same gateway 1096 ***/ 1097 public static final int HOME_NETWORK_RSSI_BOOST = 5; 1098 1099 /** 1100 * @hide 1101 * This class is used to contain all the information and API used for quality network selection 1102 */ 1103 public static class NetworkSelectionStatus { 1104 /** 1105 * Quality Network Selection Status enable, temporary disabled, permanently disabled 1106 */ 1107 /** 1108 * This network is allowed to join Quality Network Selection 1109 */ 1110 public static final int NETWORK_SELECTION_ENABLED = 0; 1111 /** 1112 * network was temporary disabled. Can be re-enabled after a time period expire 1113 */ 1114 public static final int NETWORK_SELECTION_TEMPORARY_DISABLED = 1; 1115 /** 1116 * network was permanently disabled. 1117 */ 1118 public static final int NETWORK_SELECTION_PERMANENTLY_DISABLED = 2; 1119 /** 1120 * Maximum Network selection status 1121 */ 1122 public static final int NETWORK_SELECTION_STATUS_MAX = 3; 1123 1124 /** 1125 * Quality network selection status String (for debug purpose). Use Quality network 1126 * selection status value as index to extec the corresponding debug string 1127 */ 1128 public static final String[] QUALITY_NETWORK_SELECTION_STATUS = { 1129 "NETWORK_SELECTION_ENABLED", 1130 "NETWORK_SELECTION_TEMPORARY_DISABLED", 1131 "NETWORK_SELECTION_PERMANENTLY_DISABLED"}; 1132 1133 //Quality Network disabled reasons 1134 /** 1135 * Default value. Means not disabled 1136 */ 1137 public static final int NETWORK_SELECTION_ENABLE = 0; 1138 /** 1139 * The starting index for network selection disabled reasons 1140 */ 1141 public static final int NETWORK_SELECTION_DISABLED_STARTING_INDEX = 1; 1142 /** 1143 * @deprecated it is not used any more. 1144 * This network is disabled because higher layer (>2) network is bad 1145 */ 1146 public static final int DISABLED_BAD_LINK = 1; 1147 /** 1148 * This network is disabled because multiple association rejects 1149 */ 1150 public static final int DISABLED_ASSOCIATION_REJECTION = 2; 1151 /** 1152 * This network is disabled because multiple authentication failure 1153 */ 1154 public static final int DISABLED_AUTHENTICATION_FAILURE = 3; 1155 /** 1156 * This network is disabled because multiple DHCP failure 1157 */ 1158 public static final int DISABLED_DHCP_FAILURE = 4; 1159 /** 1160 * This network is disabled because of security network but no credentials 1161 */ 1162 public static final int DISABLED_DNS_FAILURE = 5; 1163 /** 1164 * This network is temporarily disabled because it has no Internet access. 1165 */ 1166 public static final int DISABLED_NO_INTERNET_TEMPORARY = 6; 1167 /** 1168 * This network is disabled because we started WPS 1169 */ 1170 public static final int DISABLED_WPS_START = 7; 1171 /** 1172 * This network is disabled because EAP-TLS failure 1173 */ 1174 public static final int DISABLED_TLS_VERSION_MISMATCH = 8; 1175 // Values above are for temporary disablement; values below are for permanent disablement. 1176 /** 1177 * This network is disabled due to absence of user credentials 1178 */ 1179 public static final int DISABLED_AUTHENTICATION_NO_CREDENTIALS = 9; 1180 /** 1181 * This network is permanently disabled because it has no Internet access and user does not 1182 * want to stay connected. 1183 */ 1184 public static final int DISABLED_NO_INTERNET_PERMANENT = 10; 1185 /** 1186 * This network is disabled due to WifiManager disable it explicitly 1187 */ 1188 public static final int DISABLED_BY_WIFI_MANAGER = 11; 1189 /** 1190 * This network is disabled due to user switching 1191 */ 1192 public static final int DISABLED_DUE_TO_USER_SWITCH = 12; 1193 /** 1194 * This network is disabled due to wrong password 1195 */ 1196 public static final int DISABLED_BY_WRONG_PASSWORD = 13; 1197 /** 1198 * This network is disabled because service is not subscribed 1199 */ 1200 public static final int DISABLED_AUTHENTICATION_NO_SUBSCRIPTION = 14; 1201 /** 1202 * This Maximum disable reason value 1203 */ 1204 public static final int NETWORK_SELECTION_DISABLED_MAX = 15; 1205 1206 /** 1207 * Quality network selection disable reason String (for debug purpose) 1208 */ 1209 public static final String[] QUALITY_NETWORK_SELECTION_DISABLE_REASON = { 1210 "NETWORK_SELECTION_ENABLE", 1211 "NETWORK_SELECTION_DISABLED_BAD_LINK", // deprecated 1212 "NETWORK_SELECTION_DISABLED_ASSOCIATION_REJECTION ", 1213 "NETWORK_SELECTION_DISABLED_AUTHENTICATION_FAILURE", 1214 "NETWORK_SELECTION_DISABLED_DHCP_FAILURE", 1215 "NETWORK_SELECTION_DISABLED_DNS_FAILURE", 1216 "NETWORK_SELECTION_DISABLED_NO_INTERNET_TEMPORARY", 1217 "NETWORK_SELECTION_DISABLED_WPS_START", 1218 "NETWORK_SELECTION_DISABLED_TLS_VERSION", 1219 "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_CREDENTIALS", 1220 "NETWORK_SELECTION_DISABLED_NO_INTERNET_PERMANENT", 1221 "NETWORK_SELECTION_DISABLED_BY_WIFI_MANAGER", 1222 "NETWORK_SELECTION_DISABLED_BY_USER_SWITCH", 1223 "NETWORK_SELECTION_DISABLED_BY_WRONG_PASSWORD", 1224 "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_SUBSCRIPTION" 1225 }; 1226 1227 /** 1228 * Invalid time stamp for network selection disable 1229 */ 1230 public static final long INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP = -1L; 1231 1232 /** 1233 * This constant indicates the current configuration has connect choice set 1234 */ 1235 private static final int CONNECT_CHOICE_EXISTS = 1; 1236 1237 /** 1238 * This constant indicates the current configuration does not have connect choice set 1239 */ 1240 private static final int CONNECT_CHOICE_NOT_EXISTS = -1; 1241 1242 // fields for QualityNetwork Selection 1243 /** 1244 * Network selection status, should be in one of three status: enable, temporaily disabled 1245 * or permanently disabled 1246 */ 1247 private int mStatus; 1248 1249 /** 1250 * Reason for disable this network 1251 */ 1252 private int mNetworkSelectionDisableReason; 1253 1254 /** 1255 * Last time we temporarily disabled the configuration 1256 */ 1257 private long mTemporarilyDisabledTimestamp = INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP; 1258 1259 /** 1260 * counter for each Network selection disable reason 1261 */ 1262 private int[] mNetworkSeclectionDisableCounter = new int[NETWORK_SELECTION_DISABLED_MAX]; 1263 1264 /** 1265 * Connect Choice over this configuration 1266 * 1267 * When current wifi configuration is visible to the user but user explicitly choose to 1268 * connect to another network X, the another networks X's configure key will be stored here. 1269 * We will consider user has a preference of X over this network. And in the future, 1270 * network selection will always give X a higher preference over this configuration. 1271 * configKey is : "SSID"-WEP-WPA_PSK-WPA_EAP 1272 */ 1273 private String mConnectChoice; 1274 1275 /** 1276 * The system timestamp when we records the connectChoice. This value is obtained from 1277 * System.currentTimeMillis 1278 */ 1279 private long mConnectChoiceTimestamp = INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP; 1280 1281 /** 1282 * Used to cache the temporary candidate during the network selection procedure. It will be 1283 * kept updating once a new scan result has a higher score than current one 1284 */ 1285 private ScanResult mCandidate; 1286 1287 /** 1288 * Used to cache the score of the current temporary candidate during the network 1289 * selection procedure. 1290 */ 1291 private int mCandidateScore; 1292 1293 /** 1294 * Indicate whether this network is visible in latest Qualified Network Selection. This 1295 * means there is scan result found related to this Configuration and meet the minimum 1296 * requirement. The saved network need not join latest Qualified Network Selection. For 1297 * example, it is disabled. True means network is visible in latest Qualified Network 1298 * Selection and false means network is invisible 1299 */ 1300 private boolean mSeenInLastQualifiedNetworkSelection; 1301 1302 /** 1303 * Boolean indicating if we have ever successfully connected to this network. 1304 * 1305 * This value will be set to true upon a successful connection. 1306 * This value will be set to false if a previous value was not stored in the config or if 1307 * the credentials are updated (ex. a password change). 1308 */ 1309 private boolean mHasEverConnected; 1310 1311 /** 1312 * Boolean indicating whether {@link com.android.server.wifi.RecommendedNetworkEvaluator} 1313 * chose not to connect to this network in the last qualified network selection process. 1314 */ 1315 private boolean mNotRecommended; 1316 1317 /** 1318 * Set whether {@link com.android.server.wifi.RecommendedNetworkEvaluator} does not 1319 * recommend connecting to this network. 1320 */ setNotRecommended(boolean notRecommended)1321 public void setNotRecommended(boolean notRecommended) { 1322 mNotRecommended = notRecommended; 1323 } 1324 1325 /** 1326 * Returns whether {@link com.android.server.wifi.RecommendedNetworkEvaluator} does not 1327 * recommend connecting to this network. 1328 */ isNotRecommended()1329 public boolean isNotRecommended() { 1330 return mNotRecommended; 1331 } 1332 1333 /** 1334 * set whether this network is visible in latest Qualified Network Selection 1335 * @param seen value set to candidate 1336 */ setSeenInLastQualifiedNetworkSelection(boolean seen)1337 public void setSeenInLastQualifiedNetworkSelection(boolean seen) { 1338 mSeenInLastQualifiedNetworkSelection = seen; 1339 } 1340 1341 /** 1342 * get whether this network is visible in latest Qualified Network Selection 1343 * @return returns true -- network is visible in latest Qualified Network Selection 1344 * false -- network is invisible in latest Qualified Network Selection 1345 */ getSeenInLastQualifiedNetworkSelection()1346 public boolean getSeenInLastQualifiedNetworkSelection() { 1347 return mSeenInLastQualifiedNetworkSelection; 1348 } 1349 /** 1350 * set the temporary candidate of current network selection procedure 1351 * @param scanCandidate {@link ScanResult} the candidate set to mCandidate 1352 */ setCandidate(ScanResult scanCandidate)1353 public void setCandidate(ScanResult scanCandidate) { 1354 mCandidate = scanCandidate; 1355 } 1356 1357 /** 1358 * get the temporary candidate of current network selection procedure 1359 * @return returns {@link ScanResult} temporary candidate of current network selection 1360 * procedure 1361 */ getCandidate()1362 public ScanResult getCandidate() { 1363 return mCandidate; 1364 } 1365 1366 /** 1367 * set the score of the temporary candidate of current network selection procedure 1368 * @param score value set to mCandidateScore 1369 */ setCandidateScore(int score)1370 public void setCandidateScore(int score) { 1371 mCandidateScore = score; 1372 } 1373 1374 /** 1375 * get the score of the temporary candidate of current network selection procedure 1376 * @return returns score of the temporary candidate of current network selection procedure 1377 */ getCandidateScore()1378 public int getCandidateScore() { 1379 return mCandidateScore; 1380 } 1381 1382 /** 1383 * get user preferred choice over this configuration 1384 *@return returns configKey of user preferred choice over this configuration 1385 */ getConnectChoice()1386 public String getConnectChoice() { 1387 return mConnectChoice; 1388 } 1389 1390 /** 1391 * set user preferred choice over this configuration 1392 * @param newConnectChoice, the configKey of user preferred choice over this configuration 1393 */ setConnectChoice(String newConnectChoice)1394 public void setConnectChoice(String newConnectChoice) { 1395 mConnectChoice = newConnectChoice; 1396 } 1397 1398 /** 1399 * get the timeStamp when user select a choice over this configuration 1400 * @return returns when current connectChoice is set (time from System.currentTimeMillis) 1401 */ getConnectChoiceTimestamp()1402 public long getConnectChoiceTimestamp() { 1403 return mConnectChoiceTimestamp; 1404 } 1405 1406 /** 1407 * set the timeStamp when user select a choice over this configuration 1408 * @param timeStamp, the timestamp set to connectChoiceTimestamp, expected timestamp should 1409 * be obtained from System.currentTimeMillis 1410 */ setConnectChoiceTimestamp(long timeStamp)1411 public void setConnectChoiceTimestamp(long timeStamp) { 1412 mConnectChoiceTimestamp = timeStamp; 1413 } 1414 1415 /** 1416 * get current Quality network selection status 1417 * @return returns current Quality network selection status in String (for debug purpose) 1418 */ getNetworkStatusString()1419 public String getNetworkStatusString() { 1420 return QUALITY_NETWORK_SELECTION_STATUS[mStatus]; 1421 } 1422 setHasEverConnected(boolean value)1423 public void setHasEverConnected(boolean value) { 1424 mHasEverConnected = value; 1425 } 1426 getHasEverConnected()1427 public boolean getHasEverConnected() { 1428 return mHasEverConnected; 1429 } 1430 NetworkSelectionStatus()1431 public NetworkSelectionStatus() { 1432 // previously stored configs will not have this parameter, so we default to false. 1433 mHasEverConnected = false; 1434 }; 1435 1436 /** 1437 * @param reason specific error reason 1438 * @return corresponding network disable reason String (for debug purpose) 1439 */ getNetworkDisableReasonString(int reason)1440 public static String getNetworkDisableReasonString(int reason) { 1441 if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) { 1442 return QUALITY_NETWORK_SELECTION_DISABLE_REASON[reason]; 1443 } else { 1444 return null; 1445 } 1446 } 1447 /** 1448 * get current network disable reason 1449 * @return current network disable reason in String (for debug purpose) 1450 */ getNetworkDisableReasonString()1451 public String getNetworkDisableReasonString() { 1452 return QUALITY_NETWORK_SELECTION_DISABLE_REASON[mNetworkSelectionDisableReason]; 1453 } 1454 1455 /** 1456 * get current network network selection status 1457 * @return return current network network selection status 1458 */ getNetworkSelectionStatus()1459 public int getNetworkSelectionStatus() { 1460 return mStatus; 1461 } 1462 /** 1463 * @return whether current network is enabled to join network selection 1464 */ isNetworkEnabled()1465 public boolean isNetworkEnabled() { 1466 return mStatus == NETWORK_SELECTION_ENABLED; 1467 } 1468 1469 /** 1470 * @return whether current network is temporary disabled 1471 */ isNetworkTemporaryDisabled()1472 public boolean isNetworkTemporaryDisabled() { 1473 return mStatus == NETWORK_SELECTION_TEMPORARY_DISABLED; 1474 } 1475 1476 /** 1477 * @return returns whether current network is permanently disabled 1478 */ isNetworkPermanentlyDisabled()1479 public boolean isNetworkPermanentlyDisabled() { 1480 return mStatus == NETWORK_SELECTION_PERMANENTLY_DISABLED; 1481 } 1482 1483 /** 1484 * set current networ work selection status 1485 * @param status network selection status to set 1486 */ setNetworkSelectionStatus(int status)1487 public void setNetworkSelectionStatus(int status) { 1488 if (status >= 0 && status < NETWORK_SELECTION_STATUS_MAX) { 1489 mStatus = status; 1490 } 1491 } 1492 1493 /** 1494 * @return returns current network's disable reason 1495 */ getNetworkSelectionDisableReason()1496 public int getNetworkSelectionDisableReason() { 1497 return mNetworkSelectionDisableReason; 1498 } 1499 1500 /** 1501 * set Network disable reason 1502 * @param reason Network disable reason 1503 */ setNetworkSelectionDisableReason(int reason)1504 public void setNetworkSelectionDisableReason(int reason) { 1505 if (reason >= 0 && reason < NETWORK_SELECTION_DISABLED_MAX) { 1506 mNetworkSelectionDisableReason = reason; 1507 } else { 1508 throw new IllegalArgumentException("Illegal reason value: " + reason); 1509 } 1510 } 1511 1512 /** 1513 * check whether network is disabled by this reason 1514 * @param reason a specific disable reason 1515 * @return true -- network is disabled for this reason 1516 * false -- network is not disabled for this reason 1517 */ isDisabledByReason(int reason)1518 public boolean isDisabledByReason(int reason) { 1519 return mNetworkSelectionDisableReason == reason; 1520 } 1521 1522 /** 1523 * @param timeStamp Set when current network is disabled in millisecond since January 1, 1524 * 1970 00:00:00.0 UTC 1525 */ setDisableTime(long timeStamp)1526 public void setDisableTime(long timeStamp) { 1527 mTemporarilyDisabledTimestamp = timeStamp; 1528 } 1529 1530 /** 1531 * @return returns when current network is disabled in millisecond since January 1, 1532 * 1970 00:00:00.0 UTC 1533 */ getDisableTime()1534 public long getDisableTime() { 1535 return mTemporarilyDisabledTimestamp; 1536 } 1537 1538 /** 1539 * get the disable counter of a specific reason 1540 * @param reason specific failure reason 1541 * @exception throw IllegalArgumentException for illegal input 1542 * @return counter number for specific error reason. 1543 */ getDisableReasonCounter(int reason)1544 public int getDisableReasonCounter(int reason) { 1545 if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) { 1546 return mNetworkSeclectionDisableCounter[reason]; 1547 } else { 1548 throw new IllegalArgumentException("Illegal reason value: " + reason); 1549 } 1550 } 1551 1552 /** 1553 * set the counter of a specific failure reason 1554 * @param reason reason for disable error 1555 * @param value the counter value for this specific reason 1556 * @exception throw IllegalArgumentException for illegal input 1557 */ setDisableReasonCounter(int reason, int value)1558 public void setDisableReasonCounter(int reason, int value) { 1559 if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) { 1560 mNetworkSeclectionDisableCounter[reason] = value; 1561 } else { 1562 throw new IllegalArgumentException("Illegal reason value: " + reason); 1563 } 1564 } 1565 1566 /** 1567 * increment the counter of a specific failure reason 1568 * @param reason a specific failure reason 1569 * @exception throw IllegalArgumentException for illegal input 1570 */ incrementDisableReasonCounter(int reason)1571 public void incrementDisableReasonCounter(int reason) { 1572 if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) { 1573 mNetworkSeclectionDisableCounter[reason]++; 1574 } else { 1575 throw new IllegalArgumentException("Illegal reason value: " + reason); 1576 } 1577 } 1578 1579 /** 1580 * clear the counter of a specific failure reason 1581 * @hide 1582 * @param reason a specific failure reason 1583 * @exception throw IllegalArgumentException for illegal input 1584 */ clearDisableReasonCounter(int reason)1585 public void clearDisableReasonCounter(int reason) { 1586 if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) { 1587 mNetworkSeclectionDisableCounter[reason] = NETWORK_SELECTION_ENABLE; 1588 } else { 1589 throw new IllegalArgumentException("Illegal reason value: " + reason); 1590 } 1591 } 1592 1593 /** 1594 * clear all the failure reason counters 1595 */ clearDisableReasonCounter()1596 public void clearDisableReasonCounter() { 1597 Arrays.fill(mNetworkSeclectionDisableCounter, NETWORK_SELECTION_ENABLE); 1598 } 1599 1600 /** 1601 * BSSID for connection to this network (through network selection procedure) 1602 */ 1603 private String mNetworkSelectionBSSID; 1604 1605 /** 1606 * get current network Selection BSSID 1607 * @return current network Selection BSSID 1608 */ getNetworkSelectionBSSID()1609 public String getNetworkSelectionBSSID() { 1610 return mNetworkSelectionBSSID; 1611 } 1612 1613 /** 1614 * set network Selection BSSID 1615 * @param bssid The target BSSID for assocaition 1616 */ setNetworkSelectionBSSID(String bssid)1617 public void setNetworkSelectionBSSID(String bssid) { 1618 mNetworkSelectionBSSID = bssid; 1619 } 1620 copy(NetworkSelectionStatus source)1621 public void copy(NetworkSelectionStatus source) { 1622 mStatus = source.mStatus; 1623 mNetworkSelectionDisableReason = source.mNetworkSelectionDisableReason; 1624 for (int index = NETWORK_SELECTION_ENABLE; index < NETWORK_SELECTION_DISABLED_MAX; 1625 index++) { 1626 mNetworkSeclectionDisableCounter[index] = 1627 source.mNetworkSeclectionDisableCounter[index]; 1628 } 1629 mTemporarilyDisabledTimestamp = source.mTemporarilyDisabledTimestamp; 1630 mNetworkSelectionBSSID = source.mNetworkSelectionBSSID; 1631 setSeenInLastQualifiedNetworkSelection(source.getSeenInLastQualifiedNetworkSelection()); 1632 setCandidate(source.getCandidate()); 1633 setCandidateScore(source.getCandidateScore()); 1634 setConnectChoice(source.getConnectChoice()); 1635 setConnectChoiceTimestamp(source.getConnectChoiceTimestamp()); 1636 setHasEverConnected(source.getHasEverConnected()); 1637 setNotRecommended(source.isNotRecommended()); 1638 } 1639 writeToParcel(Parcel dest)1640 public void writeToParcel(Parcel dest) { 1641 dest.writeInt(getNetworkSelectionStatus()); 1642 dest.writeInt(getNetworkSelectionDisableReason()); 1643 for (int index = NETWORK_SELECTION_ENABLE; index < NETWORK_SELECTION_DISABLED_MAX; 1644 index++) { 1645 dest.writeInt(getDisableReasonCounter(index)); 1646 } 1647 dest.writeLong(getDisableTime()); 1648 dest.writeString(getNetworkSelectionBSSID()); 1649 if (getConnectChoice() != null) { 1650 dest.writeInt(CONNECT_CHOICE_EXISTS); 1651 dest.writeString(getConnectChoice()); 1652 dest.writeLong(getConnectChoiceTimestamp()); 1653 } else { 1654 dest.writeInt(CONNECT_CHOICE_NOT_EXISTS); 1655 } 1656 dest.writeInt(getHasEverConnected() ? 1 : 0); 1657 dest.writeInt(isNotRecommended() ? 1 : 0); 1658 } 1659 readFromParcel(Parcel in)1660 public void readFromParcel(Parcel in) { 1661 setNetworkSelectionStatus(in.readInt()); 1662 setNetworkSelectionDisableReason(in.readInt()); 1663 for (int index = NETWORK_SELECTION_ENABLE; index < NETWORK_SELECTION_DISABLED_MAX; 1664 index++) { 1665 setDisableReasonCounter(index, in.readInt()); 1666 } 1667 setDisableTime(in.readLong()); 1668 setNetworkSelectionBSSID(in.readString()); 1669 if (in.readInt() == CONNECT_CHOICE_EXISTS) { 1670 setConnectChoice(in.readString()); 1671 setConnectChoiceTimestamp(in.readLong()); 1672 } else { 1673 setConnectChoice(null); 1674 setConnectChoiceTimestamp(INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP); 1675 } 1676 setHasEverConnected(in.readInt() != 0); 1677 setNotRecommended(in.readInt() != 0); 1678 } 1679 } 1680 1681 /** 1682 * @hide 1683 * network selection related member 1684 */ 1685 private NetworkSelectionStatus mNetworkSelectionStatus = new NetworkSelectionStatus(); 1686 1687 /** 1688 * @hide 1689 * This class is intended to store extra failure reason information for the most recent 1690 * connection attempt, so that it may be surfaced to the settings UI 1691 */ 1692 public static class RecentFailure { 1693 1694 /** 1695 * No recent failure, or no specific reason given for the recent connection failure 1696 */ 1697 public static final int NONE = 0; 1698 /** 1699 * Connection to this network recently failed due to Association Rejection Status 17 1700 * (AP is full) 1701 */ 1702 public static final int STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17; 1703 /** 1704 * Association Rejection Status code (NONE for success/non-association-rejection-fail) 1705 */ 1706 private int mAssociationStatus = NONE; 1707 1708 /** 1709 * @param status the association status code for the recent failure 1710 */ setAssociationStatus(int status)1711 public void setAssociationStatus(int status) { 1712 mAssociationStatus = status; 1713 } 1714 /** 1715 * Sets the RecentFailure to NONE 1716 */ clear()1717 public void clear() { 1718 mAssociationStatus = NONE; 1719 } 1720 /** 1721 * Get the recent failure code 1722 */ getAssociationStatus()1723 public int getAssociationStatus() { 1724 return mAssociationStatus; 1725 } 1726 } 1727 1728 /** 1729 * @hide 1730 * RecentFailure member 1731 */ 1732 final public RecentFailure recentFailure = new RecentFailure(); 1733 1734 /** 1735 * @hide 1736 * @return network selection status 1737 */ getNetworkSelectionStatus()1738 public NetworkSelectionStatus getNetworkSelectionStatus() { 1739 return mNetworkSelectionStatus; 1740 } 1741 1742 /** 1743 * Set the network selection status 1744 * @hide 1745 */ setNetworkSelectionStatus(NetworkSelectionStatus status)1746 public void setNetworkSelectionStatus(NetworkSelectionStatus status) { 1747 mNetworkSelectionStatus = status; 1748 } 1749 1750 /** 1751 * @hide 1752 * Linked Configurations: represent the set of Wificonfigurations that are equivalent 1753 * regarding roaming and auto-joining. 1754 * The linked configuration may or may not have same SSID, and may or may not have same 1755 * credentials. 1756 * For instance, linked configurations will have same defaultGwMacAddress or same dhcp server. 1757 */ 1758 public HashMap<String, Integer> linkedConfigurations; 1759 WifiConfiguration()1760 public WifiConfiguration() { 1761 networkId = INVALID_NETWORK_ID; 1762 SSID = null; 1763 BSSID = null; 1764 FQDN = null; 1765 roamingConsortiumIds = new long[0]; 1766 priority = 0; 1767 hiddenSSID = false; 1768 allowedKeyManagement = new BitSet(); 1769 allowedProtocols = new BitSet(); 1770 allowedAuthAlgorithms = new BitSet(); 1771 allowedPairwiseCiphers = new BitSet(); 1772 allowedGroupCiphers = new BitSet(); 1773 allowedGroupManagementCiphers = new BitSet(); 1774 allowedSuiteBCiphers = new BitSet(); 1775 wepKeys = new String[4]; 1776 for (int i = 0; i < wepKeys.length; i++) { 1777 wepKeys[i] = null; 1778 } 1779 enterpriseConfig = new WifiEnterpriseConfig(); 1780 selfAdded = false; 1781 didSelfAdd = false; 1782 ephemeral = false; 1783 osu = false; 1784 trusted = true; // Networks are considered trusted by default. 1785 fromWifiNetworkSuggestion = false; 1786 fromWifiNetworkSpecifier = false; 1787 meteredHint = false; 1788 meteredOverride = METERED_OVERRIDE_NONE; 1789 useExternalScores = false; 1790 validatedInternetAccess = false; 1791 mIpConfiguration = new IpConfiguration(); 1792 lastUpdateUid = -1; 1793 creatorUid = -1; 1794 shared = true; 1795 dtimInterval = 0; 1796 mRandomizedMacAddress = MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS); 1797 } 1798 1799 /** 1800 * Identify if this configuration represents a Passpoint network 1801 */ isPasspoint()1802 public boolean isPasspoint() { 1803 return !TextUtils.isEmpty(FQDN) 1804 && !TextUtils.isEmpty(providerFriendlyName) 1805 && enterpriseConfig != null 1806 && enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE; 1807 } 1808 1809 /** 1810 * Helper function, identify if a configuration is linked 1811 * @hide 1812 */ isLinked(WifiConfiguration config)1813 public boolean isLinked(WifiConfiguration config) { 1814 if (config != null) { 1815 if (config.linkedConfigurations != null && linkedConfigurations != null) { 1816 if (config.linkedConfigurations.get(configKey()) != null 1817 && linkedConfigurations.get(config.configKey()) != null) { 1818 return true; 1819 } 1820 } 1821 } 1822 return false; 1823 } 1824 1825 /** 1826 * Helper function, idenfity if a configuration should be treated as an enterprise network 1827 * @hide 1828 */ 1829 @UnsupportedAppUsage isEnterprise()1830 public boolean isEnterprise() { 1831 return (allowedKeyManagement.get(KeyMgmt.WPA_EAP) 1832 || allowedKeyManagement.get(KeyMgmt.IEEE8021X) 1833 || allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) 1834 && enterpriseConfig != null 1835 && enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE; 1836 } 1837 1838 @Override toString()1839 public String toString() { 1840 StringBuilder sbuf = new StringBuilder(); 1841 if (this.status == WifiConfiguration.Status.CURRENT) { 1842 sbuf.append("* "); 1843 } else if (this.status == WifiConfiguration.Status.DISABLED) { 1844 sbuf.append("- DSBLE "); 1845 } 1846 sbuf.append("ID: ").append(this.networkId).append(" SSID: ").append(this.SSID). 1847 append(" PROVIDER-NAME: ").append(this.providerFriendlyName). 1848 append(" BSSID: ").append(this.BSSID).append(" FQDN: ").append(this.FQDN) 1849 .append(" PRIO: ").append(this.priority) 1850 .append(" HIDDEN: ").append(this.hiddenSSID) 1851 .append(" PMF: ").append(this.requirePMF) 1852 .append('\n'); 1853 1854 1855 sbuf.append(" NetworkSelectionStatus ") 1856 .append(mNetworkSelectionStatus.getNetworkStatusString() + "\n"); 1857 if (mNetworkSelectionStatus.getNetworkSelectionDisableReason() > 0) { 1858 sbuf.append(" mNetworkSelectionDisableReason ") 1859 .append(mNetworkSelectionStatus.getNetworkDisableReasonString() + "\n"); 1860 1861 for (int index = mNetworkSelectionStatus.NETWORK_SELECTION_ENABLE; 1862 index < mNetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX; index++) { 1863 if (mNetworkSelectionStatus.getDisableReasonCounter(index) != 0) { 1864 sbuf.append(NetworkSelectionStatus.getNetworkDisableReasonString(index) 1865 + " counter:" + mNetworkSelectionStatus.getDisableReasonCounter(index) 1866 + "\n"); 1867 } 1868 } 1869 } 1870 if (mNetworkSelectionStatus.getConnectChoice() != null) { 1871 sbuf.append(" connect choice: ").append(mNetworkSelectionStatus.getConnectChoice()); 1872 sbuf.append(" connect choice set time: ") 1873 .append(TimeUtils.logTimeOfDay( 1874 mNetworkSelectionStatus.getConnectChoiceTimestamp())); 1875 } 1876 sbuf.append(" hasEverConnected: ") 1877 .append(mNetworkSelectionStatus.getHasEverConnected()).append("\n"); 1878 1879 if (this.numAssociation > 0) { 1880 sbuf.append(" numAssociation ").append(this.numAssociation).append("\n"); 1881 } 1882 if (this.numNoInternetAccessReports > 0) { 1883 sbuf.append(" numNoInternetAccessReports "); 1884 sbuf.append(this.numNoInternetAccessReports).append("\n"); 1885 } 1886 if (this.updateTime != null) { 1887 sbuf.append(" update ").append(this.updateTime).append("\n"); 1888 } 1889 if (this.creationTime != null) { 1890 sbuf.append(" creation ").append(this.creationTime).append("\n"); 1891 } 1892 if (this.didSelfAdd) sbuf.append(" didSelfAdd"); 1893 if (this.selfAdded) sbuf.append(" selfAdded"); 1894 if (this.validatedInternetAccess) sbuf.append(" validatedInternetAccess"); 1895 if (this.ephemeral) sbuf.append(" ephemeral"); 1896 if (this.osu) sbuf.append(" osu"); 1897 if (this.trusted) sbuf.append(" trusted"); 1898 if (this.fromWifiNetworkSuggestion) sbuf.append(" fromWifiNetworkSuggestion"); 1899 if (this.fromWifiNetworkSpecifier) sbuf.append(" fromWifiNetworkSpecifier"); 1900 if (this.meteredHint) sbuf.append(" meteredHint"); 1901 if (this.useExternalScores) sbuf.append(" useExternalScores"); 1902 if (this.didSelfAdd || this.selfAdded || this.validatedInternetAccess 1903 || this.ephemeral || this.trusted || this.fromWifiNetworkSuggestion 1904 || this.fromWifiNetworkSpecifier || this.meteredHint || this.useExternalScores) { 1905 sbuf.append("\n"); 1906 } 1907 if (this.meteredOverride != METERED_OVERRIDE_NONE) { 1908 sbuf.append(" meteredOverride ").append(meteredOverride).append("\n"); 1909 } 1910 sbuf.append(" macRandomizationSetting: ").append(macRandomizationSetting).append("\n"); 1911 sbuf.append(" mRandomizedMacAddress: ").append(mRandomizedMacAddress).append("\n"); 1912 sbuf.append(" KeyMgmt:"); 1913 for (int k = 0; k < this.allowedKeyManagement.size(); k++) { 1914 if (this.allowedKeyManagement.get(k)) { 1915 sbuf.append(" "); 1916 if (k < KeyMgmt.strings.length) { 1917 sbuf.append(KeyMgmt.strings[k]); 1918 } else { 1919 sbuf.append("??"); 1920 } 1921 } 1922 } 1923 sbuf.append(" Protocols:"); 1924 for (int p = 0; p < this.allowedProtocols.size(); p++) { 1925 if (this.allowedProtocols.get(p)) { 1926 sbuf.append(" "); 1927 if (p < Protocol.strings.length) { 1928 sbuf.append(Protocol.strings[p]); 1929 } else { 1930 sbuf.append("??"); 1931 } 1932 } 1933 } 1934 sbuf.append('\n'); 1935 sbuf.append(" AuthAlgorithms:"); 1936 for (int a = 0; a < this.allowedAuthAlgorithms.size(); a++) { 1937 if (this.allowedAuthAlgorithms.get(a)) { 1938 sbuf.append(" "); 1939 if (a < AuthAlgorithm.strings.length) { 1940 sbuf.append(AuthAlgorithm.strings[a]); 1941 } else { 1942 sbuf.append("??"); 1943 } 1944 } 1945 } 1946 sbuf.append('\n'); 1947 sbuf.append(" PairwiseCiphers:"); 1948 for (int pc = 0; pc < this.allowedPairwiseCiphers.size(); pc++) { 1949 if (this.allowedPairwiseCiphers.get(pc)) { 1950 sbuf.append(" "); 1951 if (pc < PairwiseCipher.strings.length) { 1952 sbuf.append(PairwiseCipher.strings[pc]); 1953 } else { 1954 sbuf.append("??"); 1955 } 1956 } 1957 } 1958 sbuf.append('\n'); 1959 sbuf.append(" GroupCiphers:"); 1960 for (int gc = 0; gc < this.allowedGroupCiphers.size(); gc++) { 1961 if (this.allowedGroupCiphers.get(gc)) { 1962 sbuf.append(" "); 1963 if (gc < GroupCipher.strings.length) { 1964 sbuf.append(GroupCipher.strings[gc]); 1965 } else { 1966 sbuf.append("??"); 1967 } 1968 } 1969 } 1970 sbuf.append('\n'); 1971 sbuf.append(" GroupMgmtCiphers:"); 1972 for (int gmc = 0; gmc < this.allowedGroupManagementCiphers.size(); gmc++) { 1973 if (this.allowedGroupManagementCiphers.get(gmc)) { 1974 sbuf.append(" "); 1975 if (gmc < GroupMgmtCipher.strings.length) { 1976 sbuf.append(GroupMgmtCipher.strings[gmc]); 1977 } else { 1978 sbuf.append("??"); 1979 } 1980 } 1981 } 1982 sbuf.append('\n'); 1983 sbuf.append(" SuiteBCiphers:"); 1984 for (int sbc = 0; sbc < this.allowedSuiteBCiphers.size(); sbc++) { 1985 if (this.allowedSuiteBCiphers.get(sbc)) { 1986 sbuf.append(" "); 1987 if (sbc < SuiteBCipher.strings.length) { 1988 sbuf.append(SuiteBCipher.strings[sbc]); 1989 } else { 1990 sbuf.append("??"); 1991 } 1992 } 1993 } 1994 sbuf.append('\n').append(" PSK/SAE: "); 1995 if (this.preSharedKey != null) { 1996 sbuf.append('*'); 1997 } 1998 1999 sbuf.append("\nEnterprise config:\n"); 2000 sbuf.append(enterpriseConfig); 2001 2002 sbuf.append("IP config:\n"); 2003 sbuf.append(mIpConfiguration.toString()); 2004 2005 if (mNetworkSelectionStatus.getNetworkSelectionBSSID() != null) { 2006 sbuf.append(" networkSelectionBSSID=" 2007 + mNetworkSelectionStatus.getNetworkSelectionBSSID()); 2008 } 2009 long now_ms = SystemClock.elapsedRealtime(); 2010 if (mNetworkSelectionStatus.getDisableTime() != NetworkSelectionStatus 2011 .INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP) { 2012 sbuf.append('\n'); 2013 long diff = now_ms - mNetworkSelectionStatus.getDisableTime(); 2014 if (diff <= 0) { 2015 sbuf.append(" blackListed since <incorrect>"); 2016 } else { 2017 sbuf.append(" blackListed: ").append(Long.toString(diff / 1000)).append("sec "); 2018 } 2019 } 2020 if (creatorUid != 0) sbuf.append(" cuid=" + creatorUid); 2021 if (creatorName != null) sbuf.append(" cname=" + creatorName); 2022 if (lastUpdateUid != 0) sbuf.append(" luid=" + lastUpdateUid); 2023 if (lastUpdateName != null) sbuf.append(" lname=" + lastUpdateName); 2024 if (updateIdentifier != null) sbuf.append(" updateIdentifier=" + updateIdentifier); 2025 sbuf.append(" lcuid=" + lastConnectUid); 2026 sbuf.append(" userApproved=" + userApprovedAsString(userApproved)); 2027 sbuf.append(" noInternetAccessExpected=" + noInternetAccessExpected); 2028 sbuf.append(" "); 2029 2030 if (this.lastConnected != 0) { 2031 sbuf.append('\n'); 2032 sbuf.append("lastConnected: ").append(TimeUtils.logTimeOfDay(this.lastConnected)); 2033 sbuf.append(" "); 2034 } 2035 sbuf.append('\n'); 2036 if (this.linkedConfigurations != null) { 2037 for (String key : this.linkedConfigurations.keySet()) { 2038 sbuf.append(" linked: ").append(key); 2039 sbuf.append('\n'); 2040 } 2041 } 2042 sbuf.append("recentFailure: ").append("Association Rejection code: ") 2043 .append(recentFailure.getAssociationStatus()).append("\n"); 2044 return sbuf.toString(); 2045 } 2046 2047 /** {@hide} */ 2048 @UnsupportedAppUsage getPrintableSsid()2049 public String getPrintableSsid() { 2050 if (SSID == null) return ""; 2051 final int length = SSID.length(); 2052 if (length > 2 && (SSID.charAt(0) == '"') && SSID.charAt(length - 1) == '"') { 2053 return SSID.substring(1, length - 1); 2054 } 2055 2056 /** The ascii-encoded string format is P"<ascii-encoded-string>" 2057 * The decoding is implemented in the supplicant for a newly configured 2058 * network. 2059 */ 2060 if (length > 3 && (SSID.charAt(0) == 'P') && (SSID.charAt(1) == '"') && 2061 (SSID.charAt(length-1) == '"')) { 2062 WifiSsid wifiSsid = WifiSsid.createFromAsciiEncoded( 2063 SSID.substring(2, length - 1)); 2064 return wifiSsid.toString(); 2065 } 2066 return SSID; 2067 } 2068 2069 /** @hide **/ userApprovedAsString(int userApproved)2070 public static String userApprovedAsString(int userApproved) { 2071 switch (userApproved) { 2072 case USER_APPROVED: 2073 return "USER_APPROVED"; 2074 case USER_BANNED: 2075 return "USER_BANNED"; 2076 case USER_UNSPECIFIED: 2077 return "USER_UNSPECIFIED"; 2078 default: 2079 return "INVALID"; 2080 } 2081 } 2082 2083 /** 2084 * Get an identifier for associating credentials with this config 2085 * @param current configuration contains values for additional fields 2086 * that are not part of this configuration. Used 2087 * when a config with some fields is passed by an application. 2088 * @throws IllegalStateException if config is invalid for key id generation 2089 * @hide 2090 */ getKeyIdForCredentials(WifiConfiguration current)2091 public String getKeyIdForCredentials(WifiConfiguration current) { 2092 String keyMgmt = ""; 2093 2094 try { 2095 // Get current config details for fields that are not initialized 2096 if (TextUtils.isEmpty(SSID)) SSID = current.SSID; 2097 if (allowedKeyManagement.cardinality() == 0) { 2098 allowedKeyManagement = current.allowedKeyManagement; 2099 } 2100 if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) { 2101 keyMgmt += KeyMgmt.strings[KeyMgmt.WPA_EAP]; 2102 } 2103 if (allowedKeyManagement.get(KeyMgmt.OSEN)) { 2104 keyMgmt += KeyMgmt.strings[KeyMgmt.OSEN]; 2105 } 2106 if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) { 2107 keyMgmt += KeyMgmt.strings[KeyMgmt.IEEE8021X]; 2108 } 2109 if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) { 2110 keyMgmt += KeyMgmt.strings[KeyMgmt.SUITE_B_192]; 2111 } 2112 2113 if (TextUtils.isEmpty(keyMgmt)) { 2114 throw new IllegalStateException("Not an EAP network"); 2115 } 2116 2117 String keyId = trimStringForKeyId(SSID) + "_" + keyMgmt + "_" 2118 + trimStringForKeyId(enterpriseConfig.getKeyId(current != null 2119 ? current.enterpriseConfig : null)); 2120 2121 if (!fromWifiNetworkSuggestion) { 2122 return keyId; 2123 } 2124 return keyId + "_" + trimStringForKeyId(BSSID) + "_" + trimStringForKeyId(creatorName); 2125 } catch (NullPointerException e) { 2126 throw new IllegalStateException("Invalid config details"); 2127 } 2128 } 2129 trimStringForKeyId(String string)2130 private String trimStringForKeyId(String string) { 2131 if (string == null) { 2132 return ""; 2133 } 2134 // Remove quotes and spaces 2135 return string.replace("\"", "").replace(" ", ""); 2136 } 2137 readBitSet(Parcel src)2138 private static BitSet readBitSet(Parcel src) { 2139 int cardinality = src.readInt(); 2140 2141 BitSet set = new BitSet(); 2142 for (int i = 0; i < cardinality; i++) { 2143 set.set(src.readInt()); 2144 } 2145 2146 return set; 2147 } 2148 writeBitSet(Parcel dest, BitSet set)2149 private static void writeBitSet(Parcel dest, BitSet set) { 2150 int nextSetBit = -1; 2151 2152 dest.writeInt(set.cardinality()); 2153 2154 while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1) { 2155 dest.writeInt(nextSetBit); 2156 } 2157 } 2158 2159 /** @hide */ 2160 @UnsupportedAppUsage getAuthType()2161 public int getAuthType() { 2162 if (allowedKeyManagement.cardinality() > 1) { 2163 throw new IllegalStateException("More than one auth type set"); 2164 } 2165 if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) { 2166 return KeyMgmt.WPA_PSK; 2167 } else if (allowedKeyManagement.get(KeyMgmt.WPA2_PSK)) { 2168 return KeyMgmt.WPA2_PSK; 2169 } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) { 2170 return KeyMgmt.WPA_EAP; 2171 } else if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) { 2172 return KeyMgmt.IEEE8021X; 2173 } else if (allowedKeyManagement.get(KeyMgmt.SAE)) { 2174 return KeyMgmt.SAE; 2175 } else if (allowedKeyManagement.get(KeyMgmt.OWE)) { 2176 return KeyMgmt.OWE; 2177 } else if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) { 2178 return KeyMgmt.SUITE_B_192; 2179 } 2180 return KeyMgmt.NONE; 2181 } 2182 2183 /* @hide 2184 * Cache the config key, this seems useful as a speed up since a lot of 2185 * lookups in the config store are done and based on this key. 2186 */ 2187 String mCachedConfigKey; 2188 2189 /** @hide 2190 * return the string used to calculate the hash in WifiConfigStore 2191 * and uniquely identify this WifiConfiguration 2192 */ configKey(boolean allowCached)2193 public String configKey(boolean allowCached) { 2194 String key; 2195 if (allowCached && mCachedConfigKey != null) { 2196 key = mCachedConfigKey; 2197 } else if (providerFriendlyName != null) { 2198 key = FQDN + KeyMgmt.strings[KeyMgmt.WPA_EAP]; 2199 if (!shared) { 2200 key += "-" + Integer.toString(UserHandle.getUserId(creatorUid)); 2201 } 2202 } else { 2203 key = getSsidAndSecurityTypeString(); 2204 if (!shared) { 2205 key += "-" + Integer.toString(UserHandle.getUserId(creatorUid)); 2206 } 2207 mCachedConfigKey = key; 2208 } 2209 return key; 2210 } 2211 2212 /** @hide 2213 * return the SSID + security type in String format. 2214 */ getSsidAndSecurityTypeString()2215 public String getSsidAndSecurityTypeString() { 2216 String key; 2217 if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) { 2218 key = SSID + KeyMgmt.strings[KeyMgmt.WPA_PSK]; 2219 } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP) 2220 || allowedKeyManagement.get(KeyMgmt.IEEE8021X)) { 2221 key = SSID + KeyMgmt.strings[KeyMgmt.WPA_EAP]; 2222 } else if (wepKeys[0] != null) { 2223 key = SSID + "WEP"; 2224 } else if (allowedKeyManagement.get(KeyMgmt.OWE)) { 2225 key = SSID + KeyMgmt.strings[KeyMgmt.OWE]; 2226 } else if (allowedKeyManagement.get(KeyMgmt.SAE)) { 2227 key = SSID + KeyMgmt.strings[KeyMgmt.SAE]; 2228 } else if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) { 2229 key = SSID + KeyMgmt.strings[KeyMgmt.SUITE_B_192]; 2230 } else { 2231 key = SSID + KeyMgmt.strings[KeyMgmt.NONE]; 2232 } 2233 return key; 2234 } 2235 2236 /** @hide 2237 * get configKey, force calculating the config string 2238 */ configKey()2239 public String configKey() { 2240 return configKey(false); 2241 } 2242 2243 /** @hide */ 2244 @UnsupportedAppUsage getIpConfiguration()2245 public IpConfiguration getIpConfiguration() { 2246 return mIpConfiguration; 2247 } 2248 2249 /** @hide */ 2250 @UnsupportedAppUsage setIpConfiguration(IpConfiguration ipConfiguration)2251 public void setIpConfiguration(IpConfiguration ipConfiguration) { 2252 if (ipConfiguration == null) ipConfiguration = new IpConfiguration(); 2253 mIpConfiguration = ipConfiguration; 2254 } 2255 2256 /** @hide */ 2257 @UnsupportedAppUsage getStaticIpConfiguration()2258 public StaticIpConfiguration getStaticIpConfiguration() { 2259 return mIpConfiguration.getStaticIpConfiguration(); 2260 } 2261 2262 /** @hide */ 2263 @UnsupportedAppUsage setStaticIpConfiguration(StaticIpConfiguration staticIpConfiguration)2264 public void setStaticIpConfiguration(StaticIpConfiguration staticIpConfiguration) { 2265 mIpConfiguration.setStaticIpConfiguration(staticIpConfiguration); 2266 } 2267 2268 /** @hide */ 2269 @UnsupportedAppUsage getIpAssignment()2270 public IpConfiguration.IpAssignment getIpAssignment() { 2271 return mIpConfiguration.ipAssignment; 2272 } 2273 2274 /** @hide */ 2275 @UnsupportedAppUsage setIpAssignment(IpConfiguration.IpAssignment ipAssignment)2276 public void setIpAssignment(IpConfiguration.IpAssignment ipAssignment) { 2277 mIpConfiguration.ipAssignment = ipAssignment; 2278 } 2279 2280 /** @hide */ 2281 @UnsupportedAppUsage getProxySettings()2282 public IpConfiguration.ProxySettings getProxySettings() { 2283 return mIpConfiguration.proxySettings; 2284 } 2285 2286 /** @hide */ 2287 @UnsupportedAppUsage setProxySettings(IpConfiguration.ProxySettings proxySettings)2288 public void setProxySettings(IpConfiguration.ProxySettings proxySettings) { 2289 mIpConfiguration.proxySettings = proxySettings; 2290 } 2291 2292 /** 2293 * Returns the HTTP proxy used by this object. 2294 * @return a {@link ProxyInfo httpProxy} representing the proxy specified by this 2295 * WifiConfiguration, or {@code null} if no proxy is specified. 2296 */ getHttpProxy()2297 public ProxyInfo getHttpProxy() { 2298 if (mIpConfiguration.proxySettings == IpConfiguration.ProxySettings.NONE) { 2299 return null; 2300 } 2301 return new ProxyInfo(mIpConfiguration.httpProxy); 2302 } 2303 2304 /** 2305 * Set the {@link ProxyInfo} for this WifiConfiguration. This method should only be used by a 2306 * device owner or profile owner. When other apps attempt to save a {@link WifiConfiguration} 2307 * with modified proxy settings, the methods {@link WifiManager#addNetwork} and 2308 * {@link WifiManager#updateNetwork} fail and return {@code -1}. 2309 * 2310 * @param httpProxy {@link ProxyInfo} representing the httpProxy to be used by this 2311 * WifiConfiguration. Setting this to {@code null} will explicitly set no 2312 * proxy, removing any proxy that was previously set. 2313 * @exception IllegalArgumentException for invalid httpProxy 2314 */ setHttpProxy(ProxyInfo httpProxy)2315 public void setHttpProxy(ProxyInfo httpProxy) { 2316 if (httpProxy == null) { 2317 mIpConfiguration.setProxySettings(IpConfiguration.ProxySettings.NONE); 2318 mIpConfiguration.setHttpProxy(null); 2319 return; 2320 } 2321 ProxyInfo httpProxyCopy; 2322 ProxySettings proxySettingCopy; 2323 if (!Uri.EMPTY.equals(httpProxy.getPacFileUrl())) { 2324 proxySettingCopy = IpConfiguration.ProxySettings.PAC; 2325 // Construct a new PAC URL Proxy 2326 httpProxyCopy = new ProxyInfo(httpProxy.getPacFileUrl(), httpProxy.getPort()); 2327 } else { 2328 proxySettingCopy = IpConfiguration.ProxySettings.STATIC; 2329 // Construct a new HTTP Proxy 2330 httpProxyCopy = new ProxyInfo(httpProxy.getHost(), httpProxy.getPort(), 2331 httpProxy.getExclusionListAsString()); 2332 } 2333 if (!httpProxyCopy.isValid()) { 2334 throw new IllegalArgumentException("Invalid ProxyInfo: " + httpProxyCopy.toString()); 2335 } 2336 mIpConfiguration.setProxySettings(proxySettingCopy); 2337 mIpConfiguration.setHttpProxy(httpProxyCopy); 2338 } 2339 2340 /** @hide */ 2341 @UnsupportedAppUsage setProxy(ProxySettings settings, ProxyInfo proxy)2342 public void setProxy(ProxySettings settings, ProxyInfo proxy) { 2343 mIpConfiguration.proxySettings = settings; 2344 mIpConfiguration.httpProxy = proxy; 2345 } 2346 2347 /** Implement the Parcelable interface {@hide} */ describeContents()2348 public int describeContents() { 2349 return 0; 2350 } 2351 2352 /** @hide */ setPasspointManagementObjectTree(String passpointManagementObjectTree)2353 public void setPasspointManagementObjectTree(String passpointManagementObjectTree) { 2354 mPasspointManagementObjectTree = passpointManagementObjectTree; 2355 } 2356 2357 /** @hide */ getMoTree()2358 public String getMoTree() { 2359 return mPasspointManagementObjectTree; 2360 } 2361 2362 /** copy constructor {@hide} */ 2363 @UnsupportedAppUsage WifiConfiguration(WifiConfiguration source)2364 public WifiConfiguration(WifiConfiguration source) { 2365 if (source != null) { 2366 networkId = source.networkId; 2367 status = source.status; 2368 SSID = source.SSID; 2369 BSSID = source.BSSID; 2370 FQDN = source.FQDN; 2371 roamingConsortiumIds = source.roamingConsortiumIds.clone(); 2372 providerFriendlyName = source.providerFriendlyName; 2373 isHomeProviderNetwork = source.isHomeProviderNetwork; 2374 preSharedKey = source.preSharedKey; 2375 2376 mNetworkSelectionStatus.copy(source.getNetworkSelectionStatus()); 2377 apBand = source.apBand; 2378 apChannel = source.apChannel; 2379 2380 wepKeys = new String[4]; 2381 for (int i = 0; i < wepKeys.length; i++) { 2382 wepKeys[i] = source.wepKeys[i]; 2383 } 2384 2385 wepTxKeyIndex = source.wepTxKeyIndex; 2386 priority = source.priority; 2387 hiddenSSID = source.hiddenSSID; 2388 allowedKeyManagement = (BitSet) source.allowedKeyManagement.clone(); 2389 allowedProtocols = (BitSet) source.allowedProtocols.clone(); 2390 allowedAuthAlgorithms = (BitSet) source.allowedAuthAlgorithms.clone(); 2391 allowedPairwiseCiphers = (BitSet) source.allowedPairwiseCiphers.clone(); 2392 allowedGroupCiphers = (BitSet) source.allowedGroupCiphers.clone(); 2393 allowedGroupManagementCiphers = (BitSet) source.allowedGroupManagementCiphers.clone(); 2394 allowedSuiteBCiphers = (BitSet) source.allowedSuiteBCiphers.clone(); 2395 enterpriseConfig = new WifiEnterpriseConfig(source.enterpriseConfig); 2396 2397 defaultGwMacAddress = source.defaultGwMacAddress; 2398 2399 mIpConfiguration = new IpConfiguration(source.mIpConfiguration); 2400 2401 if ((source.linkedConfigurations != null) 2402 && (source.linkedConfigurations.size() > 0)) { 2403 linkedConfigurations = new HashMap<String, Integer>(); 2404 linkedConfigurations.putAll(source.linkedConfigurations); 2405 } 2406 mCachedConfigKey = null; //force null configKey 2407 selfAdded = source.selfAdded; 2408 validatedInternetAccess = source.validatedInternetAccess; 2409 isLegacyPasspointConfig = source.isLegacyPasspointConfig; 2410 ephemeral = source.ephemeral; 2411 osu = source.osu; 2412 trusted = source.trusted; 2413 fromWifiNetworkSuggestion = source.fromWifiNetworkSuggestion; 2414 fromWifiNetworkSpecifier = source.fromWifiNetworkSpecifier; 2415 meteredHint = source.meteredHint; 2416 meteredOverride = source.meteredOverride; 2417 useExternalScores = source.useExternalScores; 2418 2419 didSelfAdd = source.didSelfAdd; 2420 lastConnectUid = source.lastConnectUid; 2421 lastUpdateUid = source.lastUpdateUid; 2422 creatorUid = source.creatorUid; 2423 creatorName = source.creatorName; 2424 lastUpdateName = source.lastUpdateName; 2425 peerWifiConfiguration = source.peerWifiConfiguration; 2426 2427 lastConnected = source.lastConnected; 2428 lastDisconnected = source.lastDisconnected; 2429 numScorerOverride = source.numScorerOverride; 2430 numScorerOverrideAndSwitchedNetwork = source.numScorerOverrideAndSwitchedNetwork; 2431 numAssociation = source.numAssociation; 2432 userApproved = source.userApproved; 2433 numNoInternetAccessReports = source.numNoInternetAccessReports; 2434 noInternetAccessExpected = source.noInternetAccessExpected; 2435 creationTime = source.creationTime; 2436 updateTime = source.updateTime; 2437 shared = source.shared; 2438 recentFailure.setAssociationStatus(source.recentFailure.getAssociationStatus()); 2439 mRandomizedMacAddress = source.mRandomizedMacAddress; 2440 macRandomizationSetting = source.macRandomizationSetting; 2441 requirePMF = source.requirePMF; 2442 updateIdentifier = source.updateIdentifier; 2443 } 2444 } 2445 2446 /** Implement the Parcelable interface {@hide} */ 2447 @Override writeToParcel(Parcel dest, int flags)2448 public void writeToParcel(Parcel dest, int flags) { 2449 dest.writeInt(networkId); 2450 dest.writeInt(status); 2451 mNetworkSelectionStatus.writeToParcel(dest); 2452 dest.writeString(SSID); 2453 dest.writeString(BSSID); 2454 dest.writeInt(apBand); 2455 dest.writeInt(apChannel); 2456 dest.writeString(FQDN); 2457 dest.writeString(providerFriendlyName); 2458 dest.writeInt(isHomeProviderNetwork ? 1 : 0); 2459 dest.writeInt(roamingConsortiumIds.length); 2460 for (long roamingConsortiumId : roamingConsortiumIds) { 2461 dest.writeLong(roamingConsortiumId); 2462 } 2463 dest.writeString(preSharedKey); 2464 for (String wepKey : wepKeys) { 2465 dest.writeString(wepKey); 2466 } 2467 dest.writeInt(wepTxKeyIndex); 2468 dest.writeInt(priority); 2469 dest.writeInt(hiddenSSID ? 1 : 0); 2470 dest.writeInt(requirePMF ? 1 : 0); 2471 dest.writeString(updateIdentifier); 2472 2473 writeBitSet(dest, allowedKeyManagement); 2474 writeBitSet(dest, allowedProtocols); 2475 writeBitSet(dest, allowedAuthAlgorithms); 2476 writeBitSet(dest, allowedPairwiseCiphers); 2477 writeBitSet(dest, allowedGroupCiphers); 2478 writeBitSet(dest, allowedGroupManagementCiphers); 2479 writeBitSet(dest, allowedSuiteBCiphers); 2480 2481 dest.writeParcelable(enterpriseConfig, flags); 2482 2483 dest.writeParcelable(mIpConfiguration, flags); 2484 dest.writeString(dhcpServer); 2485 dest.writeString(defaultGwMacAddress); 2486 dest.writeInt(selfAdded ? 1 : 0); 2487 dest.writeInt(didSelfAdd ? 1 : 0); 2488 dest.writeInt(validatedInternetAccess ? 1 : 0); 2489 dest.writeInt(isLegacyPasspointConfig ? 1 : 0); 2490 dest.writeInt(ephemeral ? 1 : 0); 2491 dest.writeInt(trusted ? 1 : 0); 2492 dest.writeInt(fromWifiNetworkSuggestion ? 1 : 0); 2493 dest.writeInt(fromWifiNetworkSpecifier ? 1 : 0); 2494 dest.writeInt(meteredHint ? 1 : 0); 2495 dest.writeInt(meteredOverride); 2496 dest.writeInt(useExternalScores ? 1 : 0); 2497 dest.writeInt(creatorUid); 2498 dest.writeInt(lastConnectUid); 2499 dest.writeInt(lastUpdateUid); 2500 dest.writeString(creatorName); 2501 dest.writeString(lastUpdateName); 2502 dest.writeInt(numScorerOverride); 2503 dest.writeInt(numScorerOverrideAndSwitchedNetwork); 2504 dest.writeInt(numAssociation); 2505 dest.writeInt(userApproved); 2506 dest.writeInt(numNoInternetAccessReports); 2507 dest.writeInt(noInternetAccessExpected ? 1 : 0); 2508 dest.writeInt(shared ? 1 : 0); 2509 dest.writeString(mPasspointManagementObjectTree); 2510 dest.writeInt(recentFailure.getAssociationStatus()); 2511 dest.writeParcelable(mRandomizedMacAddress, flags); 2512 dest.writeInt(macRandomizationSetting); 2513 dest.writeInt(osu ? 1 : 0); 2514 } 2515 2516 /** Implement the Parcelable interface {@hide} */ 2517 @UnsupportedAppUsage 2518 public static final @android.annotation.NonNull Creator<WifiConfiguration> CREATOR = 2519 new Creator<WifiConfiguration>() { 2520 public WifiConfiguration createFromParcel(Parcel in) { 2521 WifiConfiguration config = new WifiConfiguration(); 2522 config.networkId = in.readInt(); 2523 config.status = in.readInt(); 2524 config.mNetworkSelectionStatus.readFromParcel(in); 2525 config.SSID = in.readString(); 2526 config.BSSID = in.readString(); 2527 config.apBand = in.readInt(); 2528 config.apChannel = in.readInt(); 2529 config.FQDN = in.readString(); 2530 config.providerFriendlyName = in.readString(); 2531 config.isHomeProviderNetwork = in.readInt() != 0; 2532 int numRoamingConsortiumIds = in.readInt(); 2533 config.roamingConsortiumIds = new long[numRoamingConsortiumIds]; 2534 for (int i = 0; i < numRoamingConsortiumIds; i++) { 2535 config.roamingConsortiumIds[i] = in.readLong(); 2536 } 2537 config.preSharedKey = in.readString(); 2538 for (int i = 0; i < config.wepKeys.length; i++) { 2539 config.wepKeys[i] = in.readString(); 2540 } 2541 config.wepTxKeyIndex = in.readInt(); 2542 config.priority = in.readInt(); 2543 config.hiddenSSID = in.readInt() != 0; 2544 config.requirePMF = in.readInt() != 0; 2545 config.updateIdentifier = in.readString(); 2546 2547 config.allowedKeyManagement = readBitSet(in); 2548 config.allowedProtocols = readBitSet(in); 2549 config.allowedAuthAlgorithms = readBitSet(in); 2550 config.allowedPairwiseCiphers = readBitSet(in); 2551 config.allowedGroupCiphers = readBitSet(in); 2552 config.allowedGroupManagementCiphers = readBitSet(in); 2553 config.allowedSuiteBCiphers = readBitSet(in); 2554 2555 config.enterpriseConfig = in.readParcelable(null); 2556 config.setIpConfiguration(in.readParcelable(null)); 2557 config.dhcpServer = in.readString(); 2558 config.defaultGwMacAddress = in.readString(); 2559 config.selfAdded = in.readInt() != 0; 2560 config.didSelfAdd = in.readInt() != 0; 2561 config.validatedInternetAccess = in.readInt() != 0; 2562 config.isLegacyPasspointConfig = in.readInt() != 0; 2563 config.ephemeral = in.readInt() != 0; 2564 config.trusted = in.readInt() != 0; 2565 config.fromWifiNetworkSuggestion = in.readInt() != 0; 2566 config.fromWifiNetworkSpecifier = in.readInt() != 0; 2567 config.meteredHint = in.readInt() != 0; 2568 config.meteredOverride = in.readInt(); 2569 config.useExternalScores = in.readInt() != 0; 2570 config.creatorUid = in.readInt(); 2571 config.lastConnectUid = in.readInt(); 2572 config.lastUpdateUid = in.readInt(); 2573 config.creatorName = in.readString(); 2574 config.lastUpdateName = in.readString(); 2575 config.numScorerOverride = in.readInt(); 2576 config.numScorerOverrideAndSwitchedNetwork = in.readInt(); 2577 config.numAssociation = in.readInt(); 2578 config.userApproved = in.readInt(); 2579 config.numNoInternetAccessReports = in.readInt(); 2580 config.noInternetAccessExpected = in.readInt() != 0; 2581 config.shared = in.readInt() != 0; 2582 config.mPasspointManagementObjectTree = in.readString(); 2583 config.recentFailure.setAssociationStatus(in.readInt()); 2584 config.mRandomizedMacAddress = in.readParcelable(null); 2585 config.macRandomizationSetting = in.readInt(); 2586 config.osu = in.readInt() != 0; 2587 return config; 2588 } 2589 2590 public WifiConfiguration[] newArray(int size) { 2591 return new WifiConfiguration[size]; 2592 } 2593 }; 2594 2595 /** 2596 * Serializes the object for backup 2597 * @hide 2598 */ getBytesForBackup()2599 public byte[] getBytesForBackup() throws IOException { 2600 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 2601 DataOutputStream out = new DataOutputStream(baos); 2602 2603 out.writeInt(BACKUP_VERSION); 2604 BackupUtils.writeString(out, SSID); 2605 out.writeInt(apBand); 2606 out.writeInt(apChannel); 2607 BackupUtils.writeString(out, preSharedKey); 2608 out.writeInt(getAuthType()); 2609 out.writeBoolean(hiddenSSID); 2610 return baos.toByteArray(); 2611 } 2612 2613 /** 2614 * Deserializes a byte array into the WiFiConfiguration Object 2615 * @hide 2616 */ getWifiConfigFromBackup(DataInputStream in)2617 public static WifiConfiguration getWifiConfigFromBackup(DataInputStream in) throws IOException, 2618 BackupUtils.BadVersionException { 2619 WifiConfiguration config = new WifiConfiguration(); 2620 int version = in.readInt(); 2621 if (version < 1 || version > BACKUP_VERSION) { 2622 throw new BackupUtils.BadVersionException("Unknown Backup Serialization Version"); 2623 } 2624 2625 if (version == 1) return null; // Version 1 is a bad dataset. 2626 2627 config.SSID = BackupUtils.readString(in); 2628 config.apBand = in.readInt(); 2629 config.apChannel = in.readInt(); 2630 config.preSharedKey = BackupUtils.readString(in); 2631 config.allowedKeyManagement.set(in.readInt()); 2632 if (version >= 3) { 2633 config.hiddenSSID = in.readBoolean(); 2634 } 2635 return config; 2636 } 2637 } 2638