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