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.os.Parcel; 26 import android.os.Parcelable; 27 import android.text.TextUtils; 28 import android.util.Log; 29 30 import java.util.HashMap; 31 import java.util.BitSet; 32 import java.util.ArrayList; 33 import java.util.Collections; 34 import java.util.Comparator; 35 import java.util.HashSet; 36 37 /** 38 * A class representing a configured Wi-Fi network, including the 39 * security configuration. 40 */ 41 public class WifiConfiguration implements Parcelable { 42 private static final String TAG = "WifiConfiguration"; 43 /** {@hide} */ 44 public static final String ssidVarName = "ssid"; 45 /** {@hide} */ 46 public static final String bssidVarName = "bssid"; 47 /** {@hide} */ 48 public static final String pskVarName = "psk"; 49 /** {@hide} */ 50 public static final String[] wepKeyVarNames = { "wep_key0", "wep_key1", "wep_key2", "wep_key3" }; 51 /** {@hide} */ 52 public static final String wepTxKeyIdxVarName = "wep_tx_keyidx"; 53 /** {@hide} */ 54 public static final String priorityVarName = "priority"; 55 /** {@hide} */ 56 public static final String hiddenSSIDVarName = "scan_ssid"; 57 /** {@hide} */ 58 public static final String pmfVarName = "ieee80211w"; 59 /** {@hide} */ 60 public static final String updateIdentiferVarName = "update_identifier"; 61 /** {@hide} */ 62 public static final int INVALID_NETWORK_ID = -1; 63 64 /** 65 * Recognized key management schemes. 66 */ 67 public static class KeyMgmt { 68 private KeyMgmt() { } 69 70 /** WPA is not used; plaintext or static WEP could be used. */ 71 public static final int NONE = 0; 72 /** WPA pre-shared key (requires {@code preSharedKey} to be specified). */ 73 public static final int WPA_PSK = 1; 74 /** WPA using EAP authentication. Generally used with an external authentication server. */ 75 public static final int WPA_EAP = 2; 76 /** IEEE 802.1X using EAP authentication and (optionally) dynamically 77 * generated WEP keys. */ 78 public static final int IEEE8021X = 3; 79 80 /** WPA2 pre-shared key for use with soft access point 81 * (requires {@code preSharedKey} to be specified). 82 * @hide 83 */ 84 public static final int WPA2_PSK = 4; 85 86 public static final String varName = "key_mgmt"; 87 88 public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP", "IEEE8021X", 89 "WPA2_PSK" }; 90 } 91 92 /** 93 * Recognized security protocols. 94 */ 95 public static class Protocol { 96 private Protocol() { } 97 98 /** WPA/IEEE 802.11i/D3.0 */ 99 public static final int WPA = 0; 100 /** WPA2/IEEE 802.11i */ 101 public static final int RSN = 1; 102 103 public static final String varName = "proto"; 104 105 public static final String[] strings = { "WPA", "RSN" }; 106 } 107 108 /** 109 * Recognized IEEE 802.11 authentication algorithms. 110 */ 111 public static class AuthAlgorithm { 112 private AuthAlgorithm() { } 113 114 /** Open System authentication (required for WPA/WPA2) */ 115 public static final int OPEN = 0; 116 /** Shared Key authentication (requires static WEP keys) */ 117 public static final int SHARED = 1; 118 /** LEAP/Network EAP (only used with LEAP) */ 119 public static final int LEAP = 2; 120 121 public static final String varName = "auth_alg"; 122 123 public static final String[] strings = { "OPEN", "SHARED", "LEAP" }; 124 } 125 126 /** 127 * Recognized pairwise ciphers for WPA. 128 */ 129 public static class PairwiseCipher { 130 private PairwiseCipher() { } 131 132 /** Use only Group keys (deprecated) */ 133 public static final int NONE = 0; 134 /** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] */ 135 public static final int TKIP = 1; 136 /** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */ 137 public static final int CCMP = 2; 138 139 public static final String varName = "pairwise"; 140 141 public static final String[] strings = { "NONE", "TKIP", "CCMP" }; 142 } 143 144 /** 145 * Recognized group ciphers. 146 * <pre> 147 * CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] 148 * TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] 149 * WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key 150 * WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11) 151 * </pre> 152 */ 153 public static class GroupCipher { 154 private GroupCipher() { } 155 156 /** WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11) */ 157 public static final int WEP40 = 0; 158 /** WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key */ 159 public static final int WEP104 = 1; 160 /** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] */ 161 public static final int TKIP = 2; 162 /** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */ 163 public static final int CCMP = 3; 164 165 public static final String varName = "group"; 166 167 public static final String[] strings = { "WEP40", "WEP104", "TKIP", "CCMP" }; 168 } 169 170 /** Possible status of a network configuration. */ 171 public static class Status { 172 private Status() { } 173 174 /** this is the network we are currently connected to */ 175 public static final int CURRENT = 0; 176 /** supplicant will not attempt to use this network */ 177 public static final int DISABLED = 1; 178 /** supplicant will consider this network available for association */ 179 public static final int ENABLED = 2; 180 181 public static final String[] strings = { "current", "disabled", "enabled" }; 182 } 183 184 /** @hide */ 185 public static final int DISABLED_UNKNOWN_REASON = 0; 186 /** @hide */ 187 public static final int DISABLED_DNS_FAILURE = 1; 188 /** @hide */ 189 public static final int DISABLED_DHCP_FAILURE = 2; 190 /** @hide */ 191 public static final int DISABLED_AUTH_FAILURE = 3; 192 /** @hide */ 193 public static final int DISABLED_ASSOCIATION_REJECT = 4; 194 /** @hide */ 195 public static final int DISABLED_BY_WIFI_MANAGER = 5; 196 197 /** @hide */ 198 public static final int UNKNOWN_UID = -1; 199 200 /** 201 * The ID number that the supplicant uses to identify this 202 * network configuration entry. This must be passed as an argument 203 * to most calls into the supplicant. 204 */ 205 public int networkId; 206 207 /** 208 * The current status of this network configuration entry. 209 * @see Status 210 */ 211 public int status; 212 213 /** 214 * The configuration needs to be written to networkHistory.txt 215 * @hide 216 */ 217 public boolean dirty; 218 219 /** 220 * The code referring to a reason for disabling the network 221 * Valid when {@link #status} == Status.DISABLED 222 * @hide 223 */ 224 public int disableReason; 225 226 /** 227 * The network's SSID. Can either be an ASCII string, 228 * which must be enclosed in double quotation marks 229 * (e.g., {@code "MyNetwork"}, or a string of 230 * hex digits,which are not enclosed in quotes 231 * (e.g., {@code 01a243f405}). 232 */ 233 public String SSID; 234 /** 235 * When set, this network configuration entry should only be used when 236 * associating with the AP having the specified BSSID. The value is 237 * a string in the format of an Ethernet MAC address, e.g., 238 * <code>XX:XX:XX:XX:XX:XX</code> where each <code>X</code> is a hex digit. 239 */ 240 public String BSSID; 241 242 /** 243 * The band which AP resides on 244 * 0-2G 1-5G 245 * By default, 2G is chosen 246 * @hide 247 */ 248 public int apBand = 0; 249 250 /** 251 * The channel which AP resides on,currently, US only 252 * 2G 1-11 253 * 5G 36,40,44,48,149,153,157,161,165 254 * 0 - find a random available channel according to the apBand 255 * @hide 256 */ 257 public int apChannel = 0; 258 259 /** 260 * Pre-shared key for use with WPA-PSK. 261 * <p/> 262 * When the value of this key is read, the actual key is 263 * not returned, just a "*" if the key has a value, or the null 264 * string otherwise. 265 */ 266 public String preSharedKey; 267 /** 268 * Up to four WEP keys. Either an ASCII string enclosed in double 269 * quotation marks (e.g., {@code "abcdef"} or a string 270 * of hex digits (e.g., {@code 0102030405}). 271 * <p/> 272 * When the value of one of these keys is read, the actual key is 273 * not returned, just a "*" if the key has a value, or the null 274 * string otherwise. 275 */ 276 public String[] wepKeys; 277 278 /** Default WEP key index, ranging from 0 to 3. */ 279 public int wepTxKeyIndex; 280 281 /** 282 * Priority determines the preference given to a network by {@code wpa_supplicant} 283 * when choosing an access point with which to associate. 284 */ 285 public int priority; 286 287 /** 288 * This is a network that does not broadcast its SSID, so an 289 * SSID-specific probe request must be used for scans. 290 */ 291 public boolean hiddenSSID; 292 293 /** 294 * This is a network that requries Protected Management Frames (PMF). 295 * @hide 296 */ 297 public boolean requirePMF; 298 299 /** 300 * Update identifier, for Passpoint network. 301 * @hide 302 */ 303 public String updateIdentifier; 304 305 /** 306 * The set of key management protocols supported by this configuration. 307 * See {@link KeyMgmt} for descriptions of the values. 308 * Defaults to WPA-PSK WPA-EAP. 309 */ 310 public BitSet allowedKeyManagement; 311 /** 312 * The set of security protocols supported by this configuration. 313 * See {@link Protocol} for descriptions of the values. 314 * Defaults to WPA RSN. 315 */ 316 public BitSet allowedProtocols; 317 /** 318 * The set of authentication protocols supported by this configuration. 319 * See {@link AuthAlgorithm} for descriptions of the values. 320 * Defaults to automatic selection. 321 */ 322 public BitSet allowedAuthAlgorithms; 323 /** 324 * The set of pairwise ciphers for WPA supported by this configuration. 325 * See {@link PairwiseCipher} for descriptions of the values. 326 * Defaults to CCMP TKIP. 327 */ 328 public BitSet allowedPairwiseCiphers; 329 /** 330 * The set of group ciphers supported by this configuration. 331 * See {@link GroupCipher} for descriptions of the values. 332 * Defaults to CCMP TKIP WEP104 WEP40. 333 */ 334 public BitSet allowedGroupCiphers; 335 /** 336 * The enterprise configuration details specifying the EAP method, 337 * certificates and other settings associated with the EAP. 338 */ 339 public WifiEnterpriseConfig enterpriseConfig; 340 341 /** 342 * Fully qualified domain name of a passpoint configuration 343 */ 344 public String FQDN; 345 346 /** 347 * Name of passpoint credential provider 348 */ 349 public String providerFriendlyName; 350 351 /** 352 * Roaming Consortium Id list for passpoint credential; identifies a set of networks where 353 * passpoint credential will be considered valid 354 */ 355 public long[] roamingConsortiumIds; 356 357 /** 358 * @hide 359 */ 360 private IpConfiguration mIpConfiguration; 361 362 /** 363 * @hide 364 * dhcp server MAC address if known 365 */ 366 public String dhcpServer; 367 368 /** 369 * @hide 370 * default Gateway MAC address if known 371 */ 372 public String defaultGwMacAddress; 373 374 /** 375 * @hide 376 * last failure 377 */ 378 public String lastFailure; 379 380 /** 381 * @hide 382 * last time we connected, this configuration had validated internet access 383 */ 384 public boolean validatedInternetAccess; 385 386 /** 387 * @hide 388 * Uid of app creating the configuration 389 */ 390 @SystemApi 391 public int creatorUid; 392 393 /** 394 * @hide 395 * Uid of last app issuing a connection related command 396 */ 397 public int lastConnectUid; 398 399 /** 400 * @hide 401 * Uid of last app modifying the configuration 402 */ 403 @SystemApi 404 public int lastUpdateUid; 405 406 /** 407 * @hide 408 * Universal name for app creating the configuration 409 * see {#link {@link PackageManager#getNameForUid(int)} 410 */ 411 @SystemApi 412 public String creatorName; 413 414 /** 415 * @hide 416 * Universal name for app updating the configuration 417 * see {#link {@link PackageManager#getNameForUid(int)} 418 */ 419 @SystemApi 420 public String lastUpdateName; 421 422 /** 423 * @hide 424 * Uid used by autoJoin 425 */ 426 public String autoJoinBSSID; 427 428 /** 429 * @hide 430 * Status of user approval for connection 431 */ 432 public int userApproved = USER_UNSPECIFIED; 433 434 /** The Below RSSI thresholds are used to configure AutoJoin 435 * - GOOD/LOW/BAD thresholds are used so as to calculate link score 436 * - UNWANTED_SOFT are used by the blacklisting logic so as to handle 437 * the unwanted network message coming from CS 438 * - UNBLACKLIST thresholds are used so as to tweak the speed at which 439 * the network is unblacklisted (i.e. if 440 * it is seen with good RSSI, it is blacklisted faster) 441 * - INITIAL_AUTOJOIN_ATTEMPT, used to determine how close from 442 * the network we need to be before autojoin kicks in 443 */ 444 /** @hide **/ 445 public static int INVALID_RSSI = -127; 446 447 /** @hide **/ 448 public static int UNWANTED_BLACKLIST_SOFT_RSSI_24 = -80; 449 450 /** @hide **/ 451 public static int UNWANTED_BLACKLIST_SOFT_RSSI_5 = -70; 452 453 /** @hide **/ 454 public static int GOOD_RSSI_24 = -65; 455 456 /** @hide **/ 457 public static int LOW_RSSI_24 = -77; 458 459 /** @hide **/ 460 public static int BAD_RSSI_24 = -87; 461 462 /** @hide **/ 463 public static int GOOD_RSSI_5 = -60; 464 465 /** @hide **/ 466 public static int LOW_RSSI_5 = -72; 467 468 /** @hide **/ 469 public static int BAD_RSSI_5 = -82; 470 471 /** @hide **/ 472 public static int UNWANTED_BLACKLIST_SOFT_BUMP = 4; 473 474 /** @hide **/ 475 public static int UNWANTED_BLACKLIST_HARD_BUMP = 8; 476 477 /** @hide **/ 478 public static int UNBLACKLIST_THRESHOLD_24_SOFT = -77; 479 480 /** @hide **/ 481 public static int UNBLACKLIST_THRESHOLD_24_HARD = -68; 482 483 /** @hide **/ 484 public static int UNBLACKLIST_THRESHOLD_5_SOFT = -63; 485 486 /** @hide **/ 487 public static int UNBLACKLIST_THRESHOLD_5_HARD = -56; 488 489 /** @hide **/ 490 public static int INITIAL_AUTO_JOIN_ATTEMPT_MIN_24 = -80; 491 492 /** @hide **/ 493 public static int INITIAL_AUTO_JOIN_ATTEMPT_MIN_5 = -70; 494 495 /** @hide 496 * 5GHz band is prefered low over 2.4 if the 5GHz RSSI is higher than this threshold */ 497 public static int A_BAND_PREFERENCE_RSSI_THRESHOLD = -65; 498 499 /** @hide 500 * 5GHz band is penalized if the 5GHz RSSI is lower than this threshold **/ 501 public static int G_BAND_PREFERENCE_RSSI_THRESHOLD = -75; 502 503 /** @hide 504 * Boost given to RSSI on a home network for the purpose of calculating the score 505 * This adds stickiness to home networks, as defined by: 506 * - less than 4 known BSSIDs 507 * - PSK only 508 * - TODO: add a test to verify that all BSSIDs are behind same gateway 509 ***/ 510 public static int HOME_NETWORK_RSSI_BOOST = 5; 511 512 /** @hide 513 * RSSI boost for configuration which use autoJoinUseAggressiveJoinAttemptThreshold 514 * To be more aggressive when initially attempting to auto join 515 */ 516 public static int MAX_INITIAL_AUTO_JOIN_RSSI_BOOST = 8; 517 518 /** 519 * @hide 520 * A summary of the RSSI and Band status for that configuration 521 * This is used as a temporary value by the auto-join controller 522 */ 523 public static final class Visibility { 524 public int rssi5; // strongest 5GHz RSSI 525 public int rssi24; // strongest 2.4GHz RSSI 526 public int num5; // number of BSSIDs on 5GHz 527 public int num24; // number of BSSIDs on 2.4GHz 528 public long age5; // timestamp of the strongest 5GHz BSSID (last time it was seen) 529 public long age24; // timestamp of the strongest 2.4GHz BSSID (last time it was seen) 530 public String BSSID24; 531 public String BSSID5; 532 public int score; // Debug only, indicate last score used for autojoin/cell-handover 533 public int currentNetworkBoost; // Debug only, indicate boost applied to RSSI if current 534 public int bandPreferenceBoost; // Debug only, indicate boost applied to RSSI if current 535 public int lastChoiceBoost; // Debug only, indicate last choice applied to this configuration 536 public String lastChoiceConfig; // Debug only, indicate last choice applied to this configuration 537 538 public Visibility() { 539 rssi5 = INVALID_RSSI; 540 rssi24 = INVALID_RSSI; 541 } 542 543 public Visibility(Visibility source) { 544 rssi5 = source.rssi5; 545 rssi24 = source.rssi24; 546 age24 = source.age24; 547 age5 = source.age5; 548 num24 = source.num24; 549 num5 = source.num5; 550 BSSID5 = source.BSSID5; 551 BSSID24 = source.BSSID24; 552 } 553 554 @Override 555 public String toString() { 556 StringBuilder sbuf = new StringBuilder(); 557 sbuf.append("["); 558 if (rssi24 > INVALID_RSSI) { 559 sbuf.append(Integer.toString(rssi24)); 560 sbuf.append(","); 561 sbuf.append(Integer.toString(num24)); 562 if (BSSID24 != null) sbuf.append(",").append(BSSID24); 563 } 564 sbuf.append("; "); 565 if (rssi5 > INVALID_RSSI) { 566 sbuf.append(Integer.toString(rssi5)); 567 sbuf.append(","); 568 sbuf.append(Integer.toString(num5)); 569 if (BSSID5 != null) sbuf.append(",").append(BSSID5); 570 } 571 if (score != 0) { 572 sbuf.append("; ").append(score); 573 sbuf.append(", ").append(currentNetworkBoost); 574 sbuf.append(", ").append(bandPreferenceBoost); 575 if (lastChoiceConfig != null) { 576 sbuf.append(", ").append(lastChoiceBoost); 577 sbuf.append(", ").append(lastChoiceConfig); 578 } 579 } 580 sbuf.append("]"); 581 return sbuf.toString(); 582 } 583 } 584 585 /** @hide 586 * Cache the visibility status of this configuration. 587 * Visibility can change at any time depending on scan results availability. 588 * Owner of the WifiConfiguration is responsible to set this field based on 589 * recent scan results. 590 ***/ 591 public Visibility visibility; 592 593 /** @hide 594 * calculate and set Visibility for that configuration. 595 * 596 * age in milliseconds: we will consider only ScanResults that are more recent, 597 * i.e. younger. 598 ***/ 599 public void setVisibility(Visibility status) { 600 visibility = status; 601 } 602 603 /** @hide */ 604 public static final int AUTO_JOIN_ENABLED = 0; 605 /** 606 * if this is set, the WifiConfiguration cannot use linkages so as to bump 607 * it's relative priority. 608 * - status between and 128 indicate various level of blacklisting depending 609 * on the severity or frequency of the connection error 610 * - deleted status indicates that the user is deleting the configuration, and so 611 * although it may have been self added we will not re-self-add it, ignore it, 612 * not return it to applications, and not connect to it 613 * */ 614 615 /** @hide 616 * network was temporary disabled due to bad connection, most likely due 617 * to weak RSSI */ 618 public static final int AUTO_JOIN_TEMPORARY_DISABLED = 1; 619 /** @hide 620 * network was temporary disabled due to bad connection, which cant be attributed 621 * to weak RSSI */ 622 public static final int AUTO_JOIN_TEMPORARY_DISABLED_LINK_ERRORS = 32; 623 /** @hide */ 624 public static final int AUTO_JOIN_TEMPORARY_DISABLED_AT_SUPPLICANT = 64; 625 /** @hide */ 626 public static final int AUTO_JOIN_DISABLED_ON_AUTH_FAILURE = 128; 627 /** @hide */ 628 public static final int AUTO_JOIN_DISABLED_NO_CREDENTIALS = 160; 629 /** @hide */ 630 public static final int AUTO_JOIN_DISABLED_USER_ACTION = 161; 631 632 /** @hide */ 633 public static final int AUTO_JOIN_DELETED = 200; 634 635 // States for the userApproved field 636 /** 637 * @hide 638 * User hasn't specified if connection is okay 639 */ 640 public static final int USER_UNSPECIFIED = 0; 641 /** 642 * @hide 643 * User has approved this for connection 644 */ 645 public static final int USER_APPROVED = 1; 646 /** 647 * @hide 648 * User has banned this from connection 649 */ 650 public static final int USER_BANNED = 2; 651 /** 652 * @hide 653 * Waiting for user input 654 */ 655 public static final int USER_PENDING = 3; 656 657 /** 658 * @hide 659 */ 660 public int autoJoinStatus; 661 662 /** 663 * @hide 664 * Number of connection failures 665 */ 666 public int numConnectionFailures; 667 668 /** 669 * @hide 670 * Number of IP config failures 671 */ 672 public int numIpConfigFailures; 673 674 /** 675 * @hide 676 * Number of Auth failures 677 */ 678 public int numAuthFailures; 679 680 /** 681 * @hide 682 * Number of reports indicating no Internet Access 683 */ 684 public int numNoInternetAccessReports; 685 686 /** 687 * @hide 688 * For debug: date at which the config was last updated 689 */ 690 public String updateTime; 691 692 /** 693 * @hide 694 * For debug: date at which the config was last updated 695 */ 696 public String creationTime; 697 698 /** 699 * @hide 700 * The WiFi configuration is considered to have no internet access for purpose of autojoining 701 * if there has been a report of it having no internet access, and, it never have had 702 * internet access in the past. 703 */ 704 public boolean hasNoInternetAccess() { 705 return numNoInternetAccessReports > 0 && !validatedInternetAccess; 706 } 707 708 /** 709 * The WiFi configuration is expected not to have Internet access (e.g., a wireless printer, a 710 * Chromecast hotspot, etc.). This will be set if the user explicitly confirms a connection to 711 * this configuration and selects "don't ask again". 712 * @hide 713 */ 714 public boolean noInternetAccessExpected; 715 716 /** 717 * @hide 718 * Last time we blacklisted the configuration 719 */ 720 public long blackListTimestamp; 721 722 /** 723 * @hide 724 * Last time the system was connected to this configuration. 725 */ 726 public long lastConnected; 727 728 /** 729 * @hide 730 * Last time the system tried to connect and failed. 731 */ 732 public long lastConnectionFailure; 733 734 /** 735 * @hide 736 * Last time the system tried to roam and failed because of authentication failure or DHCP 737 * RENEW failure. 738 */ 739 public long lastRoamingFailure; 740 741 /** @hide */ 742 public static int ROAMING_FAILURE_IP_CONFIG = 1; 743 /** @hide */ 744 public static int ROAMING_FAILURE_AUTH_FAILURE = 2; 745 746 /** 747 * @hide 748 * Initial amount of time this Wifi configuration gets blacklisted for network switching 749 * because of roaming failure 750 */ 751 public long roamingFailureBlackListTimeMilli = 1000; 752 753 /** 754 * @hide 755 * Last roaming failure reason code 756 */ 757 public int lastRoamingFailureReason; 758 759 /** 760 * @hide 761 * Last time the system was disconnected to this configuration. 762 */ 763 public long lastDisconnected; 764 765 /** 766 * Set if the configuration was self added by the framework 767 * This boolean is cleared if we get a connect/save/ update or 768 * any wifiManager command that indicate the user interacted with the configuration 769 * since we will now consider that the configuration belong to him. 770 * @hide 771 */ 772 public boolean selfAdded; 773 774 /** 775 * Set if the configuration was self added by the framework 776 * This boolean is set once and never cleared. It is used 777 * so as we never loose track of who created the 778 * configuration in the first place. 779 * @hide 780 */ 781 public boolean didSelfAdd; 782 783 /** 784 * Peer WifiConfiguration this WifiConfiguration was added for 785 * @hide 786 */ 787 public String peerWifiConfiguration; 788 789 /** 790 * @hide 791 * Indicate that a WifiConfiguration is temporary and should not be saved 792 * nor considered by AutoJoin. 793 */ 794 public boolean ephemeral; 795 796 /** 797 * @hide 798 * Indicate that we didn't auto-join because rssi was too low 799 */ 800 public boolean autoJoinBailedDueToLowRssi; 801 802 /** 803 * @hide 804 * AutoJoin even though RSSI is 10dB below threshold 805 */ 806 public int autoJoinUseAggressiveJoinAttemptThreshold; 807 808 /** 809 * @hide 810 * Number of time the scorer overrode a the priority based choice, when comparing two 811 * WifiConfigurations, note that since comparing WifiConfiguration happens very often 812 * potentially at every scan, this number might become very large, even on an idle 813 * system. 814 */ 815 @SystemApi 816 public int numScorerOverride; 817 818 /** 819 * @hide 820 * Number of time the scorer overrode a the priority based choice, and the comparison 821 * triggered a network switch 822 */ 823 @SystemApi 824 public int numScorerOverrideAndSwitchedNetwork; 825 826 /** 827 * @hide 828 * Number of time we associated to this configuration. 829 */ 830 @SystemApi 831 public int numAssociation; 832 833 /** 834 * @hide 835 * Number of time user disabled WiFi while associated to this configuration with Low RSSI. 836 */ 837 public int numUserTriggeredWifiDisableLowRSSI; 838 839 /** 840 * @hide 841 * Number of time user disabled WiFi while associated to this configuration with Bad RSSI. 842 */ 843 public int numUserTriggeredWifiDisableBadRSSI; 844 845 /** 846 * @hide 847 * Number of time user disabled WiFi while associated to this configuration 848 * and RSSI was not HIGH. 849 */ 850 public int numUserTriggeredWifiDisableNotHighRSSI; 851 852 /** 853 * @hide 854 * Number of ticks associated to this configuration with Low RSSI. 855 */ 856 public int numTicksAtLowRSSI; 857 858 /** 859 * @hide 860 * Number of ticks associated to this configuration with Bad RSSI. 861 */ 862 public int numTicksAtBadRSSI; 863 864 /** 865 * @hide 866 * Number of ticks associated to this configuration 867 * and RSSI was not HIGH. 868 */ 869 public int numTicksAtNotHighRSSI; 870 /** 871 * @hide 872 * Number of time user (WifiManager) triggered association to this configuration. 873 * TODO: count this only for Wifi Settings uuid, so as to not count 3rd party apps 874 */ 875 public int numUserTriggeredJoinAttempts; 876 877 /** 878 * @hide 879 * Connect choices 880 * 881 * remember the keys identifying the known WifiConfiguration over which this configuration 882 * was preferred by user or a "WiFi Network Management app", that is, 883 * a WifiManager.CONNECT_NETWORK or SELECT_NETWORK was received while this configuration 884 * was visible to the user: 885 * configKey is : "SSID"-WEP-WPA_PSK-WPA_EAP 886 * 887 * The integer represents the configuration's RSSI at that time (useful?) 888 * 889 * The overall auto-join algorithm make use of past connect choice so as to sort configuration, 890 * the exact algorithm still fluctuating as of 5/7/2014 891 * 892 */ 893 public HashMap<String, Integer> connectChoices; 894 895 /** 896 * @hide 897 * Linked Configurations: represent the set of Wificonfigurations that are equivalent 898 * regarding roaming and auto-joining. 899 * The linked configuration may or may not have same SSID, and may or may not have same 900 * credentials. 901 * For instance, linked configurations will have same defaultGwMacAddress or same dhcp server. 902 */ 903 public HashMap<String, Integer> linkedConfigurations; 904 905 public WifiConfiguration() { 906 networkId = INVALID_NETWORK_ID; 907 SSID = null; 908 BSSID = null; 909 FQDN = null; 910 roamingConsortiumIds = new long[0]; 911 priority = 0; 912 hiddenSSID = false; 913 disableReason = DISABLED_UNKNOWN_REASON; 914 allowedKeyManagement = new BitSet(); 915 allowedProtocols = new BitSet(); 916 allowedAuthAlgorithms = new BitSet(); 917 allowedPairwiseCiphers = new BitSet(); 918 allowedGroupCiphers = new BitSet(); 919 wepKeys = new String[4]; 920 for (int i = 0; i < wepKeys.length; i++) { 921 wepKeys[i] = null; 922 } 923 enterpriseConfig = new WifiEnterpriseConfig(); 924 autoJoinStatus = AUTO_JOIN_ENABLED; 925 selfAdded = false; 926 didSelfAdd = false; 927 ephemeral = false; 928 validatedInternetAccess = false; 929 mIpConfiguration = new IpConfiguration(); 930 lastUpdateUid = -1; 931 creatorUid = -1; 932 } 933 934 /** 935 * Identify if this configuration represents a passpoint network 936 */ 937 public boolean isPasspoint() { 938 return !TextUtils.isEmpty(FQDN) 939 && !TextUtils.isEmpty(providerFriendlyName) 940 && enterpriseConfig != null 941 && enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE; 942 } 943 944 /** 945 * Helper function, identify if a configuration is linked 946 * @hide 947 */ 948 public boolean isLinked(WifiConfiguration config) { 949 if (config.linkedConfigurations != null && linkedConfigurations != null) { 950 if (config.linkedConfigurations.get(configKey()) != null 951 && linkedConfigurations.get(config.configKey()) != null) { 952 return true; 953 } 954 } 955 return false; 956 } 957 958 /** 959 * Helper function, idenfity if a configuration should be treated as an enterprise network 960 * @hide 961 */ 962 public boolean isEnterprise() { 963 return allowedKeyManagement.get(KeyMgmt.WPA_EAP) || 964 allowedKeyManagement.get(KeyMgmt.IEEE8021X); 965 } 966 967 /** @hide **/ 968 public void setAutoJoinStatus(int status) { 969 if (status < 0) status = 0; 970 if (status == 0) { 971 blackListTimestamp = 0; 972 } else if (status > autoJoinStatus) { 973 blackListTimestamp = System.currentTimeMillis(); 974 } 975 if (status != autoJoinStatus) { 976 autoJoinStatus = status; 977 dirty = true; 978 } 979 } 980 981 @Override 982 public String toString() { 983 StringBuilder sbuf = new StringBuilder(); 984 if (this.status == WifiConfiguration.Status.CURRENT) { 985 sbuf.append("* "); 986 } else if (this.status == WifiConfiguration.Status.DISABLED) { 987 sbuf.append("- DSBLE "); 988 } 989 sbuf.append("ID: ").append(this.networkId).append(" SSID: ").append(this.SSID). 990 append(" PROVIDER-NAME: ").append(this.providerFriendlyName). 991 append(" BSSID: ").append(this.BSSID).append(" FQDN: ").append(this.FQDN). 992 append(" PRIO: ").append(this.priority). 993 append('\n'); 994 if (this.numConnectionFailures > 0) { 995 sbuf.append(" numConnectFailures ").append(this.numConnectionFailures).append("\n"); 996 } 997 if (this.numIpConfigFailures > 0) { 998 sbuf.append(" numIpConfigFailures ").append(this.numIpConfigFailures).append("\n"); 999 } 1000 if (this.numAuthFailures > 0) { 1001 sbuf.append(" numAuthFailures ").append(this.numAuthFailures).append("\n"); 1002 } 1003 if (this.autoJoinStatus > 0) { 1004 sbuf.append(" autoJoinStatus ").append(this.autoJoinStatus).append("\n"); 1005 } 1006 if (this.disableReason > 0) { 1007 sbuf.append(" disableReason ").append(this.disableReason).append("\n"); 1008 } 1009 if (this.numAssociation > 0) { 1010 sbuf.append(" numAssociation ").append(this.numAssociation).append("\n"); 1011 } 1012 if (this.numNoInternetAccessReports > 0) { 1013 sbuf.append(" numNoInternetAccessReports "); 1014 sbuf.append(this.numNoInternetAccessReports).append("\n"); 1015 } 1016 if (this.updateTime != null) { 1017 sbuf.append("update ").append(this.updateTime).append("\n"); 1018 } 1019 if (this.creationTime != null) { 1020 sbuf.append("creation").append(this.creationTime).append("\n"); 1021 } 1022 if (this.didSelfAdd) sbuf.append(" didSelfAdd"); 1023 if (this.selfAdded) sbuf.append(" selfAdded"); 1024 if (this.validatedInternetAccess) sbuf.append(" validatedInternetAccess"); 1025 if (this.ephemeral) sbuf.append(" ephemeral"); 1026 if (this.didSelfAdd || this.selfAdded || this.validatedInternetAccess || this.ephemeral) { 1027 sbuf.append("\n"); 1028 } 1029 sbuf.append(" KeyMgmt:"); 1030 for (int k = 0; k < this.allowedKeyManagement.size(); k++) { 1031 if (this.allowedKeyManagement.get(k)) { 1032 sbuf.append(" "); 1033 if (k < KeyMgmt.strings.length) { 1034 sbuf.append(KeyMgmt.strings[k]); 1035 } else { 1036 sbuf.append("??"); 1037 } 1038 } 1039 } 1040 sbuf.append(" Protocols:"); 1041 for (int p = 0; p < this.allowedProtocols.size(); p++) { 1042 if (this.allowedProtocols.get(p)) { 1043 sbuf.append(" "); 1044 if (p < Protocol.strings.length) { 1045 sbuf.append(Protocol.strings[p]); 1046 } else { 1047 sbuf.append("??"); 1048 } 1049 } 1050 } 1051 sbuf.append('\n'); 1052 sbuf.append(" AuthAlgorithms:"); 1053 for (int a = 0; a < this.allowedAuthAlgorithms.size(); a++) { 1054 if (this.allowedAuthAlgorithms.get(a)) { 1055 sbuf.append(" "); 1056 if (a < AuthAlgorithm.strings.length) { 1057 sbuf.append(AuthAlgorithm.strings[a]); 1058 } else { 1059 sbuf.append("??"); 1060 } 1061 } 1062 } 1063 sbuf.append('\n'); 1064 sbuf.append(" PairwiseCiphers:"); 1065 for (int pc = 0; pc < this.allowedPairwiseCiphers.size(); pc++) { 1066 if (this.allowedPairwiseCiphers.get(pc)) { 1067 sbuf.append(" "); 1068 if (pc < PairwiseCipher.strings.length) { 1069 sbuf.append(PairwiseCipher.strings[pc]); 1070 } else { 1071 sbuf.append("??"); 1072 } 1073 } 1074 } 1075 sbuf.append('\n'); 1076 sbuf.append(" GroupCiphers:"); 1077 for (int gc = 0; gc < this.allowedGroupCiphers.size(); gc++) { 1078 if (this.allowedGroupCiphers.get(gc)) { 1079 sbuf.append(" "); 1080 if (gc < GroupCipher.strings.length) { 1081 sbuf.append(GroupCipher.strings[gc]); 1082 } else { 1083 sbuf.append("??"); 1084 } 1085 } 1086 } 1087 sbuf.append('\n').append(" PSK: "); 1088 if (this.preSharedKey != null) { 1089 sbuf.append('*'); 1090 } 1091 sbuf.append("\nEnterprise config:\n"); 1092 sbuf.append(enterpriseConfig); 1093 1094 sbuf.append("IP config:\n"); 1095 sbuf.append(mIpConfiguration.toString()); 1096 1097 if (this.autoJoinBSSID != null) sbuf.append(" autoJoinBSSID=" + autoJoinBSSID); 1098 long now_ms = System.currentTimeMillis(); 1099 if (this.blackListTimestamp != 0) { 1100 sbuf.append('\n'); 1101 long diff = now_ms - this.blackListTimestamp; 1102 if (diff <= 0) { 1103 sbuf.append(" blackListed since <incorrect>"); 1104 } else { 1105 sbuf.append(" blackListed: ").append(Long.toString(diff/1000)).append( "sec "); 1106 } 1107 } 1108 if (creatorUid != 0) sbuf.append(" cuid=" + Integer.toString(creatorUid)); 1109 if (creatorName != null) sbuf.append(" cname=" + creatorName); 1110 if (lastUpdateUid != 0) sbuf.append(" luid=" + lastUpdateUid); 1111 if (lastUpdateName != null) sbuf.append(" lname=" + lastUpdateName); 1112 sbuf.append(" lcuid=" + lastConnectUid); 1113 sbuf.append(" userApproved=" + userApprovedAsString(userApproved)); 1114 sbuf.append(" noInternetAccessExpected=" + noInternetAccessExpected); 1115 sbuf.append(" "); 1116 1117 if (this.lastConnected != 0) { 1118 sbuf.append('\n'); 1119 long diff = now_ms - this.lastConnected; 1120 if (diff <= 0) { 1121 sbuf.append("lastConnected since <incorrect>"); 1122 } else { 1123 sbuf.append("lastConnected: ").append(Long.toString(diff/1000)).append( "sec "); 1124 } 1125 } 1126 if (this.lastConnectionFailure != 0) { 1127 sbuf.append('\n'); 1128 long diff = now_ms - this.lastConnectionFailure; 1129 if (diff <= 0) { 1130 sbuf.append("lastConnectionFailure since <incorrect> "); 1131 } else { 1132 sbuf.append("lastConnectionFailure: ").append(Long.toString(diff/1000)); 1133 sbuf.append( "sec "); 1134 } 1135 } 1136 if (this.lastRoamingFailure != 0) { 1137 sbuf.append('\n'); 1138 long diff = now_ms - this.lastRoamingFailure; 1139 if (diff <= 0) { 1140 sbuf.append("lastRoamingFailure since <incorrect> "); 1141 } else { 1142 sbuf.append("lastRoamingFailure: ").append(Long.toString(diff/1000)); 1143 sbuf.append( "sec "); 1144 } 1145 } 1146 sbuf.append("roamingFailureBlackListTimeMilli: "). 1147 append(Long.toString(this.roamingFailureBlackListTimeMilli)); 1148 sbuf.append('\n'); 1149 if (this.linkedConfigurations != null) { 1150 for(String key : this.linkedConfigurations.keySet()) { 1151 sbuf.append(" linked: ").append(key); 1152 sbuf.append('\n'); 1153 } 1154 } 1155 if (this.connectChoices != null) { 1156 for(String key : this.connectChoices.keySet()) { 1157 Integer choice = this.connectChoices.get(key); 1158 if (choice != null) { 1159 sbuf.append(" choice: ").append(key); 1160 sbuf.append(" = ").append(choice); 1161 sbuf.append('\n'); 1162 } 1163 } 1164 } 1165 sbuf.append("triggeredLow: ").append(this.numUserTriggeredWifiDisableLowRSSI); 1166 sbuf.append(" triggeredBad: ").append(this.numUserTriggeredWifiDisableBadRSSI); 1167 sbuf.append(" triggeredNotHigh: ").append(this.numUserTriggeredWifiDisableNotHighRSSI); 1168 sbuf.append('\n'); 1169 sbuf.append("ticksLow: ").append(this.numTicksAtLowRSSI); 1170 sbuf.append(" ticksBad: ").append(this.numTicksAtBadRSSI); 1171 sbuf.append(" ticksNotHigh: ").append(this.numTicksAtNotHighRSSI); 1172 sbuf.append('\n'); 1173 sbuf.append("triggeredJoin: ").append(this.numUserTriggeredJoinAttempts); 1174 sbuf.append('\n'); 1175 sbuf.append("autoJoinBailedDueToLowRssi: ").append(this.autoJoinBailedDueToLowRssi); 1176 sbuf.append('\n'); 1177 sbuf.append("autoJoinUseAggressiveJoinAttemptThreshold: "); 1178 sbuf.append(this.autoJoinUseAggressiveJoinAttemptThreshold); 1179 sbuf.append('\n'); 1180 1181 return sbuf.toString(); 1182 } 1183 1184 /** 1185 * Construct a WifiConfiguration from a scanned network 1186 * @param scannedAP the scan result used to construct the config entry 1187 * TODO: figure out whether this is a useful way to construct a new entry. 1188 * 1189 public WifiConfiguration(ScanResult scannedAP) { 1190 networkId = -1; 1191 SSID = scannedAP.SSID; 1192 BSSID = scannedAP.BSSID; 1193 } 1194 */ 1195 1196 /** {@hide} */ 1197 public String getPrintableSsid() { 1198 if (SSID == null) return ""; 1199 final int length = SSID.length(); 1200 if (length > 2 && (SSID.charAt(0) == '"') && SSID.charAt(length - 1) == '"') { 1201 return SSID.substring(1, length - 1); 1202 } 1203 1204 /** The ascii-encoded string format is P"<ascii-encoded-string>" 1205 * The decoding is implemented in the supplicant for a newly configured 1206 * network. 1207 */ 1208 if (length > 3 && (SSID.charAt(0) == 'P') && (SSID.charAt(1) == '"') && 1209 (SSID.charAt(length-1) == '"')) { 1210 WifiSsid wifiSsid = WifiSsid.createFromAsciiEncoded( 1211 SSID.substring(2, length - 1)); 1212 return wifiSsid.toString(); 1213 } 1214 return SSID; 1215 } 1216 1217 /** @hide **/ 1218 public static String userApprovedAsString(int userApproved) { 1219 switch (userApproved) { 1220 case USER_APPROVED: 1221 return "USER_APPROVED"; 1222 case USER_BANNED: 1223 return "USER_BANNED"; 1224 case USER_UNSPECIFIED: 1225 return "USER_UNSPECIFIED"; 1226 default: 1227 return "INVALID"; 1228 } 1229 } 1230 1231 /** 1232 * Get an identifier for associating credentials with this config 1233 * @param current configuration contains values for additional fields 1234 * that are not part of this configuration. Used 1235 * when a config with some fields is passed by an application. 1236 * @throws IllegalStateException if config is invalid for key id generation 1237 * @hide 1238 */ 1239 public String getKeyIdForCredentials(WifiConfiguration current) { 1240 String keyMgmt = null; 1241 1242 try { 1243 // Get current config details for fields that are not initialized 1244 if (TextUtils.isEmpty(SSID)) SSID = current.SSID; 1245 if (allowedKeyManagement.cardinality() == 0) { 1246 allowedKeyManagement = current.allowedKeyManagement; 1247 } 1248 if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) { 1249 keyMgmt = KeyMgmt.strings[KeyMgmt.WPA_EAP]; 1250 } 1251 if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) { 1252 keyMgmt += KeyMgmt.strings[KeyMgmt.IEEE8021X]; 1253 } 1254 1255 if (TextUtils.isEmpty(keyMgmt)) { 1256 throw new IllegalStateException("Not an EAP network"); 1257 } 1258 1259 return trimStringForKeyId(SSID) + "_" + keyMgmt + "_" + 1260 trimStringForKeyId(enterpriseConfig.getKeyId(current != null ? 1261 current.enterpriseConfig : null)); 1262 } catch (NullPointerException e) { 1263 throw new IllegalStateException("Invalid config details"); 1264 } 1265 } 1266 1267 private String trimStringForKeyId(String string) { 1268 // Remove quotes and spaces 1269 return string.replace("\"", "").replace(" ", ""); 1270 } 1271 1272 private static BitSet readBitSet(Parcel src) { 1273 int cardinality = src.readInt(); 1274 1275 BitSet set = new BitSet(); 1276 for (int i = 0; i < cardinality; i++) { 1277 set.set(src.readInt()); 1278 } 1279 1280 return set; 1281 } 1282 1283 private static void writeBitSet(Parcel dest, BitSet set) { 1284 int nextSetBit = -1; 1285 1286 dest.writeInt(set.cardinality()); 1287 1288 while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1) { 1289 dest.writeInt(nextSetBit); 1290 } 1291 } 1292 1293 /** @hide */ 1294 public int getAuthType() { 1295 if (allowedKeyManagement.cardinality() > 1) { 1296 throw new IllegalStateException("More than one auth type set"); 1297 } 1298 if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) { 1299 return KeyMgmt.WPA_PSK; 1300 } else if (allowedKeyManagement.get(KeyMgmt.WPA2_PSK)) { 1301 return KeyMgmt.WPA2_PSK; 1302 } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) { 1303 return KeyMgmt.WPA_EAP; 1304 } else if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) { 1305 return KeyMgmt.IEEE8021X; 1306 } 1307 return KeyMgmt.NONE; 1308 } 1309 1310 /* @hide 1311 * Cache the config key, this seems useful as a speed up since a lot of 1312 * lookups in the config store are done and based on this key. 1313 */ 1314 String mCachedConfigKey; 1315 1316 /** @hide 1317 * return the string used to calculate the hash in WifiConfigStore 1318 * and uniquely identify this WifiConfiguration 1319 */ 1320 public String configKey(boolean allowCached) { 1321 String key; 1322 if (allowCached && mCachedConfigKey != null) { 1323 key = mCachedConfigKey; 1324 } else if (providerFriendlyName != null) { 1325 key = FQDN + KeyMgmt.strings[KeyMgmt.WPA_EAP]; 1326 } else { 1327 if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) { 1328 key = SSID + KeyMgmt.strings[KeyMgmt.WPA_PSK]; 1329 } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP) || 1330 allowedKeyManagement.get(KeyMgmt.IEEE8021X)) { 1331 key = SSID + KeyMgmt.strings[KeyMgmt.WPA_EAP]; 1332 } else if (wepKeys[0] != null) { 1333 key = SSID + "WEP"; 1334 } else { 1335 key = SSID + KeyMgmt.strings[KeyMgmt.NONE]; 1336 } 1337 mCachedConfigKey = key; 1338 } 1339 return key; 1340 } 1341 1342 /** @hide 1343 * get configKey, force calculating the config string 1344 */ 1345 public String configKey() { 1346 return configKey(false); 1347 } 1348 1349 /** @hide 1350 * return the config key string based on a scan result 1351 */ 1352 static public String configKey(ScanResult result) { 1353 String key = "\"" + result.SSID + "\""; 1354 1355 if (result.capabilities.contains("WEP")) { 1356 key = key + "-WEP"; 1357 } 1358 1359 if (result.capabilities.contains("PSK")) { 1360 key = key + "-" + KeyMgmt.strings[KeyMgmt.WPA_PSK]; 1361 } 1362 1363 if (result.capabilities.contains("EAP")) { 1364 key = key + "-" + KeyMgmt.strings[KeyMgmt.WPA_EAP]; 1365 } 1366 1367 return key; 1368 } 1369 1370 /** @hide */ 1371 public IpConfiguration getIpConfiguration() { 1372 return mIpConfiguration; 1373 } 1374 1375 /** @hide */ 1376 public void setIpConfiguration(IpConfiguration ipConfiguration) { 1377 mIpConfiguration = ipConfiguration; 1378 } 1379 1380 /** @hide */ 1381 public StaticIpConfiguration getStaticIpConfiguration() { 1382 return mIpConfiguration.getStaticIpConfiguration(); 1383 } 1384 1385 /** @hide */ 1386 public void setStaticIpConfiguration(StaticIpConfiguration staticIpConfiguration) { 1387 mIpConfiguration.setStaticIpConfiguration(staticIpConfiguration); 1388 } 1389 1390 /** @hide */ 1391 public IpConfiguration.IpAssignment getIpAssignment() { 1392 return mIpConfiguration.ipAssignment; 1393 } 1394 1395 /** @hide */ 1396 public void setIpAssignment(IpConfiguration.IpAssignment ipAssignment) { 1397 mIpConfiguration.ipAssignment = ipAssignment; 1398 } 1399 1400 /** @hide */ 1401 public IpConfiguration.ProxySettings getProxySettings() { 1402 return mIpConfiguration.proxySettings; 1403 } 1404 1405 /** @hide */ 1406 public void setProxySettings(IpConfiguration.ProxySettings proxySettings) { 1407 mIpConfiguration.proxySettings = proxySettings; 1408 } 1409 1410 /** @hide */ 1411 public ProxyInfo getHttpProxy() { 1412 return mIpConfiguration.httpProxy; 1413 } 1414 1415 /** @hide */ 1416 public void setHttpProxy(ProxyInfo httpProxy) { 1417 mIpConfiguration.httpProxy = httpProxy; 1418 } 1419 1420 /** @hide */ 1421 public void setProxy(ProxySettings settings, ProxyInfo proxy) { 1422 mIpConfiguration.proxySettings = settings; 1423 mIpConfiguration.httpProxy = proxy; 1424 } 1425 1426 /** Implement the Parcelable interface {@hide} */ 1427 public int describeContents() { 1428 return 0; 1429 } 1430 1431 /** copy constructor {@hide} */ 1432 public WifiConfiguration(WifiConfiguration source) { 1433 if (source != null) { 1434 networkId = source.networkId; 1435 status = source.status; 1436 disableReason = source.disableReason; 1437 disableReason = source.disableReason; 1438 SSID = source.SSID; 1439 BSSID = source.BSSID; 1440 FQDN = source.FQDN; 1441 roamingConsortiumIds = source.roamingConsortiumIds.clone(); 1442 providerFriendlyName = source.providerFriendlyName; 1443 preSharedKey = source.preSharedKey; 1444 1445 apBand = source.apBand; 1446 apChannel = source.apChannel; 1447 1448 wepKeys = new String[4]; 1449 for (int i = 0; i < wepKeys.length; i++) { 1450 wepKeys[i] = source.wepKeys[i]; 1451 } 1452 1453 wepTxKeyIndex = source.wepTxKeyIndex; 1454 priority = source.priority; 1455 hiddenSSID = source.hiddenSSID; 1456 allowedKeyManagement = (BitSet) source.allowedKeyManagement.clone(); 1457 allowedProtocols = (BitSet) source.allowedProtocols.clone(); 1458 allowedAuthAlgorithms = (BitSet) source.allowedAuthAlgorithms.clone(); 1459 allowedPairwiseCiphers = (BitSet) source.allowedPairwiseCiphers.clone(); 1460 allowedGroupCiphers = (BitSet) source.allowedGroupCiphers.clone(); 1461 1462 enterpriseConfig = new WifiEnterpriseConfig(source.enterpriseConfig); 1463 1464 defaultGwMacAddress = source.defaultGwMacAddress; 1465 1466 mIpConfiguration = new IpConfiguration(source.mIpConfiguration); 1467 1468 if ((source.connectChoices != null) && (source.connectChoices.size() > 0)) { 1469 connectChoices = new HashMap<String, Integer>(); 1470 connectChoices.putAll(source.connectChoices); 1471 } 1472 1473 if ((source.linkedConfigurations != null) 1474 && (source.linkedConfigurations.size() > 0)) { 1475 linkedConfigurations = new HashMap<String, Integer>(); 1476 linkedConfigurations.putAll(source.linkedConfigurations); 1477 } 1478 mCachedConfigKey = null; //force null configKey 1479 autoJoinStatus = source.autoJoinStatus; 1480 selfAdded = source.selfAdded; 1481 validatedInternetAccess = source.validatedInternetAccess; 1482 ephemeral = source.ephemeral; 1483 if (source.visibility != null) { 1484 visibility = new Visibility(source.visibility); 1485 } 1486 1487 lastFailure = source.lastFailure; 1488 didSelfAdd = source.didSelfAdd; 1489 lastConnectUid = source.lastConnectUid; 1490 lastUpdateUid = source.lastUpdateUid; 1491 creatorUid = source.creatorUid; 1492 creatorName = source.creatorName; 1493 lastUpdateName = source.lastUpdateName; 1494 peerWifiConfiguration = source.peerWifiConfiguration; 1495 blackListTimestamp = source.blackListTimestamp; 1496 lastConnected = source.lastConnected; 1497 lastDisconnected = source.lastDisconnected; 1498 lastConnectionFailure = source.lastConnectionFailure; 1499 lastRoamingFailure = source.lastRoamingFailure; 1500 lastRoamingFailureReason = source.lastRoamingFailureReason; 1501 roamingFailureBlackListTimeMilli = source.roamingFailureBlackListTimeMilli; 1502 numConnectionFailures = source.numConnectionFailures; 1503 numIpConfigFailures = source.numIpConfigFailures; 1504 numAuthFailures = source.numAuthFailures; 1505 numScorerOverride = source.numScorerOverride; 1506 numScorerOverrideAndSwitchedNetwork = source.numScorerOverrideAndSwitchedNetwork; 1507 numAssociation = source.numAssociation; 1508 numUserTriggeredWifiDisableLowRSSI = source.numUserTriggeredWifiDisableLowRSSI; 1509 numUserTriggeredWifiDisableBadRSSI = source.numUserTriggeredWifiDisableBadRSSI; 1510 numUserTriggeredWifiDisableNotHighRSSI = source.numUserTriggeredWifiDisableNotHighRSSI; 1511 numTicksAtLowRSSI = source.numTicksAtLowRSSI; 1512 numTicksAtBadRSSI = source.numTicksAtBadRSSI; 1513 numTicksAtNotHighRSSI = source.numTicksAtNotHighRSSI; 1514 numUserTriggeredJoinAttempts = source.numUserTriggeredJoinAttempts; 1515 autoJoinBSSID = source.autoJoinBSSID; 1516 autoJoinUseAggressiveJoinAttemptThreshold 1517 = source.autoJoinUseAggressiveJoinAttemptThreshold; 1518 autoJoinBailedDueToLowRssi = source.autoJoinBailedDueToLowRssi; 1519 dirty = source.dirty; 1520 userApproved = source.userApproved; 1521 numNoInternetAccessReports = source.numNoInternetAccessReports; 1522 noInternetAccessExpected = source.noInternetAccessExpected; 1523 creationTime = source.creationTime; 1524 updateTime = source.updateTime; 1525 } 1526 } 1527 1528 /** {@hide} */ 1529 //public static final int NOTHING_TAG = 0; 1530 /** {@hide} */ 1531 //public static final int SCAN_CACHE_TAG = 1; 1532 1533 /** Implement the Parcelable interface {@hide} */ 1534 @Override 1535 public void writeToParcel(Parcel dest, int flags) { 1536 dest.writeInt(networkId); 1537 dest.writeInt(status); 1538 dest.writeInt(disableReason); 1539 dest.writeString(SSID); 1540 dest.writeString(BSSID); 1541 dest.writeInt(apBand); 1542 dest.writeInt(apChannel); 1543 dest.writeString(autoJoinBSSID); 1544 dest.writeString(FQDN); 1545 dest.writeString(providerFriendlyName); 1546 dest.writeInt(roamingConsortiumIds.length); 1547 for (long roamingConsortiumId : roamingConsortiumIds) { 1548 dest.writeLong(roamingConsortiumId); 1549 } 1550 dest.writeString(preSharedKey); 1551 for (String wepKey : wepKeys) { 1552 dest.writeString(wepKey); 1553 } 1554 dest.writeInt(wepTxKeyIndex); 1555 dest.writeInt(priority); 1556 dest.writeInt(hiddenSSID ? 1 : 0); 1557 dest.writeInt(requirePMF ? 1 : 0); 1558 dest.writeString(updateIdentifier); 1559 1560 writeBitSet(dest, allowedKeyManagement); 1561 writeBitSet(dest, allowedProtocols); 1562 writeBitSet(dest, allowedAuthAlgorithms); 1563 writeBitSet(dest, allowedPairwiseCiphers); 1564 writeBitSet(dest, allowedGroupCiphers); 1565 1566 dest.writeParcelable(enterpriseConfig, flags); 1567 1568 dest.writeParcelable(mIpConfiguration, flags); 1569 dest.writeString(dhcpServer); 1570 dest.writeString(defaultGwMacAddress); 1571 dest.writeInt(autoJoinStatus); 1572 dest.writeInt(selfAdded ? 1 : 0); 1573 dest.writeInt(didSelfAdd ? 1 : 0); 1574 dest.writeInt(validatedInternetAccess ? 1 : 0); 1575 dest.writeInt(ephemeral ? 1 : 0); 1576 dest.writeInt(creatorUid); 1577 dest.writeInt(lastConnectUid); 1578 dest.writeInt(lastUpdateUid); 1579 dest.writeString(creatorName); 1580 dest.writeString(lastUpdateName); 1581 dest.writeLong(blackListTimestamp); 1582 dest.writeLong(lastConnectionFailure); 1583 dest.writeLong(lastRoamingFailure); 1584 dest.writeInt(lastRoamingFailureReason); 1585 dest.writeLong(roamingFailureBlackListTimeMilli); 1586 dest.writeInt(numConnectionFailures); 1587 dest.writeInt(numIpConfigFailures); 1588 dest.writeInt(numAuthFailures); 1589 dest.writeInt(numScorerOverride); 1590 dest.writeInt(numScorerOverrideAndSwitchedNetwork); 1591 dest.writeInt(numAssociation); 1592 dest.writeInt(numUserTriggeredWifiDisableLowRSSI); 1593 dest.writeInt(numUserTriggeredWifiDisableBadRSSI); 1594 dest.writeInt(numUserTriggeredWifiDisableNotHighRSSI); 1595 dest.writeInt(numTicksAtLowRSSI); 1596 dest.writeInt(numTicksAtBadRSSI); 1597 dest.writeInt(numTicksAtNotHighRSSI); 1598 dest.writeInt(numUserTriggeredJoinAttempts); 1599 dest.writeInt(autoJoinUseAggressiveJoinAttemptThreshold); 1600 dest.writeInt(autoJoinBailedDueToLowRssi ? 1 : 0); 1601 dest.writeInt(userApproved); 1602 dest.writeInt(numNoInternetAccessReports); 1603 dest.writeInt(noInternetAccessExpected ? 1 : 0); 1604 } 1605 1606 /** Implement the Parcelable interface {@hide} */ 1607 public static final Creator<WifiConfiguration> CREATOR = 1608 new Creator<WifiConfiguration>() { 1609 public WifiConfiguration createFromParcel(Parcel in) { 1610 WifiConfiguration config = new WifiConfiguration(); 1611 config.networkId = in.readInt(); 1612 config.status = in.readInt(); 1613 config.disableReason = in.readInt(); 1614 config.SSID = in.readString(); 1615 config.BSSID = in.readString(); 1616 config.apBand = in.readInt(); 1617 config.apChannel = in.readInt(); 1618 config.autoJoinBSSID = in.readString(); 1619 config.FQDN = in.readString(); 1620 config.providerFriendlyName = in.readString(); 1621 int numRoamingConsortiumIds = in.readInt(); 1622 config.roamingConsortiumIds = new long[numRoamingConsortiumIds]; 1623 for (int i = 0; i < numRoamingConsortiumIds; i++) { 1624 config.roamingConsortiumIds[i] = in.readLong(); 1625 } 1626 config.preSharedKey = in.readString(); 1627 for (int i = 0; i < config.wepKeys.length; i++) { 1628 config.wepKeys[i] = in.readString(); 1629 } 1630 config.wepTxKeyIndex = in.readInt(); 1631 config.priority = in.readInt(); 1632 config.hiddenSSID = in.readInt() != 0; 1633 config.requirePMF = in.readInt() != 0; 1634 config.updateIdentifier = in.readString(); 1635 1636 config.allowedKeyManagement = readBitSet(in); 1637 config.allowedProtocols = readBitSet(in); 1638 config.allowedAuthAlgorithms = readBitSet(in); 1639 config.allowedPairwiseCiphers = readBitSet(in); 1640 config.allowedGroupCiphers = readBitSet(in); 1641 1642 config.enterpriseConfig = in.readParcelable(null); 1643 1644 config.mIpConfiguration = in.readParcelable(null); 1645 config.dhcpServer = in.readString(); 1646 config.defaultGwMacAddress = in.readString(); 1647 config.autoJoinStatus = in.readInt(); 1648 config.selfAdded = in.readInt() != 0; 1649 config.didSelfAdd = in.readInt() != 0; 1650 config.validatedInternetAccess = in.readInt() != 0; 1651 config.ephemeral = in.readInt() != 0; 1652 config.creatorUid = in.readInt(); 1653 config.lastConnectUid = in.readInt(); 1654 config.lastUpdateUid = in.readInt(); 1655 config.creatorName = in.readString(); 1656 config.lastUpdateName = in.readString(); 1657 config.blackListTimestamp = in.readLong(); 1658 config.lastConnectionFailure = in.readLong(); 1659 config.lastRoamingFailure = in.readLong(); 1660 config.lastRoamingFailureReason = in.readInt(); 1661 config.roamingFailureBlackListTimeMilli = in.readLong(); 1662 config.numConnectionFailures = in.readInt(); 1663 config.numIpConfigFailures = in.readInt(); 1664 config.numAuthFailures = in.readInt(); 1665 config.numScorerOverride = in.readInt(); 1666 config.numScorerOverrideAndSwitchedNetwork = in.readInt(); 1667 config.numAssociation = in.readInt(); 1668 config.numUserTriggeredWifiDisableLowRSSI = in.readInt(); 1669 config.numUserTriggeredWifiDisableBadRSSI = in.readInt(); 1670 config.numUserTriggeredWifiDisableNotHighRSSI = in.readInt(); 1671 config.numTicksAtLowRSSI = in.readInt(); 1672 config.numTicksAtBadRSSI = in.readInt(); 1673 config.numTicksAtNotHighRSSI = in.readInt(); 1674 config.numUserTriggeredJoinAttempts = in.readInt(); 1675 config.autoJoinUseAggressiveJoinAttemptThreshold = in.readInt(); 1676 config.autoJoinBailedDueToLowRssi = in.readInt() != 0; 1677 config.userApproved = in.readInt(); 1678 config.numNoInternetAccessReports = in.readInt(); 1679 config.noInternetAccessExpected = in.readInt() != 0; 1680 return config; 1681 } 1682 1683 public WifiConfiguration[] newArray(int size) { 1684 return new WifiConfiguration[size]; 1685 } 1686 }; 1687 } 1688