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.IntRange; 20 import android.annotation.Nullable; 21 import android.annotation.SystemApi; 22 import android.compat.annotation.UnsupportedAppUsage; 23 import android.net.NetworkInfo.DetailedState; 24 import android.net.NetworkUtils; 25 import android.os.Build; 26 import android.os.Parcel; 27 import android.os.Parcelable; 28 import android.text.TextUtils; 29 30 import java.net.Inet4Address; 31 import java.net.InetAddress; 32 import java.net.UnknownHostException; 33 import java.util.EnumMap; 34 import java.util.Locale; 35 36 /** 37 * Describes the state of any Wifi connection that is active or 38 * is in the process of being set up. 39 */ 40 public class WifiInfo implements Parcelable { 41 private static final String TAG = "WifiInfo"; 42 /** 43 * This is the map described in the Javadoc comment above. The positions 44 * of the elements of the array must correspond to the ordinal values 45 * of <code>DetailedState</code>. 46 */ 47 private static final EnumMap<SupplicantState, DetailedState> stateMap = 48 new EnumMap<SupplicantState, DetailedState>(SupplicantState.class); 49 50 /** 51 * Default MAC address reported to a client that does not have the 52 * android.permission.LOCAL_MAC_ADDRESS permission. 53 * 54 * @hide 55 */ 56 @UnsupportedAppUsage 57 public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00"; 58 59 static { stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED)60 stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED); stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED)61 stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED); stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE)62 stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE); stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING)63 stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING); stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING)64 stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING); stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING)65 stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING); stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING)66 stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING); stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING)67 stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING); stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING)68 stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING); stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR)69 stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR); stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED)70 stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED); stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE)71 stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE); stateMap.put(SupplicantState.INVALID, DetailedState.FAILED)72 stateMap.put(SupplicantState.INVALID, DetailedState.FAILED); 73 } 74 75 private SupplicantState mSupplicantState; 76 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 77 private String mBSSID; 78 @UnsupportedAppUsage 79 private WifiSsid mWifiSsid; 80 private int mNetworkId; 81 82 /** @hide **/ 83 @UnsupportedAppUsage 84 public static final int INVALID_RSSI = -127; 85 86 /** @hide **/ 87 public static final int MIN_RSSI = -126; 88 89 /** @hide **/ 90 public static final int MAX_RSSI = 200; 91 92 93 /** 94 * Received Signal Strength Indicator 95 */ 96 private int mRssi; 97 98 /** 99 * The unit in which links speeds are expressed. 100 */ 101 public static final String LINK_SPEED_UNITS = "Mbps"; 102 private int mLinkSpeed; 103 104 /** 105 * Constant for unknown link speed. 106 */ 107 public static final int LINK_SPEED_UNKNOWN = -1; 108 109 /** 110 * Tx(transmit) Link speed in Mbps 111 */ 112 private int mTxLinkSpeed; 113 114 /** 115 * Rx(receive) Link speed in Mbps 116 */ 117 private int mRxLinkSpeed; 118 119 /** 120 * Frequency in MHz 121 */ 122 public static final String FREQUENCY_UNITS = "MHz"; 123 private int mFrequency; 124 125 @UnsupportedAppUsage 126 private InetAddress mIpAddress; 127 @UnsupportedAppUsage 128 private String mMacAddress = DEFAULT_MAC_ADDRESS; 129 130 /** 131 * Whether the network is ephemeral or not. 132 */ 133 private boolean mEphemeral; 134 135 /** 136 * Whether the network is trusted or not. 137 */ 138 private boolean mTrusted; 139 140 /** 141 * OSU (Online Sign Up) AP for Passpoint R2. 142 */ 143 private boolean mOsuAp; 144 145 /** 146 * Fully qualified domain name of a Passpoint configuration 147 */ 148 private String mFqdn; 149 150 /** 151 * Name of Passpoint credential provider 152 */ 153 private String mProviderFriendlyName; 154 155 /** 156 * If connected to a network suggestion or specifier, store the package name of the app, 157 * else null. 158 */ 159 private String mNetworkSuggestionOrSpecifierPackageName; 160 161 /** 162 * Running total count of lost (not ACKed) transmitted unicast data packets. 163 * @hide 164 */ 165 public long txBad; 166 /** 167 * Running total count of transmitted unicast data retry packets. 168 * @hide 169 */ 170 public long txRetries; 171 /** 172 * Running total count of successfully transmitted (ACKed) unicast data packets. 173 * @hide 174 */ 175 public long txSuccess; 176 /** 177 * Running total count of received unicast data packets. 178 * @hide 179 */ 180 public long rxSuccess; 181 182 /** 183 * Average rate of lost transmitted packets, in units of packets per second. 184 * @hide 185 */ 186 public double txBadRate; 187 /** 188 * Average rate of transmitted retry packets, in units of packets per second. 189 * @hide 190 */ 191 public double txRetriesRate; 192 /** 193 * Average rate of successfully transmitted unicast packets, in units of packets per second. 194 * @hide 195 */ 196 public double txSuccessRate; 197 /** 198 * Average rate of received unicast data packets, in units of packets per second. 199 * @hide 200 */ 201 public double rxSuccessRate; 202 203 /** 204 * @hide 205 */ 206 @UnsupportedAppUsage 207 public int score; 208 209 /** 210 * Flag indicating that AP has hinted that upstream connection is metered, 211 * and sensitive to heavy data transfers. 212 */ 213 private boolean mMeteredHint; 214 215 /** @hide */ 216 @UnsupportedAppUsage WifiInfo()217 public WifiInfo() { 218 mWifiSsid = null; 219 mBSSID = null; 220 mNetworkId = -1; 221 mSupplicantState = SupplicantState.UNINITIALIZED; 222 mRssi = INVALID_RSSI; 223 mLinkSpeed = LINK_SPEED_UNKNOWN; 224 mFrequency = -1; 225 } 226 227 /** @hide */ reset()228 public void reset() { 229 setInetAddress(null); 230 setBSSID(null); 231 setSSID(null); 232 setNetworkId(-1); 233 setRssi(INVALID_RSSI); 234 setLinkSpeed(LINK_SPEED_UNKNOWN); 235 setTxLinkSpeedMbps(LINK_SPEED_UNKNOWN); 236 setRxLinkSpeedMbps(LINK_SPEED_UNKNOWN); 237 setFrequency(-1); 238 setMeteredHint(false); 239 setEphemeral(false); 240 setOsuAp(false); 241 setNetworkSuggestionOrSpecifierPackageName(null); 242 setFQDN(null); 243 setProviderFriendlyName(null); 244 txBad = 0; 245 txSuccess = 0; 246 rxSuccess = 0; 247 txRetries = 0; 248 txBadRate = 0; 249 txSuccessRate = 0; 250 rxSuccessRate = 0; 251 txRetriesRate = 0; 252 score = 0; 253 } 254 255 /** 256 * Copy constructor 257 * @hide 258 */ WifiInfo(WifiInfo source)259 public WifiInfo(WifiInfo source) { 260 if (source != null) { 261 mSupplicantState = source.mSupplicantState; 262 mBSSID = source.mBSSID; 263 mWifiSsid = source.mWifiSsid; 264 mNetworkId = source.mNetworkId; 265 mRssi = source.mRssi; 266 mLinkSpeed = source.mLinkSpeed; 267 mTxLinkSpeed = source.mTxLinkSpeed; 268 mRxLinkSpeed = source.mRxLinkSpeed; 269 mFrequency = source.mFrequency; 270 mIpAddress = source.mIpAddress; 271 mMacAddress = source.mMacAddress; 272 mMeteredHint = source.mMeteredHint; 273 mEphemeral = source.mEphemeral; 274 mTrusted = source.mTrusted; 275 mNetworkSuggestionOrSpecifierPackageName = 276 source.mNetworkSuggestionOrSpecifierPackageName; 277 mOsuAp = source.mOsuAp; 278 mFqdn = source.mFqdn; 279 mProviderFriendlyName = source.mProviderFriendlyName; 280 txBad = source.txBad; 281 txRetries = source.txRetries; 282 txSuccess = source.txSuccess; 283 rxSuccess = source.rxSuccess; 284 txBadRate = source.txBadRate; 285 txRetriesRate = source.txRetriesRate; 286 txSuccessRate = source.txSuccessRate; 287 rxSuccessRate = source.rxSuccessRate; 288 score = source.score; 289 } 290 } 291 292 /** @hide */ setSSID(WifiSsid wifiSsid)293 public void setSSID(WifiSsid wifiSsid) { 294 mWifiSsid = wifiSsid; 295 } 296 297 /** 298 * Returns the service set identifier (SSID) of the current 802.11 network. 299 * <p> 300 * If the SSID can be decoded as UTF-8, it will be returned surrounded by double 301 * quotation marks. Otherwise, it is returned as a string of hex digits. 302 * The SSID may be 303 * <lt><unknown ssid>, if there is no network currently connected or if the caller has 304 * insufficient permissions to access the SSID.<lt> 305 * </p> 306 * <p> 307 * Prior to {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method 308 * always returned the SSID with no quotes around it. 309 * </p> 310 * 311 * @return the SSID. 312 */ getSSID()313 public String getSSID() { 314 if (mWifiSsid != null) { 315 String unicode = mWifiSsid.toString(); 316 if (!TextUtils.isEmpty(unicode)) { 317 return "\"" + unicode + "\""; 318 } else { 319 String hex = mWifiSsid.getHexString(); 320 return (hex != null) ? hex : WifiSsid.NONE; 321 } 322 } 323 return WifiSsid.NONE; 324 } 325 326 /** @hide */ 327 @UnsupportedAppUsage getWifiSsid()328 public WifiSsid getWifiSsid() { 329 return mWifiSsid; 330 } 331 332 /** @hide */ 333 @UnsupportedAppUsage setBSSID(String BSSID)334 public void setBSSID(String BSSID) { 335 mBSSID = BSSID; 336 } 337 338 /** 339 * Return the basic service set identifier (BSSID) of the current access point. 340 * <p> 341 * The BSSID may be 342 * <lt>{@code null}, if there is no network currently connected.</lt> 343 * <lt>{@code "02:00:00:00:00:00"}, if the caller has insufficient permissions to access the 344 * BSSID.<lt> 345 * </p> 346 * 347 * @return the BSSID, in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX} 348 */ getBSSID()349 public String getBSSID() { 350 return mBSSID; 351 } 352 353 /** 354 * Returns the received signal strength indicator of the current 802.11 355 * network, in dBm. 356 * 357 * <p>Use {@link android.net.wifi.WifiManager#calculateSignalLevel} to convert this number into 358 * an absolute signal level which can be displayed to a user. 359 * 360 * @return the RSSI. 361 */ getRssi()362 public int getRssi() { 363 return mRssi; 364 } 365 366 /** @hide */ 367 @UnsupportedAppUsage setRssi(int rssi)368 public void setRssi(int rssi) { 369 if (rssi < INVALID_RSSI) 370 rssi = INVALID_RSSI; 371 if (rssi > MAX_RSSI) 372 rssi = MAX_RSSI; 373 mRssi = rssi; 374 } 375 376 /** 377 * Returns the current link speed in {@link #LINK_SPEED_UNITS}. 378 * @return the link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown. 379 * @see #LINK_SPEED_UNITS 380 * @see #LINK_SPEED_UNKNOWN 381 */ getLinkSpeed()382 public int getLinkSpeed() { 383 return mLinkSpeed; 384 } 385 386 /** @hide */ 387 @UnsupportedAppUsage setLinkSpeed(int linkSpeed)388 public void setLinkSpeed(int linkSpeed) { 389 mLinkSpeed = linkSpeed; 390 } 391 392 /** 393 * Returns the current transmit link speed in Mbps. 394 * @return the Tx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown. 395 * @see #LINK_SPEED_UNKNOWN 396 */ 397 @IntRange(from = -1) getTxLinkSpeedMbps()398 public int getTxLinkSpeedMbps() { 399 return mTxLinkSpeed; 400 } 401 402 /** 403 * Update the last transmitted packet bit rate in Mbps. 404 * @hide 405 */ setTxLinkSpeedMbps(int txLinkSpeed)406 public void setTxLinkSpeedMbps(int txLinkSpeed) { 407 mTxLinkSpeed = txLinkSpeed; 408 } 409 410 /** 411 * Returns the current receive link speed in Mbps. 412 * @return the Rx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown. 413 * @see #LINK_SPEED_UNKNOWN 414 */ 415 @IntRange(from = -1) getRxLinkSpeedMbps()416 public int getRxLinkSpeedMbps() { 417 return mRxLinkSpeed; 418 } 419 420 /** 421 * Update the last received packet bit rate in Mbps. 422 * @hide 423 */ setRxLinkSpeedMbps(int rxLinkSpeed)424 public void setRxLinkSpeedMbps(int rxLinkSpeed) { 425 mRxLinkSpeed = rxLinkSpeed; 426 } 427 428 /** 429 * Returns the current frequency in {@link #FREQUENCY_UNITS}. 430 * @return the frequency. 431 * @see #FREQUENCY_UNITS 432 */ getFrequency()433 public int getFrequency() { 434 return mFrequency; 435 } 436 437 /** @hide */ setFrequency(int frequency)438 public void setFrequency(int frequency) { 439 this.mFrequency = frequency; 440 } 441 442 /** 443 * @hide 444 * TODO: makes real freq boundaries 445 */ is24GHz()446 public boolean is24GHz() { 447 return ScanResult.is24GHz(mFrequency); 448 } 449 450 /** 451 * @hide 452 * TODO: makes real freq boundaries 453 */ 454 @UnsupportedAppUsage is5GHz()455 public boolean is5GHz() { 456 return ScanResult.is5GHz(mFrequency); 457 } 458 459 /** 460 * Record the MAC address of the WLAN interface 461 * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form 462 * @hide 463 */ 464 @UnsupportedAppUsage setMacAddress(String macAddress)465 public void setMacAddress(String macAddress) { 466 this.mMacAddress = macAddress; 467 } 468 getMacAddress()469 public String getMacAddress() { 470 return mMacAddress; 471 } 472 473 /** 474 * @return true if {@link #getMacAddress()} has a real MAC address. 475 * 476 * @hide 477 */ hasRealMacAddress()478 public boolean hasRealMacAddress() { 479 return mMacAddress != null && !DEFAULT_MAC_ADDRESS.equals(mMacAddress); 480 } 481 482 /** 483 * Indicates if we've dynamically detected this active network connection as 484 * being metered. 485 * 486 * @see WifiConfiguration#isMetered(WifiConfiguration, WifiInfo) 487 * @hide 488 */ setMeteredHint(boolean meteredHint)489 public void setMeteredHint(boolean meteredHint) { 490 mMeteredHint = meteredHint; 491 } 492 493 /** {@hide} */ 494 @UnsupportedAppUsage getMeteredHint()495 public boolean getMeteredHint() { 496 return mMeteredHint; 497 } 498 499 /** {@hide} */ setEphemeral(boolean ephemeral)500 public void setEphemeral(boolean ephemeral) { 501 mEphemeral = ephemeral; 502 } 503 504 /** {@hide} */ 505 @UnsupportedAppUsage isEphemeral()506 public boolean isEphemeral() { 507 return mEphemeral; 508 } 509 510 /** {@hide} */ setTrusted(boolean trusted)511 public void setTrusted(boolean trusted) { 512 mTrusted = trusted; 513 } 514 515 /** {@hide} */ isTrusted()516 public boolean isTrusted() { 517 return mTrusted; 518 } 519 520 /** {@hide} */ setOsuAp(boolean osuAp)521 public void setOsuAp(boolean osuAp) { 522 mOsuAp = osuAp; 523 } 524 525 /** {@hide} */ 526 @SystemApi isOsuAp()527 public boolean isOsuAp() { 528 return mOsuAp; 529 } 530 531 /** {@hide} */ 532 @SystemApi isPasspointAp()533 public boolean isPasspointAp() { 534 return mFqdn != null && mProviderFriendlyName != null; 535 } 536 537 /** {@hide} */ setFQDN(@ullable String fqdn)538 public void setFQDN(@Nullable String fqdn) { 539 mFqdn = fqdn; 540 } 541 542 /** 543 * Returns the Fully Qualified Domain Name of the network if it is a Passpoint network. 544 */ getPasspointFqdn()545 public @Nullable String getPasspointFqdn() { 546 return mFqdn; 547 } 548 549 /** {@hide} */ setProviderFriendlyName(@ullable String providerFriendlyName)550 public void setProviderFriendlyName(@Nullable String providerFriendlyName) { 551 mProviderFriendlyName = providerFriendlyName; 552 } 553 554 /** 555 * Returns the Provider Friendly Name of the network if it is a Passpoint network. 556 */ getPasspointProviderFriendlyName()557 public @Nullable String getPasspointProviderFriendlyName() { 558 return mProviderFriendlyName; 559 } 560 561 /** {@hide} */ setNetworkSuggestionOrSpecifierPackageName(@ullable String packageName)562 public void setNetworkSuggestionOrSpecifierPackageName(@Nullable String packageName) { 563 mNetworkSuggestionOrSpecifierPackageName = packageName; 564 } 565 566 /** {@hide} */ getNetworkSuggestionOrSpecifierPackageName()567 public @Nullable String getNetworkSuggestionOrSpecifierPackageName() { 568 return mNetworkSuggestionOrSpecifierPackageName; 569 } 570 571 572 /** @hide */ 573 @UnsupportedAppUsage setNetworkId(int id)574 public void setNetworkId(int id) { 575 mNetworkId = id; 576 } 577 578 /** 579 * Each configured network has a unique small integer ID, used to identify 580 * the network. This method returns the ID for the currently connected network. 581 * <p> 582 * The networkId may be {@code -1} if there is no currently connected network or if the caller 583 * has insufficient permissions to access the network ID. 584 * </p> 585 * 586 * @return the network ID. 587 */ getNetworkId()588 public int getNetworkId() { 589 return mNetworkId; 590 } 591 592 /** 593 * Return the detailed state of the supplicant's negotiation with an 594 * access point, in the form of a {@link SupplicantState SupplicantState} object. 595 * @return the current {@link SupplicantState SupplicantState} 596 */ getSupplicantState()597 public SupplicantState getSupplicantState() { 598 return mSupplicantState; 599 } 600 601 /** @hide */ 602 @UnsupportedAppUsage setSupplicantState(SupplicantState state)603 public void setSupplicantState(SupplicantState state) { 604 mSupplicantState = state; 605 } 606 607 /** @hide */ setInetAddress(InetAddress address)608 public void setInetAddress(InetAddress address) { 609 mIpAddress = address; 610 } 611 getIpAddress()612 public int getIpAddress() { 613 int result = 0; 614 if (mIpAddress instanceof Inet4Address) { 615 result = NetworkUtils.inetAddressToInt((Inet4Address)mIpAddress); 616 } 617 return result; 618 } 619 620 /** 621 * @return {@code true} if this network does not broadcast its SSID, so an 622 * SSID-specific probe request must be used for scans. 623 */ getHiddenSSID()624 public boolean getHiddenSSID() { 625 if (mWifiSsid == null) return false; 626 return mWifiSsid.isHidden(); 627 } 628 629 /** 630 * Map a supplicant state into a fine-grained network connectivity state. 631 * @param suppState the supplicant state 632 * @return the corresponding {@link DetailedState} 633 */ getDetailedStateOf(SupplicantState suppState)634 public static DetailedState getDetailedStateOf(SupplicantState suppState) { 635 return stateMap.get(suppState); 636 } 637 638 /** 639 * Set the <code>SupplicantState</code> from the string name 640 * of the state. 641 * @param stateName the name of the state, as a <code>String</code> returned 642 * in an event sent by {@code wpa_supplicant}. 643 */ 644 @UnsupportedAppUsage setSupplicantState(String stateName)645 void setSupplicantState(String stateName) { 646 mSupplicantState = valueOf(stateName); 647 } 648 valueOf(String stateName)649 static SupplicantState valueOf(String stateName) { 650 if ("4WAY_HANDSHAKE".equalsIgnoreCase(stateName)) 651 return SupplicantState.FOUR_WAY_HANDSHAKE; 652 else { 653 try { 654 return SupplicantState.valueOf(stateName.toUpperCase(Locale.ROOT)); 655 } catch (IllegalArgumentException e) { 656 return SupplicantState.INVALID; 657 } 658 } 659 } 660 661 /** 662 * Remove double quotes (") surrounding a SSID string, if present. Otherwise, return the 663 * string unmodified. Return null if the input string was null. 664 * @hide 665 */ 666 @Nullable 667 @SystemApi sanitizeSsid(@ullable String string)668 public static String sanitizeSsid(@Nullable String string) { 669 return removeDoubleQuotes(string); 670 } 671 672 /** @hide */ 673 @UnsupportedAppUsage 674 @Nullable removeDoubleQuotes(@ullable String string)675 public static String removeDoubleQuotes(@Nullable String string) { 676 if (string == null) return null; 677 final int length = string.length(); 678 if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) { 679 return string.substring(1, length - 1); 680 } 681 return string; 682 } 683 684 @Override toString()685 public String toString() { 686 StringBuffer sb = new StringBuffer(); 687 String none = "<none>"; 688 689 sb.append("SSID: ").append(mWifiSsid == null ? WifiSsid.NONE : mWifiSsid) 690 .append(", BSSID: ").append(mBSSID == null ? none : mBSSID) 691 .append(", MAC: ").append(mMacAddress == null ? none : mMacAddress) 692 .append(", Supplicant state: ") 693 .append(mSupplicantState == null ? none : mSupplicantState) 694 .append(", RSSI: ").append(mRssi) 695 .append(", Link speed: ").append(mLinkSpeed).append(LINK_SPEED_UNITS) 696 .append(", Tx Link speed: ").append(mTxLinkSpeed).append(LINK_SPEED_UNITS) 697 .append(", Rx Link speed: ").append(mRxLinkSpeed).append(LINK_SPEED_UNITS) 698 .append(", Frequency: ").append(mFrequency).append(FREQUENCY_UNITS) 699 .append(", Net ID: ").append(mNetworkId) 700 .append(", Metered hint: ").append(mMeteredHint) 701 .append(", score: ").append(Integer.toString(score)); 702 return sb.toString(); 703 } 704 705 /** Implement the Parcelable interface {@hide} */ describeContents()706 public int describeContents() { 707 return 0; 708 } 709 710 /** Implement the Parcelable interface {@hide} */ writeToParcel(Parcel dest, int flags)711 public void writeToParcel(Parcel dest, int flags) { 712 dest.writeInt(mNetworkId); 713 dest.writeInt(mRssi); 714 dest.writeInt(mLinkSpeed); 715 dest.writeInt(mTxLinkSpeed); 716 dest.writeInt(mRxLinkSpeed); 717 dest.writeInt(mFrequency); 718 if (mIpAddress != null) { 719 dest.writeByte((byte)1); 720 dest.writeByteArray(mIpAddress.getAddress()); 721 } else { 722 dest.writeByte((byte)0); 723 } 724 if (mWifiSsid != null) { 725 dest.writeInt(1); 726 mWifiSsid.writeToParcel(dest, flags); 727 } else { 728 dest.writeInt(0); 729 } 730 dest.writeString(mBSSID); 731 dest.writeString(mMacAddress); 732 dest.writeInt(mMeteredHint ? 1 : 0); 733 dest.writeInt(mEphemeral ? 1 : 0); 734 dest.writeInt(mTrusted ? 1 : 0); 735 dest.writeInt(score); 736 dest.writeLong(txSuccess); 737 dest.writeDouble(txSuccessRate); 738 dest.writeLong(txRetries); 739 dest.writeDouble(txRetriesRate); 740 dest.writeLong(txBad); 741 dest.writeDouble(txBadRate); 742 dest.writeLong(rxSuccess); 743 dest.writeDouble(rxSuccessRate); 744 mSupplicantState.writeToParcel(dest, flags); 745 dest.writeInt(mOsuAp ? 1 : 0); 746 dest.writeString(mNetworkSuggestionOrSpecifierPackageName); 747 dest.writeString(mFqdn); 748 dest.writeString(mProviderFriendlyName); 749 } 750 751 /** Implement the Parcelable interface {@hide} */ 752 @UnsupportedAppUsage 753 public static final @android.annotation.NonNull Creator<WifiInfo> CREATOR = 754 new Creator<WifiInfo>() { 755 public WifiInfo createFromParcel(Parcel in) { 756 WifiInfo info = new WifiInfo(); 757 info.setNetworkId(in.readInt()); 758 info.setRssi(in.readInt()); 759 info.setLinkSpeed(in.readInt()); 760 info.setTxLinkSpeedMbps(in.readInt()); 761 info.setRxLinkSpeedMbps(in.readInt()); 762 info.setFrequency(in.readInt()); 763 if (in.readByte() == 1) { 764 try { 765 info.setInetAddress(InetAddress.getByAddress(in.createByteArray())); 766 } catch (UnknownHostException e) {} 767 } 768 if (in.readInt() == 1) { 769 info.mWifiSsid = WifiSsid.CREATOR.createFromParcel(in); 770 } 771 info.mBSSID = in.readString(); 772 info.mMacAddress = in.readString(); 773 info.mMeteredHint = in.readInt() != 0; 774 info.mEphemeral = in.readInt() != 0; 775 info.mTrusted = in.readInt() != 0; 776 info.score = in.readInt(); 777 info.txSuccess = in.readLong(); 778 info.txSuccessRate = in.readDouble(); 779 info.txRetries = in.readLong(); 780 info.txRetriesRate = in.readDouble(); 781 info.txBad = in.readLong(); 782 info.txBadRate = in.readDouble(); 783 info.rxSuccess = in.readLong(); 784 info.rxSuccessRate = in.readDouble(); 785 info.mSupplicantState = SupplicantState.CREATOR.createFromParcel(in); 786 info.mOsuAp = in.readInt() != 0; 787 info.mNetworkSuggestionOrSpecifierPackageName = in.readString(); 788 info.mFqdn = in.readString(); 789 info.mProviderFriendlyName = in.readString(); 790 return info; 791 } 792 793 public WifiInfo[] newArray(int size) { 794 return new WifiInfo[size]; 795 } 796 }; 797 } 798