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