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.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.SystemApi; 23 import android.compat.annotation.UnsupportedAppUsage; 24 import android.net.NetworkInfo.DetailedState; 25 import android.os.Build; 26 import android.os.Parcel; 27 import android.os.Parcelable; 28 import android.text.TextUtils; 29 30 import com.android.net.module.util.Inet4AddressUtils; 31 32 import java.net.Inet4Address; 33 import java.net.InetAddress; 34 import java.net.UnknownHostException; 35 import java.util.EnumMap; 36 import java.util.Locale; 37 38 /** 39 * Describes the state of any Wi-Fi connection that is active or 40 * is in the process of being set up. 41 */ 42 public class WifiInfo implements Parcelable { 43 private static final String TAG = "WifiInfo"; 44 /** 45 * This is the map described in the Javadoc comment above. The positions 46 * of the elements of the array must correspond to the ordinal values 47 * of <code>DetailedState</code>. 48 */ 49 private static final EnumMap<SupplicantState, DetailedState> stateMap = 50 new EnumMap<SupplicantState, DetailedState>(SupplicantState.class); 51 52 /** 53 * Default MAC address reported to a client that does not have the 54 * android.permission.LOCAL_MAC_ADDRESS permission. 55 * 56 * @hide 57 */ 58 @SystemApi 59 public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00"; 60 61 static { stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED)62 stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED); stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED)63 stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED); stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE)64 stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE); stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING)65 stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING); stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING)66 stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING); stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING)67 stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING); stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING)68 stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING); stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING)69 stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING); stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING)70 stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING); stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR)71 stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR); stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED)72 stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED); stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE)73 stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE); stateMap.put(SupplicantState.INVALID, DetailedState.FAILED)74 stateMap.put(SupplicantState.INVALID, DetailedState.FAILED); 75 } 76 77 private SupplicantState mSupplicantState; 78 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 79 private String mBSSID; 80 @UnsupportedAppUsage 81 private WifiSsid mWifiSsid; 82 private int mNetworkId; 83 84 /** 85 * Used to indicate that the RSSI is invalid, for example if no RSSI measurements are available 86 * yet. 87 * @hide 88 */ 89 @SystemApi 90 public static final int INVALID_RSSI = -127; 91 92 /** @hide **/ 93 public static final int MIN_RSSI = -126; 94 95 /** @hide **/ 96 public static final int MAX_RSSI = 200; 97 98 99 /** 100 * Received Signal Strength Indicator 101 */ 102 private int mRssi; 103 104 /** 105 * Wi-Fi standard for the connection 106 */ 107 private @WifiAnnotations.WifiStandard int mWifiStandard; 108 109 /** 110 * The unit in which links speeds are expressed. 111 */ 112 public static final String LINK_SPEED_UNITS = "Mbps"; 113 private int mLinkSpeed; 114 115 /** 116 * Constant for unknown link speed. 117 */ 118 public static final int LINK_SPEED_UNKNOWN = -1; 119 120 /** 121 * Tx(transmit) Link speed in Mbps 122 */ 123 private int mTxLinkSpeed; 124 125 /** 126 * Max supported Tx(transmit) link speed in Mbps 127 */ 128 private int mMaxSupportedTxLinkSpeed; 129 130 /** 131 * Rx(receive) Link speed in Mbps 132 */ 133 private int mRxLinkSpeed; 134 135 /** 136 * Max supported Rx(receive) link speed in Mbps 137 */ 138 private int mMaxSupportedRxLinkSpeed; 139 140 /** 141 * Frequency in MHz 142 */ 143 public static final String FREQUENCY_UNITS = "MHz"; 144 private int mFrequency; 145 146 @UnsupportedAppUsage 147 private InetAddress mIpAddress; 148 @UnsupportedAppUsage 149 private String mMacAddress = DEFAULT_MAC_ADDRESS; 150 151 /** 152 * Whether the network is ephemeral or not. 153 */ 154 private boolean mEphemeral; 155 156 /** 157 * Whether the network is trusted or not. 158 */ 159 private boolean mTrusted; 160 161 /** 162 * OSU (Online Sign Up) AP for Passpoint R2. 163 */ 164 private boolean mOsuAp; 165 166 /** 167 * Fully qualified domain name of a Passpoint configuration 168 */ 169 private String mFqdn; 170 171 /** 172 * Name of Passpoint credential provider 173 */ 174 private String mProviderFriendlyName; 175 176 /** 177 * If connected to a network suggestion or specifier, store the package name of the app, 178 * else null. 179 */ 180 private String mRequestingPackageName; 181 182 /** 183 * Running total count of lost (not ACKed) transmitted unicast data packets. 184 * @hide 185 */ 186 public long txBad; 187 /** 188 * Running total count of transmitted unicast data retry packets. 189 * @hide 190 */ 191 public long txRetries; 192 /** 193 * Running total count of successfully transmitted (ACKed) unicast data packets. 194 * @hide 195 */ 196 public long txSuccess; 197 /** 198 * Running total count of received unicast data packets. 199 * @hide 200 */ 201 public long rxSuccess; 202 203 private double mLostTxPacketsPerSecond; 204 205 /** 206 * Average rate of lost transmitted packets, in units of packets per second. 207 * @hide 208 */ 209 @SystemApi getLostTxPacketsPerSecond()210 public double getLostTxPacketsPerSecond() { 211 return mLostTxPacketsPerSecond; 212 } 213 214 /** @hide */ setLostTxPacketsPerSecond(double lostTxPacketsPerSecond)215 public void setLostTxPacketsPerSecond(double lostTxPacketsPerSecond) { 216 mLostTxPacketsPerSecond = lostTxPacketsPerSecond; 217 } 218 219 private double mTxRetriedTxPacketsPerSecond; 220 221 /** 222 * Average rate of transmitted retry packets, in units of packets per second. 223 * @hide 224 */ 225 @SystemApi getRetriedTxPacketsPerSecond()226 public double getRetriedTxPacketsPerSecond() { 227 return mTxRetriedTxPacketsPerSecond; 228 } 229 230 /** @hide */ setRetriedTxPacketsRate(double txRetriedTxPacketsPerSecond)231 public void setRetriedTxPacketsRate(double txRetriedTxPacketsPerSecond) { 232 mTxRetriedTxPacketsPerSecond = txRetriedTxPacketsPerSecond; 233 } 234 235 private double mSuccessfulTxPacketsPerSecond; 236 237 /** 238 * Average rate of successfully transmitted unicast packets, in units of packets per second. 239 * @hide 240 */ 241 @SystemApi getSuccessfulTxPacketsPerSecond()242 public double getSuccessfulTxPacketsPerSecond() { 243 return mSuccessfulTxPacketsPerSecond; 244 } 245 246 /** @hide */ setSuccessfulTxPacketsPerSecond(double successfulTxPacketsPerSecond)247 public void setSuccessfulTxPacketsPerSecond(double successfulTxPacketsPerSecond) { 248 mSuccessfulTxPacketsPerSecond = successfulTxPacketsPerSecond; 249 } 250 251 private double mSuccessfulRxPacketsPerSecond; 252 253 /** 254 * Average rate of received unicast data packets, in units of packets per second. 255 * @hide 256 */ 257 @SystemApi getSuccessfulRxPacketsPerSecond()258 public double getSuccessfulRxPacketsPerSecond() { 259 return mSuccessfulRxPacketsPerSecond; 260 } 261 262 /** @hide */ setSuccessfulRxPacketsPerSecond(double successfulRxPacketsPerSecond)263 public void setSuccessfulRxPacketsPerSecond(double successfulRxPacketsPerSecond) { 264 mSuccessfulRxPacketsPerSecond = successfulRxPacketsPerSecond; 265 } 266 267 /** @hide */ 268 @UnsupportedAppUsage 269 public int score; 270 271 /** 272 * The current Wifi score. 273 * NOTE: this value should only be used for debugging purposes. Do not rely on this value for 274 * any computations. The meaning of this value can and will change at any time without warning. 275 * @hide 276 */ 277 @SystemApi getScore()278 public int getScore() { 279 return score; 280 } 281 282 /** @hide */ setScore(int score)283 public void setScore(int score) { 284 this.score = score; 285 } 286 287 /** 288 * Flag indicating that AP has hinted that upstream connection is metered, 289 * and sensitive to heavy data transfers. 290 */ 291 private boolean mMeteredHint; 292 293 /** 294 * Passpoint unique key 295 */ 296 private String mPasspointUniqueId; 297 298 /** @hide */ 299 @UnsupportedAppUsage WifiInfo()300 public WifiInfo() { 301 mWifiSsid = null; 302 mBSSID = null; 303 mNetworkId = -1; 304 mSupplicantState = SupplicantState.UNINITIALIZED; 305 mRssi = INVALID_RSSI; 306 mLinkSpeed = LINK_SPEED_UNKNOWN; 307 mFrequency = -1; 308 } 309 310 /** @hide */ reset()311 public void reset() { 312 setInetAddress(null); 313 setBSSID(null); 314 setSSID(null); 315 setNetworkId(-1); 316 setRssi(INVALID_RSSI); 317 setLinkSpeed(LINK_SPEED_UNKNOWN); 318 setTxLinkSpeedMbps(LINK_SPEED_UNKNOWN); 319 setRxLinkSpeedMbps(LINK_SPEED_UNKNOWN); 320 setMaxSupportedTxLinkSpeedMbps(LINK_SPEED_UNKNOWN); 321 setMaxSupportedRxLinkSpeedMbps(LINK_SPEED_UNKNOWN); 322 setFrequency(-1); 323 setMeteredHint(false); 324 setEphemeral(false); 325 setOsuAp(false); 326 setRequestingPackageName(null); 327 setFQDN(null); 328 setProviderFriendlyName(null); 329 setPasspointUniqueId(null); 330 txBad = 0; 331 txSuccess = 0; 332 rxSuccess = 0; 333 txRetries = 0; 334 mLostTxPacketsPerSecond = 0; 335 mSuccessfulTxPacketsPerSecond = 0; 336 mSuccessfulRxPacketsPerSecond = 0; 337 mTxRetriedTxPacketsPerSecond = 0; 338 score = 0; 339 } 340 341 /** 342 * Copy constructor 343 * @hide 344 */ WifiInfo(WifiInfo source)345 public WifiInfo(WifiInfo source) { 346 if (source != null) { 347 mSupplicantState = source.mSupplicantState; 348 mBSSID = source.mBSSID; 349 mWifiSsid = source.mWifiSsid; 350 mNetworkId = source.mNetworkId; 351 mRssi = source.mRssi; 352 mLinkSpeed = source.mLinkSpeed; 353 mTxLinkSpeed = source.mTxLinkSpeed; 354 mRxLinkSpeed = source.mRxLinkSpeed; 355 mFrequency = source.mFrequency; 356 mIpAddress = source.mIpAddress; 357 mMacAddress = source.mMacAddress; 358 mMeteredHint = source.mMeteredHint; 359 mEphemeral = source.mEphemeral; 360 mTrusted = source.mTrusted; 361 mRequestingPackageName = 362 source.mRequestingPackageName; 363 mOsuAp = source.mOsuAp; 364 mFqdn = source.mFqdn; 365 mProviderFriendlyName = source.mProviderFriendlyName; 366 txBad = source.txBad; 367 txRetries = source.txRetries; 368 txSuccess = source.txSuccess; 369 rxSuccess = source.rxSuccess; 370 mLostTxPacketsPerSecond = source.mLostTxPacketsPerSecond; 371 mTxRetriedTxPacketsPerSecond = source.mTxRetriedTxPacketsPerSecond; 372 mSuccessfulTxPacketsPerSecond = source.mSuccessfulTxPacketsPerSecond; 373 mSuccessfulRxPacketsPerSecond = source.mSuccessfulRxPacketsPerSecond; 374 score = source.score; 375 mWifiStandard = source.mWifiStandard; 376 mMaxSupportedTxLinkSpeed = source.mMaxSupportedTxLinkSpeed; 377 mMaxSupportedRxLinkSpeed = source.mMaxSupportedRxLinkSpeed; 378 mPasspointUniqueId = source.mPasspointUniqueId; 379 } 380 } 381 382 /** Builder for WifiInfo */ 383 public static final class Builder { 384 private final WifiInfo mWifiInfo = new WifiInfo(); 385 386 /** 387 * Set the SSID, in the form of a raw byte array. 388 * @see WifiInfo#getSSID() 389 */ 390 @NonNull setSsid(@onNull byte[] ssid)391 public Builder setSsid(@NonNull byte[] ssid) { 392 mWifiInfo.setSSID(WifiSsid.createFromByteArray(ssid)); 393 return this; 394 } 395 396 /** 397 * Set the BSSID. 398 * @see WifiInfo#getBSSID() 399 */ 400 @NonNull setBssid(@onNull String bssid)401 public Builder setBssid(@NonNull String bssid) { 402 mWifiInfo.setBSSID(bssid); 403 return this; 404 } 405 406 /** 407 * Set the RSSI, in dBm. 408 * @see WifiInfo#getRssi() 409 */ 410 @NonNull setRssi(int rssi)411 public Builder setRssi(int rssi) { 412 mWifiInfo.setRssi(rssi); 413 return this; 414 } 415 416 /** 417 * Set the network ID. 418 * @see WifiInfo#getNetworkId() 419 */ 420 @NonNull setNetworkId(int networkId)421 public Builder setNetworkId(int networkId) { 422 mWifiInfo.setNetworkId(networkId); 423 return this; 424 } 425 426 /** 427 * Build a WifiInfo object. 428 */ 429 @NonNull build()430 public WifiInfo build() { 431 return new WifiInfo(mWifiInfo); 432 } 433 } 434 435 /** @hide */ setSSID(WifiSsid wifiSsid)436 public void setSSID(WifiSsid wifiSsid) { 437 mWifiSsid = wifiSsid; 438 } 439 440 /** 441 * Returns the service set identifier (SSID) of the current 802.11 network. 442 * <p> 443 * If the SSID can be decoded as UTF-8, it will be returned surrounded by double 444 * quotation marks. Otherwise, it is returned as a string of hex digits. 445 * The SSID may be {@link WifiManager#UNKNOWN_SSID}, if there is no network currently connected 446 * or if the caller has insufficient permissions to access the SSID. 447 * </p> 448 * <p> 449 * Prior to {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method 450 * always returned the SSID with no quotes around it. 451 * </p> 452 * 453 * @return the SSID. 454 */ getSSID()455 public String getSSID() { 456 if (mWifiSsid != null) { 457 String unicode = mWifiSsid.toString(); 458 if (!TextUtils.isEmpty(unicode)) { 459 return "\"" + unicode + "\""; 460 } else { 461 String hex = mWifiSsid.getHexString(); 462 return (hex != null) ? hex : WifiManager.UNKNOWN_SSID; 463 } 464 } 465 return WifiManager.UNKNOWN_SSID; 466 } 467 468 /** @hide */ 469 @UnsupportedAppUsage getWifiSsid()470 public WifiSsid getWifiSsid() { 471 return mWifiSsid; 472 } 473 474 /** @hide */ 475 @UnsupportedAppUsage setBSSID(String BSSID)476 public void setBSSID(String BSSID) { 477 mBSSID = BSSID; 478 } 479 480 /** 481 * Return the basic service set identifier (BSSID) of the current access point. 482 * <p> 483 * The BSSID may be 484 * <lt>{@code null}, if there is no network currently connected.</lt> 485 * <lt>{@code "02:00:00:00:00:00"}, if the caller has insufficient permissions to access the 486 * BSSID.<lt> 487 * </p> 488 * 489 * @return the BSSID, in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX} 490 */ getBSSID()491 public String getBSSID() { 492 return mBSSID; 493 } 494 495 /** 496 * Returns the received signal strength indicator of the current 802.11 497 * network, in dBm. 498 * 499 * <p>Use {@link android.net.wifi.WifiManager#calculateSignalLevel} to convert this number into 500 * an absolute signal level which can be displayed to a user. 501 * 502 * @return the RSSI. 503 */ getRssi()504 public int getRssi() { 505 return mRssi; 506 } 507 508 /** @hide */ 509 @UnsupportedAppUsage setRssi(int rssi)510 public void setRssi(int rssi) { 511 if (rssi < INVALID_RSSI) 512 rssi = INVALID_RSSI; 513 if (rssi > MAX_RSSI) 514 rssi = MAX_RSSI; 515 mRssi = rssi; 516 } 517 518 /** 519 * Sets the Wi-Fi standard 520 * @hide 521 */ setWifiStandard(@ifiAnnotations.WifiStandard int wifiStandard)522 public void setWifiStandard(@WifiAnnotations.WifiStandard int wifiStandard) { 523 mWifiStandard = wifiStandard; 524 } 525 526 /** 527 * Get connection Wi-Fi standard 528 * @return the connection Wi-Fi standard 529 */ getWifiStandard()530 public @WifiAnnotations.WifiStandard int getWifiStandard() { 531 return mWifiStandard; 532 } 533 534 /** 535 * Returns the current link speed in {@link #LINK_SPEED_UNITS}. 536 * @return the link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown. 537 * @see #LINK_SPEED_UNITS 538 * @see #LINK_SPEED_UNKNOWN 539 */ getLinkSpeed()540 public int getLinkSpeed() { 541 return mLinkSpeed; 542 } 543 544 /** @hide */ 545 @UnsupportedAppUsage setLinkSpeed(int linkSpeed)546 public void setLinkSpeed(int linkSpeed) { 547 mLinkSpeed = linkSpeed; 548 } 549 550 /** 551 * Returns the current transmit link speed in Mbps. 552 * @return the Tx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown. 553 * @see #LINK_SPEED_UNKNOWN 554 */ 555 @IntRange(from = -1) getTxLinkSpeedMbps()556 public int getTxLinkSpeedMbps() { 557 return mTxLinkSpeed; 558 } 559 560 /** 561 * Returns the maximum supported transmit link speed in Mbps 562 * @return the max supported tx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is 563 * unknown. @see #LINK_SPEED_UNKNOWN 564 */ getMaxSupportedTxLinkSpeedMbps()565 public int getMaxSupportedTxLinkSpeedMbps() { 566 return mMaxSupportedTxLinkSpeed; 567 } 568 569 /** 570 * Update the last transmitted packet bit rate in Mbps. 571 * @hide 572 */ setTxLinkSpeedMbps(int txLinkSpeed)573 public void setTxLinkSpeedMbps(int txLinkSpeed) { 574 mTxLinkSpeed = txLinkSpeed; 575 } 576 577 /** 578 * Set the maximum supported transmit link speed in Mbps 579 * @hide 580 */ setMaxSupportedTxLinkSpeedMbps(int maxSupportedTxLinkSpeed)581 public void setMaxSupportedTxLinkSpeedMbps(int maxSupportedTxLinkSpeed) { 582 mMaxSupportedTxLinkSpeed = maxSupportedTxLinkSpeed; 583 } 584 585 /** 586 * Returns the current receive link speed in Mbps. 587 * @return the Rx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown. 588 * @see #LINK_SPEED_UNKNOWN 589 */ 590 @IntRange(from = -1) getRxLinkSpeedMbps()591 public int getRxLinkSpeedMbps() { 592 return mRxLinkSpeed; 593 } 594 595 /** 596 * Returns the maximum supported receive link speed in Mbps 597 * @return the max supported Rx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is 598 * unknown. @see #LINK_SPEED_UNKNOWN 599 */ getMaxSupportedRxLinkSpeedMbps()600 public int getMaxSupportedRxLinkSpeedMbps() { 601 return mMaxSupportedRxLinkSpeed; 602 } 603 604 /** 605 * Update the last received packet bit rate in Mbps. 606 * @hide 607 */ setRxLinkSpeedMbps(int rxLinkSpeed)608 public void setRxLinkSpeedMbps(int rxLinkSpeed) { 609 mRxLinkSpeed = rxLinkSpeed; 610 } 611 612 /** 613 * Set the maximum supported receive link speed in Mbps 614 * @hide 615 */ setMaxSupportedRxLinkSpeedMbps(int maxSupportedRxLinkSpeed)616 public void setMaxSupportedRxLinkSpeedMbps(int maxSupportedRxLinkSpeed) { 617 mMaxSupportedRxLinkSpeed = maxSupportedRxLinkSpeed; 618 } 619 620 /** 621 * Returns the current frequency in {@link #FREQUENCY_UNITS}. 622 * @return the frequency. 623 * @see #FREQUENCY_UNITS 624 */ getFrequency()625 public int getFrequency() { 626 return mFrequency; 627 } 628 629 /** @hide */ setFrequency(int frequency)630 public void setFrequency(int frequency) { 631 this.mFrequency = frequency; 632 } 633 634 /** 635 * @hide 636 */ is24GHz()637 public boolean is24GHz() { 638 return ScanResult.is24GHz(mFrequency); 639 } 640 641 /** 642 * @hide 643 */ 644 @UnsupportedAppUsage is5GHz()645 public boolean is5GHz() { 646 return ScanResult.is5GHz(mFrequency); 647 } 648 649 /** 650 * @hide 651 */ is6GHz()652 public boolean is6GHz() { 653 return ScanResult.is6GHz(mFrequency); 654 } 655 656 /** 657 * Record the MAC address of the WLAN interface 658 * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form 659 * @hide 660 */ 661 @UnsupportedAppUsage setMacAddress(String macAddress)662 public void setMacAddress(String macAddress) { 663 this.mMacAddress = macAddress; 664 } 665 getMacAddress()666 public String getMacAddress() { 667 return mMacAddress; 668 } 669 670 /** 671 * @return true if {@link #getMacAddress()} has a real MAC address. 672 * 673 * @hide 674 */ hasRealMacAddress()675 public boolean hasRealMacAddress() { 676 return mMacAddress != null && !DEFAULT_MAC_ADDRESS.equals(mMacAddress); 677 } 678 679 /** 680 * Indicates if we've dynamically detected this active network connection as 681 * being metered. 682 * 683 * @see WifiConfiguration#isMetered(WifiConfiguration, WifiInfo) 684 * @hide 685 */ setMeteredHint(boolean meteredHint)686 public void setMeteredHint(boolean meteredHint) { 687 mMeteredHint = meteredHint; 688 } 689 690 /** {@hide} */ 691 @UnsupportedAppUsage getMeteredHint()692 public boolean getMeteredHint() { 693 return mMeteredHint; 694 } 695 696 /** {@hide} */ setEphemeral(boolean ephemeral)697 public void setEphemeral(boolean ephemeral) { 698 mEphemeral = ephemeral; 699 } 700 701 /** 702 * Returns true if the current Wifi network is ephemeral, false otherwise. 703 * An ephemeral network is a network that is temporary and not persisted in the system. 704 * Ephemeral networks cannot be forgotten, only disabled with 705 * {@link WifiManager#disableEphemeralNetwork(String)}. 706 * 707 * @hide 708 */ 709 @SystemApi isEphemeral()710 public boolean isEphemeral() { 711 return mEphemeral; 712 } 713 714 /** {@hide} */ setTrusted(boolean trusted)715 public void setTrusted(boolean trusted) { 716 mTrusted = trusted; 717 } 718 719 /** {@hide} */ isTrusted()720 public boolean isTrusted() { 721 return mTrusted; 722 } 723 724 /** {@hide} */ setOsuAp(boolean osuAp)725 public void setOsuAp(boolean osuAp) { 726 mOsuAp = osuAp; 727 } 728 729 /** {@hide} */ 730 @SystemApi isOsuAp()731 public boolean isOsuAp() { 732 return mOsuAp; 733 } 734 735 /** {@hide} */ 736 @SystemApi isPasspointAp()737 public boolean isPasspointAp() { 738 return mFqdn != null && mProviderFriendlyName != null; 739 } 740 741 /** {@hide} */ setFQDN(@ullable String fqdn)742 public void setFQDN(@Nullable String fqdn) { 743 mFqdn = fqdn; 744 } 745 746 /** 747 * Returns the Fully Qualified Domain Name of the network if it is a Passpoint network. 748 * <p> 749 * The FQDN may be 750 * <lt>{@code null} if no network currently connected, currently connected network is not 751 * passpoint network or the caller has insufficient permissions to access the FQDN.</lt> 752 * </p> 753 */ getPasspointFqdn()754 public @Nullable String getPasspointFqdn() { 755 return mFqdn; 756 } 757 758 /** {@hide} */ setProviderFriendlyName(@ullable String providerFriendlyName)759 public void setProviderFriendlyName(@Nullable String providerFriendlyName) { 760 mProviderFriendlyName = providerFriendlyName; 761 } 762 763 /** 764 * Returns the Provider Friendly Name of the network if it is a Passpoint network. 765 * <p> 766 * The Provider Friendly Name may be 767 * <lt>{@code null} if no network currently connected, currently connected network is not 768 * passpoint network or the caller has insufficient permissions to access the Provider Friendly 769 * Name. </lt> 770 * </p> 771 */ getPasspointProviderFriendlyName()772 public @Nullable String getPasspointProviderFriendlyName() { 773 return mProviderFriendlyName; 774 } 775 776 /** {@hide} */ setRequestingPackageName(@ullable String packageName)777 public void setRequestingPackageName(@Nullable String packageName) { 778 mRequestingPackageName = packageName; 779 } 780 781 /** 782 * If this network was created in response to an app request (e.g. through Network Suggestion 783 * or Network Specifier), return the package name of the app that made the request. 784 * Null otherwise. 785 * @hide 786 */ 787 @SystemApi getRequestingPackageName()788 public @Nullable String getRequestingPackageName() { 789 return mRequestingPackageName; 790 } 791 792 793 /** @hide */ 794 @UnsupportedAppUsage setNetworkId(int id)795 public void setNetworkId(int id) { 796 mNetworkId = id; 797 } 798 799 /** 800 * Each configured network has a unique small integer ID, used to identify 801 * the network. This method returns the ID for the currently connected network. 802 * <p> 803 * The networkId may be {@code -1} if there is no currently connected network or if the caller 804 * has insufficient permissions to access the network ID. 805 * </p> 806 * 807 * @return the network ID. 808 */ getNetworkId()809 public int getNetworkId() { 810 return mNetworkId; 811 } 812 813 /** 814 * Return the detailed state of the supplicant's negotiation with an 815 * access point, in the form of a {@link SupplicantState SupplicantState} object. 816 * @return the current {@link SupplicantState SupplicantState} 817 */ getSupplicantState()818 public SupplicantState getSupplicantState() { 819 return mSupplicantState; 820 } 821 822 /** @hide */ 823 @UnsupportedAppUsage setSupplicantState(SupplicantState state)824 public void setSupplicantState(SupplicantState state) { 825 mSupplicantState = state; 826 } 827 828 /** @hide */ setInetAddress(InetAddress address)829 public void setInetAddress(InetAddress address) { 830 mIpAddress = address; 831 } 832 getIpAddress()833 public int getIpAddress() { 834 int result = 0; 835 if (mIpAddress instanceof Inet4Address) { 836 result = Inet4AddressUtils.inet4AddressToIntHTL((Inet4Address) mIpAddress); 837 } 838 return result; 839 } 840 841 /** 842 * @return {@code true} if this network does not broadcast its SSID, so an 843 * SSID-specific probe request must be used for scans. 844 */ getHiddenSSID()845 public boolean getHiddenSSID() { 846 if (mWifiSsid == null) return false; 847 return mWifiSsid.isHidden(); 848 } 849 850 /** 851 * Map a supplicant state into a fine-grained network connectivity state. 852 * @param suppState the supplicant state 853 * @return the corresponding {@link DetailedState} 854 */ getDetailedStateOf(SupplicantState suppState)855 public static DetailedState getDetailedStateOf(SupplicantState suppState) { 856 return stateMap.get(suppState); 857 } 858 859 /** 860 * Set the <code>SupplicantState</code> from the string name 861 * of the state. 862 * @param stateName the name of the state, as a <code>String</code> returned 863 * in an event sent by {@code wpa_supplicant}. 864 */ 865 @UnsupportedAppUsage setSupplicantState(String stateName)866 void setSupplicantState(String stateName) { 867 mSupplicantState = valueOf(stateName); 868 } 869 valueOf(String stateName)870 static SupplicantState valueOf(String stateName) { 871 if ("4WAY_HANDSHAKE".equalsIgnoreCase(stateName)) 872 return SupplicantState.FOUR_WAY_HANDSHAKE; 873 else { 874 try { 875 return SupplicantState.valueOf(stateName.toUpperCase(Locale.ROOT)); 876 } catch (IllegalArgumentException e) { 877 return SupplicantState.INVALID; 878 } 879 } 880 } 881 882 /** 883 * Remove double quotes (") surrounding a SSID string, if present. Otherwise, return the 884 * string unmodified. Return null if the input string was null. 885 * @hide 886 */ 887 @Nullable 888 @SystemApi sanitizeSsid(@ullable String string)889 public static String sanitizeSsid(@Nullable String string) { 890 return removeDoubleQuotes(string); 891 } 892 893 /** @hide */ 894 @UnsupportedAppUsage 895 @Nullable removeDoubleQuotes(@ullable String string)896 public static String removeDoubleQuotes(@Nullable String string) { 897 if (string == null) return null; 898 final int length = string.length(); 899 if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) { 900 return string.substring(1, length - 1); 901 } 902 return string; 903 } 904 905 @Override toString()906 public String toString() { 907 StringBuffer sb = new StringBuffer(); 908 String none = "<none>"; 909 910 sb.append("SSID: ").append(mWifiSsid == null ? WifiManager.UNKNOWN_SSID : mWifiSsid) 911 .append(", BSSID: ").append(mBSSID == null ? none : mBSSID) 912 .append(", MAC: ").append(mMacAddress == null ? none : mMacAddress) 913 .append(", Supplicant state: ") 914 .append(mSupplicantState == null ? none : mSupplicantState) 915 .append(", Wi-Fi standard: ").append(mWifiStandard) 916 .append(", RSSI: ").append(mRssi) 917 .append(", Link speed: ").append(mLinkSpeed).append(LINK_SPEED_UNITS) 918 .append(", Tx Link speed: ").append(mTxLinkSpeed).append(LINK_SPEED_UNITS) 919 .append(", Max Supported Tx Link speed: ") 920 .append(mMaxSupportedTxLinkSpeed).append(LINK_SPEED_UNITS) 921 .append(", Rx Link speed: ").append(mRxLinkSpeed).append(LINK_SPEED_UNITS) 922 .append(", Max Supported Rx Link speed: ") 923 .append(mMaxSupportedRxLinkSpeed).append(LINK_SPEED_UNITS) 924 .append(", Frequency: ").append(mFrequency).append(FREQUENCY_UNITS) 925 .append(", Net ID: ").append(mNetworkId) 926 .append(", Metered hint: ").append(mMeteredHint) 927 .append(", score: ").append(Integer.toString(score)); 928 return sb.toString(); 929 } 930 931 /** Implement the Parcelable interface {@hide} */ describeContents()932 public int describeContents() { 933 return 0; 934 } 935 936 /** Implement the Parcelable interface {@hide} */ writeToParcel(Parcel dest, int flags)937 public void writeToParcel(Parcel dest, int flags) { 938 dest.writeInt(mNetworkId); 939 dest.writeInt(mRssi); 940 dest.writeInt(mLinkSpeed); 941 dest.writeInt(mTxLinkSpeed); 942 dest.writeInt(mRxLinkSpeed); 943 dest.writeInt(mFrequency); 944 if (mIpAddress != null) { 945 dest.writeByte((byte)1); 946 dest.writeByteArray(mIpAddress.getAddress()); 947 } else { 948 dest.writeByte((byte)0); 949 } 950 if (mWifiSsid != null) { 951 dest.writeInt(1); 952 mWifiSsid.writeToParcel(dest, flags); 953 } else { 954 dest.writeInt(0); 955 } 956 dest.writeString(mBSSID); 957 dest.writeString(mMacAddress); 958 dest.writeInt(mMeteredHint ? 1 : 0); 959 dest.writeInt(mEphemeral ? 1 : 0); 960 dest.writeInt(mTrusted ? 1 : 0); 961 dest.writeInt(score); 962 dest.writeLong(txSuccess); 963 dest.writeDouble(mSuccessfulTxPacketsPerSecond); 964 dest.writeLong(txRetries); 965 dest.writeDouble(mTxRetriedTxPacketsPerSecond); 966 dest.writeLong(txBad); 967 dest.writeDouble(mLostTxPacketsPerSecond); 968 dest.writeLong(rxSuccess); 969 dest.writeDouble(mSuccessfulRxPacketsPerSecond); 970 mSupplicantState.writeToParcel(dest, flags); 971 dest.writeInt(mOsuAp ? 1 : 0); 972 dest.writeString(mRequestingPackageName); 973 dest.writeString(mFqdn); 974 dest.writeString(mProviderFriendlyName); 975 dest.writeInt(mWifiStandard); 976 dest.writeInt(mMaxSupportedTxLinkSpeed); 977 dest.writeInt(mMaxSupportedRxLinkSpeed); 978 dest.writeString(mPasspointUniqueId); 979 } 980 981 /** Implement the Parcelable interface {@hide} */ 982 @UnsupportedAppUsage 983 public static final @android.annotation.NonNull Creator<WifiInfo> CREATOR = 984 new Creator<WifiInfo>() { 985 public WifiInfo createFromParcel(Parcel in) { 986 WifiInfo info = new WifiInfo(); 987 info.setNetworkId(in.readInt()); 988 info.setRssi(in.readInt()); 989 info.setLinkSpeed(in.readInt()); 990 info.setTxLinkSpeedMbps(in.readInt()); 991 info.setRxLinkSpeedMbps(in.readInt()); 992 info.setFrequency(in.readInt()); 993 if (in.readByte() == 1) { 994 try { 995 info.setInetAddress(InetAddress.getByAddress(in.createByteArray())); 996 } catch (UnknownHostException e) {} 997 } 998 if (in.readInt() == 1) { 999 info.mWifiSsid = WifiSsid.CREATOR.createFromParcel(in); 1000 } 1001 info.mBSSID = in.readString(); 1002 info.mMacAddress = in.readString(); 1003 info.mMeteredHint = in.readInt() != 0; 1004 info.mEphemeral = in.readInt() != 0; 1005 info.mTrusted = in.readInt() != 0; 1006 info.score = in.readInt(); 1007 info.txSuccess = in.readLong(); 1008 info.mSuccessfulTxPacketsPerSecond = in.readDouble(); 1009 info.txRetries = in.readLong(); 1010 info.mTxRetriedTxPacketsPerSecond = in.readDouble(); 1011 info.txBad = in.readLong(); 1012 info.mLostTxPacketsPerSecond = in.readDouble(); 1013 info.rxSuccess = in.readLong(); 1014 info.mSuccessfulRxPacketsPerSecond = in.readDouble(); 1015 info.mSupplicantState = SupplicantState.CREATOR.createFromParcel(in); 1016 info.mOsuAp = in.readInt() != 0; 1017 info.mRequestingPackageName = in.readString(); 1018 info.mFqdn = in.readString(); 1019 info.mProviderFriendlyName = in.readString(); 1020 info.mWifiStandard = in.readInt(); 1021 info.mMaxSupportedTxLinkSpeed = in.readInt(); 1022 info.mMaxSupportedRxLinkSpeed = in.readInt(); 1023 info.mPasspointUniqueId = in.readString(); 1024 return info; 1025 } 1026 1027 public WifiInfo[] newArray(int size) { 1028 return new WifiInfo[size]; 1029 } 1030 }; 1031 1032 /** 1033 * Set the Passpoint unique identifier for the current connection 1034 * 1035 * @param passpointUniqueId Unique identifier 1036 * @hide 1037 */ setPasspointUniqueId(@ullable String passpointUniqueId)1038 public void setPasspointUniqueId(@Nullable String passpointUniqueId) { 1039 mPasspointUniqueId = passpointUniqueId; 1040 } 1041 1042 /** 1043 * Get the Passpoint unique identifier for the current connection 1044 * 1045 * @return Passpoint unique identifier 1046 * @hide 1047 */ getPasspointUniqueId()1048 public @Nullable String getPasspointUniqueId() { 1049 return mPasspointUniqueId; 1050 } 1051 } 1052