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 static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID; 20 21 import android.Manifest; 22 import android.annotation.IntDef; 23 import android.annotation.IntRange; 24 import android.annotation.NonNull; 25 import android.annotation.Nullable; 26 import android.annotation.RequiresPermission; 27 import android.annotation.SystemApi; 28 import android.compat.annotation.UnsupportedAppUsage; 29 import android.net.ConnectivityManager; 30 import android.net.ConnectivityManager.NetworkCallback; 31 import android.net.LinkProperties; 32 import android.net.Network; 33 import android.net.NetworkCapabilities; 34 import android.net.NetworkInfo.DetailedState; 35 import android.net.TransportInfo; 36 import android.os.Build; 37 import android.os.Parcel; 38 import android.os.Parcelable; 39 import android.telephony.SubscriptionManager; 40 import android.text.TextUtils; 41 42 import androidx.annotation.RequiresApi; 43 44 import com.android.modules.utils.build.SdkLevel; 45 import com.android.net.module.util.Inet4AddressUtils; 46 47 import java.lang.annotation.Retention; 48 import java.lang.annotation.RetentionPolicy; 49 import java.net.Inet4Address; 50 import java.net.InetAddress; 51 import java.net.UnknownHostException; 52 import java.util.ArrayList; 53 import java.util.EnumMap; 54 import java.util.List; 55 import java.util.Locale; 56 import java.util.Objects; 57 58 /** 59 * Describes the state of any Wi-Fi connection that is active or 60 * is in the process of being set up. 61 * 62 * In the connected state, access to location sensitive fields requires 63 * the same permissions as {@link WifiManager#getScanResults}. If such access is not allowed, 64 * {@link #getSSID} will return {@link WifiManager#UNKNOWN_SSID} and 65 * {@link #getBSSID} will return {@code "02:00:00:00:00:00"}. 66 * {@link #getNetworkId()} will return {@code -1}. 67 * {@link #getPasspointFqdn()} will return null. 68 * {@link #getPasspointProviderFriendlyName()} will return null. 69 * {@link #getInformationElements()} will return null. 70 * {@link #getMacAddress()} will return {@code "02:00:00:00:00:00"}. 71 */ 72 public class WifiInfo implements TransportInfo, Parcelable { 73 private static final String TAG = "WifiInfo"; 74 /** 75 * This is the map described in the Javadoc comment above. The positions 76 * of the elements of the array must correspond to the ordinal values 77 * of <code>DetailedState</code>. 78 */ 79 private static final EnumMap<SupplicantState, DetailedState> stateMap = 80 new EnumMap<SupplicantState, DetailedState>(SupplicantState.class); 81 82 /** 83 * Default MAC address reported to a client that does not have the 84 * android.permission.LOCAL_MAC_ADDRESS permission. 85 * 86 * @hide 87 */ 88 @SystemApi 89 public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00"; 90 91 static { stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED)92 stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED); stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED)93 stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED); stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE)94 stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE); stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING)95 stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING); stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING)96 stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING); stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING)97 stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING); stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING)98 stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING); stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING)99 stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING); stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING)100 stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING); stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR)101 stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR); stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED)102 stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED); stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE)103 stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE); stateMap.put(SupplicantState.INVALID, DetailedState.FAILED)104 stateMap.put(SupplicantState.INVALID, DetailedState.FAILED); 105 } 106 107 private SupplicantState mSupplicantState; 108 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 109 private String mBSSID; 110 @UnsupportedAppUsage 111 private WifiSsid mWifiSsid; 112 private int mNetworkId; 113 private int mSecurityType; 114 115 /** 116 * Used to indicate that the RSSI is invalid, for example if no RSSI measurements are available 117 * yet. 118 * @hide 119 */ 120 @SystemApi 121 public static final int INVALID_RSSI = -127; 122 123 /** @hide **/ 124 public static final int MIN_RSSI = -126; 125 126 /** @hide **/ 127 public static final int MAX_RSSI = 200; 128 129 /** Unknown security type. */ 130 public static final int SECURITY_TYPE_UNKNOWN = -1; 131 /** Security type for an open network. */ 132 public static final int SECURITY_TYPE_OPEN = 0; 133 /** Security type for a WEP network. */ 134 public static final int SECURITY_TYPE_WEP = 1; 135 /** Security type for a PSK network. */ 136 public static final int SECURITY_TYPE_PSK = 2; 137 /** Security type for an EAP network. */ 138 public static final int SECURITY_TYPE_EAP = 3; 139 /** Security type for an SAE network. */ 140 public static final int SECURITY_TYPE_SAE = 4; 141 /** Security type for a WPA3-Enterprise in 192-bit security network. */ 142 public static final int SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT = 5; 143 /** Security type for an OWE network. */ 144 public static final int SECURITY_TYPE_OWE = 6; 145 /** Security type for a WAPI PSK network. */ 146 public static final int SECURITY_TYPE_WAPI_PSK = 7; 147 /** Security type for a WAPI Certificate network. */ 148 public static final int SECURITY_TYPE_WAPI_CERT = 8; 149 /** Security type for a WPA3-Enterprise network. */ 150 public static final int SECURITY_TYPE_EAP_WPA3_ENTERPRISE = 9; 151 /** Security type for an OSEN network. */ 152 public static final int SECURITY_TYPE_OSEN = 10; 153 /** Security type for a Passpoint R1/R2 network, where TKIP and WEP are not allowed. */ 154 public static final int SECURITY_TYPE_PASSPOINT_R1_R2 = 11; 155 /** 156 * Security type for a Passpoint R3 network, where TKIP and WEP are not allowed, 157 * and PMF must be set to Required. 158 */ 159 public static final int SECURITY_TYPE_PASSPOINT_R3 = 12; 160 161 /** 162 * Security type of current connection. 163 * @hide 164 */ 165 @Retention(RetentionPolicy.SOURCE) 166 @IntDef(prefix = { "SECURITY_TYPE_" }, value = { 167 SECURITY_TYPE_UNKNOWN, 168 SECURITY_TYPE_OPEN, 169 SECURITY_TYPE_WEP, 170 SECURITY_TYPE_PSK, 171 SECURITY_TYPE_EAP, 172 SECURITY_TYPE_SAE, 173 SECURITY_TYPE_OWE, 174 SECURITY_TYPE_WAPI_PSK, 175 SECURITY_TYPE_WAPI_CERT, 176 SECURITY_TYPE_EAP_WPA3_ENTERPRISE, 177 SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT, 178 SECURITY_TYPE_PASSPOINT_R1_R2, 179 SECURITY_TYPE_PASSPOINT_R3, 180 }) 181 public @interface SecurityType {} 182 183 /** @see #isPrimary() - No permission to access the field. */ 184 private static final int IS_PRIMARY_NO_PERMISSION = -1; 185 /** @see #isPrimary() - false */ 186 private static final int IS_PRIMARY_FALSE = 0; 187 /** @see #isPrimary() - true */ 188 private static final int IS_PRIMARY_TRUE = 1; 189 /** Tri state to store {@link #isPrimary()} field. */ 190 /** @hide */ 191 @Retention(RetentionPolicy.SOURCE) 192 @IntDef(prefix = { "IS_PRIMARY_" }, value = { 193 IS_PRIMARY_NO_PERMISSION, IS_PRIMARY_FALSE, IS_PRIMARY_TRUE 194 }) 195 public @interface IsPrimaryValues {} 196 197 /** 198 * Received Signal Strength Indicator 199 */ 200 private int mRssi; 201 202 /** 203 * Wi-Fi standard for the connection 204 */ 205 private @WifiAnnotations.WifiStandard int mWifiStandard; 206 207 /** 208 * The unit in which links speeds are expressed. 209 */ 210 public static final String LINK_SPEED_UNITS = "Mbps"; 211 private int mLinkSpeed; 212 213 /** 214 * Constant for unknown link speed. 215 */ 216 public static final int LINK_SPEED_UNKNOWN = -1; 217 218 /** 219 * Tx(transmit) Link speed in Mbps 220 */ 221 private int mTxLinkSpeed; 222 223 /** 224 * Max supported Tx(transmit) link speed in Mbps 225 */ 226 private int mMaxSupportedTxLinkSpeed; 227 228 /** 229 * Rx(receive) Link speed in Mbps 230 */ 231 private int mRxLinkSpeed; 232 233 /** 234 * Max supported Rx(receive) link speed in Mbps 235 */ 236 private int mMaxSupportedRxLinkSpeed; 237 238 /** 239 * Frequency in MHz 240 */ 241 public static final String FREQUENCY_UNITS = "MHz"; 242 private int mFrequency; 243 244 @UnsupportedAppUsage 245 private InetAddress mIpAddress; 246 @UnsupportedAppUsage 247 private String mMacAddress = DEFAULT_MAC_ADDRESS; 248 249 /** 250 * Whether the network is ephemeral or not. 251 */ 252 private boolean mEphemeral; 253 254 /** 255 * Whether the network is trusted or not. 256 */ 257 private boolean mTrusted; 258 259 /** 260 * Whether the network is oem paid or not. 261 */ 262 private boolean mOemPaid; 263 264 /** 265 * Whether the network is oem private or not. 266 */ 267 private boolean mOemPrivate; 268 269 /** 270 * Whether the network is a carrier merged network. 271 */ 272 private boolean mCarrierMerged; 273 274 /** 275 * OSU (Online Sign Up) AP for Passpoint R2. 276 */ 277 private boolean mOsuAp; 278 279 /** 280 * Fully qualified domain name of a Passpoint configuration 281 */ 282 private String mFqdn; 283 284 /** 285 * Name of Passpoint credential provider 286 */ 287 private String mProviderFriendlyName; 288 289 /** 290 * If connected to a network suggestion or specifier, store the package name of the app, 291 * else null. 292 */ 293 private String mRequestingPackageName; 294 295 /** 296 * Identify which Telephony subscription provides this network. 297 */ 298 private int mSubscriptionId; 299 300 /** 301 * Running total count of lost (not ACKed) transmitted unicast data packets. 302 * @hide 303 */ 304 public long txBad; 305 /** 306 * Running total count of transmitted unicast data retry packets. 307 * @hide 308 */ 309 public long txRetries; 310 /** 311 * Running total count of successfully transmitted (ACKed) unicast data packets. 312 * @hide 313 */ 314 public long txSuccess; 315 /** 316 * Running total count of received unicast data packets. 317 * @hide 318 */ 319 public long rxSuccess; 320 321 private double mLostTxPacketsPerSecond; 322 323 /** 324 * Average rate of lost transmitted packets, in units of packets per second. 325 * @hide 326 */ 327 @SystemApi getLostTxPacketsPerSecond()328 public double getLostTxPacketsPerSecond() { 329 return mLostTxPacketsPerSecond; 330 } 331 332 /** @hide */ setLostTxPacketsPerSecond(double lostTxPacketsPerSecond)333 public void setLostTxPacketsPerSecond(double lostTxPacketsPerSecond) { 334 mLostTxPacketsPerSecond = lostTxPacketsPerSecond; 335 } 336 337 private double mTxRetriedTxPacketsPerSecond; 338 339 /** 340 * Average rate of transmitted retry packets, in units of packets per second. 341 * @hide 342 */ 343 @SystemApi getRetriedTxPacketsPerSecond()344 public double getRetriedTxPacketsPerSecond() { 345 return mTxRetriedTxPacketsPerSecond; 346 } 347 348 /** @hide */ setRetriedTxPacketsRate(double txRetriedTxPacketsPerSecond)349 public void setRetriedTxPacketsRate(double txRetriedTxPacketsPerSecond) { 350 mTxRetriedTxPacketsPerSecond = txRetriedTxPacketsPerSecond; 351 } 352 353 private double mSuccessfulTxPacketsPerSecond; 354 355 /** 356 * Average rate of successfully transmitted unicast packets, in units of packets per second. 357 * @hide 358 */ 359 @SystemApi getSuccessfulTxPacketsPerSecond()360 public double getSuccessfulTxPacketsPerSecond() { 361 return mSuccessfulTxPacketsPerSecond; 362 } 363 364 /** @hide */ setSuccessfulTxPacketsPerSecond(double successfulTxPacketsPerSecond)365 public void setSuccessfulTxPacketsPerSecond(double successfulTxPacketsPerSecond) { 366 mSuccessfulTxPacketsPerSecond = successfulTxPacketsPerSecond; 367 } 368 369 private double mSuccessfulRxPacketsPerSecond; 370 371 /** 372 * Average rate of received unicast data packets, in units of packets per second. 373 * @hide 374 */ 375 @SystemApi getSuccessfulRxPacketsPerSecond()376 public double getSuccessfulRxPacketsPerSecond() { 377 return mSuccessfulRxPacketsPerSecond; 378 } 379 380 /** @hide */ setSuccessfulRxPacketsPerSecond(double successfulRxPacketsPerSecond)381 public void setSuccessfulRxPacketsPerSecond(double successfulRxPacketsPerSecond) { 382 mSuccessfulRxPacketsPerSecond = successfulRxPacketsPerSecond; 383 } 384 385 /** @hide */ 386 @UnsupportedAppUsage 387 public int score; 388 389 /** 390 * The current Wifi score. 391 * NOTE: this value should only be used for debugging purposes. Do not rely on this value for 392 * any computations. The meaning of this value can and will change at any time without warning. 393 * @hide 394 */ 395 @SystemApi getScore()396 public int getScore() { 397 return score; 398 } 399 400 /** @hide */ setScore(int score)401 public void setScore(int score) { 402 this.score = score; 403 } 404 405 /** 406 * Flag indicating that AP has hinted that upstream connection is metered, 407 * and sensitive to heavy data transfers. 408 */ 409 private boolean mMeteredHint; 410 411 /** 412 * Passpoint unique key 413 */ 414 private String mPasspointUniqueId; 415 416 /** 417 * information elements found in the beacon of the connected bssid. 418 */ 419 @Nullable 420 private List<ScanResult.InformationElement> mInformationElements; 421 422 /** 423 * @see #isPrimary() 424 * The field is stored as an int since is a tristate internally - true, false, no permission. 425 */ 426 private @IsPrimaryValues int mIsPrimary; 427 428 /** @hide */ 429 @UnsupportedAppUsage WifiInfo()430 public WifiInfo() { 431 mWifiSsid = null; 432 mBSSID = null; 433 mNetworkId = -1; 434 mSupplicantState = SupplicantState.UNINITIALIZED; 435 mRssi = INVALID_RSSI; 436 mLinkSpeed = LINK_SPEED_UNKNOWN; 437 mFrequency = -1; 438 mSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 439 mSecurityType = -1; 440 mIsPrimary = IS_PRIMARY_FALSE; 441 } 442 443 /** @hide */ reset()444 public void reset() { 445 setInetAddress(null); 446 setBSSID(null); 447 setSSID(null); 448 setNetworkId(-1); 449 setRssi(INVALID_RSSI); 450 setLinkSpeed(LINK_SPEED_UNKNOWN); 451 setTxLinkSpeedMbps(LINK_SPEED_UNKNOWN); 452 setRxLinkSpeedMbps(LINK_SPEED_UNKNOWN); 453 setMaxSupportedTxLinkSpeedMbps(LINK_SPEED_UNKNOWN); 454 setMaxSupportedRxLinkSpeedMbps(LINK_SPEED_UNKNOWN); 455 setFrequency(-1); 456 setMeteredHint(false); 457 setEphemeral(false); 458 setTrusted(false); 459 setOemPaid(false); 460 setOemPrivate(false); 461 setCarrierMerged(false); 462 setOsuAp(false); 463 setRequestingPackageName(null); 464 setFQDN(null); 465 setProviderFriendlyName(null); 466 setPasspointUniqueId(null); 467 setSubscriptionId(SubscriptionManager.INVALID_SUBSCRIPTION_ID); 468 setInformationElements(null); 469 setIsPrimary(false); 470 txBad = 0; 471 txSuccess = 0; 472 rxSuccess = 0; 473 txRetries = 0; 474 mLostTxPacketsPerSecond = 0; 475 mSuccessfulTxPacketsPerSecond = 0; 476 mSuccessfulRxPacketsPerSecond = 0; 477 mTxRetriedTxPacketsPerSecond = 0; 478 score = 0; 479 mSecurityType = -1; 480 } 481 482 /** 483 * Copy constructor 484 * @hide 485 */ WifiInfo(WifiInfo source)486 public WifiInfo(WifiInfo source) { 487 this(source, NetworkCapabilities.REDACT_NONE); 488 } 489 490 /** 491 * Copy constructor 492 * @hide 493 */ WifiInfo(WifiInfo source, long redactions)494 private WifiInfo(WifiInfo source, long redactions) { 495 if (source != null) { 496 mSupplicantState = source.mSupplicantState; 497 mBSSID = shouldRedactLocationSensitiveFields(redactions) 498 ? DEFAULT_MAC_ADDRESS : source.mBSSID; 499 mWifiSsid = shouldRedactLocationSensitiveFields(redactions) 500 ? WifiSsid.createFromHex(null) : source.mWifiSsid; 501 mNetworkId = shouldRedactLocationSensitiveFields(redactions) 502 ? INVALID_NETWORK_ID : source.mNetworkId; 503 mRssi = source.mRssi; 504 mLinkSpeed = source.mLinkSpeed; 505 mTxLinkSpeed = source.mTxLinkSpeed; 506 mRxLinkSpeed = source.mRxLinkSpeed; 507 mFrequency = source.mFrequency; 508 mIpAddress = source.mIpAddress; 509 mMacAddress = (shouldRedactLocalMacAddressFields(redactions) 510 || shouldRedactLocationSensitiveFields(redactions)) 511 ? DEFAULT_MAC_ADDRESS : source.mMacAddress; 512 mMeteredHint = source.mMeteredHint; 513 mEphemeral = source.mEphemeral; 514 mTrusted = source.mTrusted; 515 mOemPaid = source.mOemPaid; 516 mOemPrivate = source.mOemPrivate; 517 mCarrierMerged = source.mCarrierMerged; 518 mRequestingPackageName = 519 source.mRequestingPackageName; 520 mOsuAp = source.mOsuAp; 521 mFqdn = shouldRedactLocationSensitiveFields(redactions) 522 ? null : source.mFqdn; 523 mProviderFriendlyName = shouldRedactLocationSensitiveFields(redactions) 524 ? null : source.mProviderFriendlyName; 525 mSubscriptionId = source.mSubscriptionId; 526 txBad = source.txBad; 527 txRetries = source.txRetries; 528 txSuccess = source.txSuccess; 529 rxSuccess = source.rxSuccess; 530 mLostTxPacketsPerSecond = source.mLostTxPacketsPerSecond; 531 mTxRetriedTxPacketsPerSecond = source.mTxRetriedTxPacketsPerSecond; 532 mSuccessfulTxPacketsPerSecond = source.mSuccessfulTxPacketsPerSecond; 533 mSuccessfulRxPacketsPerSecond = source.mSuccessfulRxPacketsPerSecond; 534 score = source.score; 535 mWifiStandard = source.mWifiStandard; 536 mMaxSupportedTxLinkSpeed = source.mMaxSupportedTxLinkSpeed; 537 mMaxSupportedRxLinkSpeed = source.mMaxSupportedRxLinkSpeed; 538 mPasspointUniqueId = shouldRedactLocationSensitiveFields(redactions) 539 ? null : source.mPasspointUniqueId; 540 if (source.mInformationElements != null 541 && !shouldRedactLocationSensitiveFields(redactions)) { 542 mInformationElements = new ArrayList<>(source.mInformationElements); 543 } 544 mIsPrimary = shouldRedactNetworkSettingsFields(redactions) 545 ? IS_PRIMARY_NO_PERMISSION : source.mIsPrimary; 546 mSecurityType = source.mSecurityType; 547 } 548 } 549 550 /** Builder for WifiInfo */ 551 public static final class Builder { 552 private final WifiInfo mWifiInfo = new WifiInfo(); 553 554 /** 555 * Set the SSID, in the form of a raw byte array. 556 * @see WifiInfo#getSSID() 557 */ 558 @NonNull setSsid(@onNull byte[] ssid)559 public Builder setSsid(@NonNull byte[] ssid) { 560 mWifiInfo.setSSID(WifiSsid.createFromByteArray(ssid)); 561 return this; 562 } 563 564 /** 565 * Set the BSSID. 566 * @see WifiInfo#getBSSID() 567 */ 568 @NonNull setBssid(@onNull String bssid)569 public Builder setBssid(@NonNull String bssid) { 570 mWifiInfo.setBSSID(bssid); 571 return this; 572 } 573 574 /** 575 * Set the RSSI, in dBm. 576 * @see WifiInfo#getRssi() 577 */ 578 @NonNull setRssi(int rssi)579 public Builder setRssi(int rssi) { 580 mWifiInfo.setRssi(rssi); 581 return this; 582 } 583 584 /** 585 * Set the network ID. 586 * @see WifiInfo#getNetworkId() 587 */ 588 @NonNull setNetworkId(int networkId)589 public Builder setNetworkId(int networkId) { 590 mWifiInfo.setNetworkId(networkId); 591 return this; 592 } 593 594 /** 595 * Set the current security type 596 * @see WifiInfo#getCurrentSecurityType() 597 */ 598 @NonNull setCurrentSecurityType(@ifiConfiguration.SecurityType int securityType)599 public Builder setCurrentSecurityType(@WifiConfiguration.SecurityType int securityType) { 600 mWifiInfo.setCurrentSecurityType(securityType); 601 return this; 602 } 603 604 /** 605 * Build a WifiInfo object. 606 */ 607 @NonNull build()608 public WifiInfo build() { 609 return new WifiInfo(mWifiInfo); 610 } 611 } 612 613 /** @hide */ setSSID(WifiSsid wifiSsid)614 public void setSSID(WifiSsid wifiSsid) { 615 mWifiSsid = wifiSsid; 616 } 617 618 /** 619 * Returns the service set identifier (SSID) of the current 802.11 network. 620 * <p> 621 * If the SSID can be decoded as UTF-8, it will be returned surrounded by double 622 * quotation marks. Otherwise, it is returned as a string of hex digits. 623 * The SSID may be {@link WifiManager#UNKNOWN_SSID}, if there is no network currently connected 624 * or if the caller has insufficient permissions to access the SSID. 625 * </p> 626 * <p> 627 * Prior to {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method 628 * always returned the SSID with no quotes around it. 629 * </p> 630 * 631 * @return the SSID. 632 */ getSSID()633 public String getSSID() { 634 if (mWifiSsid != null) { 635 String unicode = mWifiSsid.toString(); 636 if (!TextUtils.isEmpty(unicode)) { 637 return "\"" + unicode + "\""; 638 } else { 639 String hex = mWifiSsid.getHexString(); 640 return (hex != null) ? hex : WifiManager.UNKNOWN_SSID; 641 } 642 } 643 return WifiManager.UNKNOWN_SSID; 644 } 645 646 /** @hide */ 647 @UnsupportedAppUsage getWifiSsid()648 public WifiSsid getWifiSsid() { 649 return mWifiSsid; 650 } 651 652 /** @hide */ 653 @UnsupportedAppUsage setBSSID(String BSSID)654 public void setBSSID(String BSSID) { 655 mBSSID = BSSID; 656 } 657 658 /** 659 * Return the basic service set identifier (BSSID) of the current access point. 660 * <p> 661 * The BSSID may be 662 * <lt>{@code null}, if there is no network currently connected.</lt> 663 * <lt>{@code "02:00:00:00:00:00"}, if the caller has insufficient permissions to access the 664 * BSSID.<lt> 665 * </p> 666 * 667 * @return the BSSID, in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX} 668 */ getBSSID()669 public String getBSSID() { 670 return mBSSID; 671 } 672 673 /** 674 * Returns the received signal strength indicator of the current 802.11 675 * network, in dBm. 676 * 677 * <p>Use {@link android.net.wifi.WifiManager#calculateSignalLevel} to convert this number into 678 * an absolute signal level which can be displayed to a user. 679 * 680 * @return the RSSI. 681 */ getRssi()682 public int getRssi() { 683 return mRssi; 684 } 685 686 /** @hide */ 687 @UnsupportedAppUsage setRssi(int rssi)688 public void setRssi(int rssi) { 689 if (rssi < INVALID_RSSI) 690 rssi = INVALID_RSSI; 691 if (rssi > MAX_RSSI) 692 rssi = MAX_RSSI; 693 mRssi = rssi; 694 } 695 696 /** 697 * Sets the Wi-Fi standard 698 * @hide 699 */ setWifiStandard(@ifiAnnotations.WifiStandard int wifiStandard)700 public void setWifiStandard(@WifiAnnotations.WifiStandard int wifiStandard) { 701 mWifiStandard = wifiStandard; 702 } 703 704 /** 705 * Get connection Wi-Fi standard 706 * @return the connection Wi-Fi standard 707 */ getWifiStandard()708 public @WifiAnnotations.WifiStandard int getWifiStandard() { 709 return mWifiStandard; 710 } 711 712 /** 713 * Returns the current link speed in {@link #LINK_SPEED_UNITS}. 714 * @return the link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown. 715 * @see #LINK_SPEED_UNITS 716 * @see #LINK_SPEED_UNKNOWN 717 */ getLinkSpeed()718 public int getLinkSpeed() { 719 return mLinkSpeed; 720 } 721 722 /** @hide */ 723 @UnsupportedAppUsage setLinkSpeed(int linkSpeed)724 public void setLinkSpeed(int linkSpeed) { 725 mLinkSpeed = linkSpeed; 726 } 727 728 /** 729 * Returns the current transmit link speed in Mbps. 730 * @return the Tx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown. 731 * @see #LINK_SPEED_UNKNOWN 732 */ 733 @IntRange(from = -1) getTxLinkSpeedMbps()734 public int getTxLinkSpeedMbps() { 735 return mTxLinkSpeed; 736 } 737 738 /** 739 * Returns the maximum supported transmit link speed in Mbps 740 * @return the max supported tx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is 741 * unknown. @see #LINK_SPEED_UNKNOWN 742 */ getMaxSupportedTxLinkSpeedMbps()743 public int getMaxSupportedTxLinkSpeedMbps() { 744 return mMaxSupportedTxLinkSpeed; 745 } 746 747 /** 748 * Update the last transmitted packet bit rate in Mbps. 749 * @hide 750 */ setTxLinkSpeedMbps(int txLinkSpeed)751 public void setTxLinkSpeedMbps(int txLinkSpeed) { 752 mTxLinkSpeed = txLinkSpeed; 753 } 754 755 /** 756 * Set the maximum supported transmit link speed in Mbps 757 * @hide 758 */ setMaxSupportedTxLinkSpeedMbps(int maxSupportedTxLinkSpeed)759 public void setMaxSupportedTxLinkSpeedMbps(int maxSupportedTxLinkSpeed) { 760 mMaxSupportedTxLinkSpeed = maxSupportedTxLinkSpeed; 761 } 762 763 /** 764 * Returns the current receive link speed in Mbps. 765 * @return the Rx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown. 766 * @see #LINK_SPEED_UNKNOWN 767 */ 768 @IntRange(from = -1) getRxLinkSpeedMbps()769 public int getRxLinkSpeedMbps() { 770 return mRxLinkSpeed; 771 } 772 773 /** 774 * Returns the maximum supported receive link speed in Mbps 775 * @return the max supported Rx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is 776 * unknown. @see #LINK_SPEED_UNKNOWN 777 */ getMaxSupportedRxLinkSpeedMbps()778 public int getMaxSupportedRxLinkSpeedMbps() { 779 return mMaxSupportedRxLinkSpeed; 780 } 781 782 /** 783 * Update the last received packet bit rate in Mbps. 784 * @hide 785 */ setRxLinkSpeedMbps(int rxLinkSpeed)786 public void setRxLinkSpeedMbps(int rxLinkSpeed) { 787 mRxLinkSpeed = rxLinkSpeed; 788 } 789 790 /** 791 * Set the maximum supported receive link speed in Mbps 792 * @hide 793 */ setMaxSupportedRxLinkSpeedMbps(int maxSupportedRxLinkSpeed)794 public void setMaxSupportedRxLinkSpeedMbps(int maxSupportedRxLinkSpeed) { 795 mMaxSupportedRxLinkSpeed = maxSupportedRxLinkSpeed; 796 } 797 798 /** 799 * Returns the current frequency in {@link #FREQUENCY_UNITS}. 800 * @return the frequency. 801 * @see #FREQUENCY_UNITS 802 */ getFrequency()803 public int getFrequency() { 804 return mFrequency; 805 } 806 807 /** @hide */ setFrequency(int frequency)808 public void setFrequency(int frequency) { 809 this.mFrequency = frequency; 810 } 811 812 /** 813 * @hide 814 */ is24GHz()815 public boolean is24GHz() { 816 return ScanResult.is24GHz(mFrequency); 817 } 818 819 /** 820 * @hide 821 */ 822 @UnsupportedAppUsage is5GHz()823 public boolean is5GHz() { 824 return ScanResult.is5GHz(mFrequency); 825 } 826 827 /** 828 * @hide 829 */ is6GHz()830 public boolean is6GHz() { 831 return ScanResult.is6GHz(mFrequency); 832 } 833 834 /** 835 * Record the MAC address of the WLAN interface 836 * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form 837 * @hide 838 */ 839 @UnsupportedAppUsage setMacAddress(String macAddress)840 public void setMacAddress(String macAddress) { 841 this.mMacAddress = macAddress; 842 } 843 844 /** 845 * Returns the MAC address used for this connection. 846 * @return MAC address of the connection or {@code "02:00:00:00:00:00"} if the caller has 847 * insufficient permission. 848 */ 849 @RequiresPermission(allOf = { 850 Manifest.permission.LOCAL_MAC_ADDRESS, 851 Manifest.permission.ACCESS_FINE_LOCATION 852 }) getMacAddress()853 public String getMacAddress() { 854 return mMacAddress; 855 } 856 857 /** 858 * @return true if {@link #getMacAddress()} has a real MAC address. 859 * 860 * @hide 861 */ hasRealMacAddress()862 public boolean hasRealMacAddress() { 863 return mMacAddress != null && !DEFAULT_MAC_ADDRESS.equals(mMacAddress); 864 } 865 866 /** 867 * Indicates if we've dynamically detected this active network connection as 868 * being metered. 869 * 870 * @see WifiConfiguration#isMetered(WifiConfiguration, WifiInfo) 871 * @hide 872 */ setMeteredHint(boolean meteredHint)873 public void setMeteredHint(boolean meteredHint) { 874 mMeteredHint = meteredHint; 875 } 876 877 /** {@hide} */ 878 @UnsupportedAppUsage getMeteredHint()879 public boolean getMeteredHint() { 880 return mMeteredHint; 881 } 882 883 /** {@hide} */ setEphemeral(boolean ephemeral)884 public void setEphemeral(boolean ephemeral) { 885 mEphemeral = ephemeral; 886 } 887 888 /** 889 * Returns true if the current Wifi network is ephemeral, false otherwise. 890 * An ephemeral network is a network that is temporary and not persisted in the system. 891 * Ephemeral networks cannot be forgotten, only disabled with 892 * {@link WifiManager#disableEphemeralNetwork(String)}. 893 * 894 * @hide 895 */ 896 @SystemApi isEphemeral()897 public boolean isEphemeral() { 898 return mEphemeral; 899 } 900 901 /** {@hide} */ setTrusted(boolean trusted)902 public void setTrusted(boolean trusted) { 903 mTrusted = trusted; 904 } 905 906 /** 907 * Returns true if the current Wifi network is a trusted network, false otherwise. 908 * @see WifiNetworkSuggestion.Builder#setUntrusted(boolean). 909 * {@hide} 910 */ 911 @SystemApi isTrusted()912 public boolean isTrusted() { 913 return mTrusted; 914 } 915 916 /** {@hide} */ setOemPaid(boolean oemPaid)917 public void setOemPaid(boolean oemPaid) { 918 mOemPaid = oemPaid; 919 } 920 921 /** 922 * Returns true if the current Wifi network is an oem paid network, false otherwise. 923 * @see WifiNetworkSuggestion.Builder#setOemPaid(boolean). 924 * {@hide} 925 */ 926 @RequiresApi(Build.VERSION_CODES.S) 927 @SystemApi isOemPaid()928 public boolean isOemPaid() { 929 if (!SdkLevel.isAtLeastS()) { 930 throw new UnsupportedOperationException(); 931 } 932 return mOemPaid; 933 } 934 935 /** {@hide} */ setOemPrivate(boolean oemPrivate)936 public void setOemPrivate(boolean oemPrivate) { 937 mOemPrivate = oemPrivate; 938 } 939 940 /** 941 * Returns true if the current Wifi network is an oem private network, false otherwise. 942 * @see WifiNetworkSuggestion.Builder#setOemPrivate(boolean). 943 * {@hide} 944 */ 945 @RequiresApi(Build.VERSION_CODES.S) 946 @SystemApi isOemPrivate()947 public boolean isOemPrivate() { 948 if (!SdkLevel.isAtLeastS()) { 949 throw new UnsupportedOperationException(); 950 } 951 return mOemPrivate; 952 } 953 954 /** 955 * {@hide} 956 */ setCarrierMerged(boolean carrierMerged)957 public void setCarrierMerged(boolean carrierMerged) { 958 mCarrierMerged = carrierMerged; 959 } 960 961 /** 962 * Returns true if the current Wifi network is a carrier merged network, false otherwise. 963 * @see WifiNetworkSuggestion.Builder#setCarrierMerged(boolean). 964 * {@hide} 965 */ 966 @SystemApi 967 @RequiresApi(Build.VERSION_CODES.S) isCarrierMerged()968 public boolean isCarrierMerged() { 969 if (!SdkLevel.isAtLeastS()) { 970 throw new UnsupportedOperationException(); 971 } 972 return mCarrierMerged; 973 } 974 975 976 /** {@hide} */ setOsuAp(boolean osuAp)977 public void setOsuAp(boolean osuAp) { 978 mOsuAp = osuAp; 979 } 980 981 /** {@hide} */ 982 @SystemApi isOsuAp()983 public boolean isOsuAp() { 984 return mOsuAp; 985 } 986 987 /** {@hide} */ 988 @SystemApi isPasspointAp()989 public boolean isPasspointAp() { 990 return mFqdn != null && mProviderFriendlyName != null; 991 } 992 993 /** {@hide} */ setFQDN(@ullable String fqdn)994 public void setFQDN(@Nullable String fqdn) { 995 mFqdn = fqdn; 996 } 997 998 /** 999 * Returns the Fully Qualified Domain Name of the network if it is a Passpoint network. 1000 * <p> 1001 * The FQDN may be 1002 * <lt>{@code null} if no network currently connected, currently connected network is not 1003 * passpoint network or the caller has insufficient permissions to access the FQDN.</lt> 1004 * </p> 1005 */ getPasspointFqdn()1006 public @Nullable String getPasspointFqdn() { 1007 return mFqdn; 1008 } 1009 1010 /** {@hide} */ setProviderFriendlyName(@ullable String providerFriendlyName)1011 public void setProviderFriendlyName(@Nullable String providerFriendlyName) { 1012 mProviderFriendlyName = providerFriendlyName; 1013 } 1014 1015 /** 1016 * Returns the Provider Friendly Name of the network if it is a Passpoint network. 1017 * <p> 1018 * The Provider Friendly Name may be 1019 * <lt>{@code null} if no network currently connected, currently connected network is not 1020 * passpoint network or the caller has insufficient permissions to access the Provider Friendly 1021 * Name. </lt> 1022 * </p> 1023 */ getPasspointProviderFriendlyName()1024 public @Nullable String getPasspointProviderFriendlyName() { 1025 return mProviderFriendlyName; 1026 } 1027 1028 /** {@hide} */ setRequestingPackageName(@ullable String packageName)1029 public void setRequestingPackageName(@Nullable String packageName) { 1030 mRequestingPackageName = packageName; 1031 } 1032 1033 /** 1034 * If this network was created in response to an app request (e.g. through Network Suggestion 1035 * or Network Specifier), return the package name of the app that made the request. 1036 * Null otherwise. 1037 * @hide 1038 */ 1039 @SystemApi getRequestingPackageName()1040 public @Nullable String getRequestingPackageName() { 1041 return mRequestingPackageName; 1042 } 1043 1044 /** {@hide} */ setSubscriptionId(int subId)1045 public void setSubscriptionId(int subId) { 1046 mSubscriptionId = subId; 1047 } 1048 1049 /** 1050 * If this network is provisioned by a carrier, returns subscription Id corresponding to the 1051 * associated SIM on the device. If this network is not provisioned by a carrier, returns 1052 * {@link android.telephony.SubscriptionManager#INVALID_SUBSCRIPTION_ID} 1053 * 1054 * @see WifiNetworkSuggestion.Builder#setSubscriptionId(int) 1055 * @see android.telephony.SubscriptionInfo#getSubscriptionId() 1056 */ 1057 @RequiresApi(Build.VERSION_CODES.S) getSubscriptionId()1058 public int getSubscriptionId() { 1059 if (!SdkLevel.isAtLeastS()) { 1060 throw new UnsupportedOperationException(); 1061 } 1062 return mSubscriptionId; 1063 } 1064 1065 1066 /** @hide */ 1067 @UnsupportedAppUsage setNetworkId(int id)1068 public void setNetworkId(int id) { 1069 mNetworkId = id; 1070 } 1071 1072 /** 1073 * Each configured network has a unique small integer ID, used to identify 1074 * the network. This method returns the ID for the currently connected network. 1075 * <p> 1076 * The networkId may be {@code -1} if there is no currently connected network or if the caller 1077 * has insufficient permissions to access the network ID. 1078 * </p> 1079 * 1080 * @return the network ID. 1081 */ getNetworkId()1082 public int getNetworkId() { 1083 return mNetworkId; 1084 } 1085 1086 /** 1087 * Return the detailed state of the supplicant's negotiation with an 1088 * access point, in the form of a {@link SupplicantState SupplicantState} object. 1089 * @return the current {@link SupplicantState SupplicantState} 1090 */ getSupplicantState()1091 public SupplicantState getSupplicantState() { 1092 return mSupplicantState; 1093 } 1094 1095 /** @hide */ 1096 @UnsupportedAppUsage setSupplicantState(SupplicantState state)1097 public void setSupplicantState(SupplicantState state) { 1098 mSupplicantState = state; 1099 } 1100 1101 /** @hide */ setInetAddress(InetAddress address)1102 public void setInetAddress(InetAddress address) { 1103 mIpAddress = address; 1104 } 1105 1106 /** 1107 * @deprecated Use the methods on {@link android.net.LinkProperties} which can be obtained 1108 * either via {@link NetworkCallback#onLinkPropertiesChanged(Network, LinkProperties)} or 1109 * {@link ConnectivityManager#getLinkProperties(Network)}. 1110 */ 1111 @Deprecated getIpAddress()1112 public int getIpAddress() { 1113 int result = 0; 1114 if (mIpAddress instanceof Inet4Address) { 1115 result = Inet4AddressUtils.inet4AddressToIntHTL((Inet4Address) mIpAddress); 1116 } 1117 return result; 1118 } 1119 1120 /** 1121 * @return {@code true} if this network does not broadcast its SSID, so an 1122 * SSID-specific probe request must be used for scans. 1123 */ getHiddenSSID()1124 public boolean getHiddenSSID() { 1125 if (mWifiSsid == null) return false; 1126 return mWifiSsid.isHidden(); 1127 } 1128 1129 /** 1130 * Map a supplicant state into a fine-grained network connectivity state. 1131 * @param suppState the supplicant state 1132 * @return the corresponding {@link DetailedState} 1133 */ getDetailedStateOf(SupplicantState suppState)1134 public static DetailedState getDetailedStateOf(SupplicantState suppState) { 1135 return stateMap.get(suppState); 1136 } 1137 1138 /** 1139 * Set the <code>SupplicantState</code> from the string name 1140 * of the state. 1141 * @param stateName the name of the state, as a <code>String</code> returned 1142 * in an event sent by {@code wpa_supplicant}. 1143 */ 1144 @UnsupportedAppUsage setSupplicantState(String stateName)1145 void setSupplicantState(String stateName) { 1146 mSupplicantState = valueOf(stateName); 1147 } 1148 valueOf(String stateName)1149 static SupplicantState valueOf(String stateName) { 1150 if ("4WAY_HANDSHAKE".equalsIgnoreCase(stateName)) 1151 return SupplicantState.FOUR_WAY_HANDSHAKE; 1152 else { 1153 try { 1154 return SupplicantState.valueOf(stateName.toUpperCase(Locale.ROOT)); 1155 } catch (IllegalArgumentException e) { 1156 return SupplicantState.INVALID; 1157 } 1158 } 1159 } 1160 1161 /** 1162 * Remove double quotes (") surrounding a SSID string, if present. Otherwise, return the 1163 * string unmodified. Return null if the input string was null. 1164 * @hide 1165 */ 1166 @Nullable 1167 @SystemApi sanitizeSsid(@ullable String string)1168 public static String sanitizeSsid(@Nullable String string) { 1169 return removeDoubleQuotes(string); 1170 } 1171 1172 /** @hide */ 1173 @UnsupportedAppUsage 1174 @Nullable removeDoubleQuotes(@ullable String string)1175 public static String removeDoubleQuotes(@Nullable String string) { 1176 if (string == null) return null; 1177 final int length = string.length(); 1178 if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) { 1179 return string.substring(1, length - 1); 1180 } 1181 return string; 1182 } 1183 1184 @Override toString()1185 public String toString() { 1186 StringBuffer sb = new StringBuffer(); 1187 String none = "<none>"; 1188 1189 sb.append("SSID: ").append(getSSID()) 1190 .append(", BSSID: ").append(mBSSID == null ? none : mBSSID) 1191 .append(", MAC: ").append(mMacAddress == null ? none : mMacAddress) 1192 .append(", Security type: ").append(mSecurityType) 1193 .append(", Supplicant state: ") 1194 .append(mSupplicantState == null ? none : mSupplicantState) 1195 .append(", Wi-Fi standard: ").append(mWifiStandard) 1196 .append(", RSSI: ").append(mRssi) 1197 .append(", Link speed: ").append(mLinkSpeed).append(LINK_SPEED_UNITS) 1198 .append(", Tx Link speed: ").append(mTxLinkSpeed).append(LINK_SPEED_UNITS) 1199 .append(", Max Supported Tx Link speed: ") 1200 .append(mMaxSupportedTxLinkSpeed).append(LINK_SPEED_UNITS) 1201 .append(", Rx Link speed: ").append(mRxLinkSpeed).append(LINK_SPEED_UNITS) 1202 .append(", Max Supported Rx Link speed: ") 1203 .append(mMaxSupportedRxLinkSpeed).append(LINK_SPEED_UNITS) 1204 .append(", Frequency: ").append(mFrequency).append(FREQUENCY_UNITS) 1205 .append(", Net ID: ").append(mNetworkId) 1206 .append(", Metered hint: ").append(mMeteredHint) 1207 .append(", score: ").append(Integer.toString(score)) 1208 .append(", CarrierMerged: ").append(mCarrierMerged) 1209 .append(", SubscriptionId: ").append(mSubscriptionId) 1210 .append(", IsPrimary: ").append(mIsPrimary); 1211 return sb.toString(); 1212 } 1213 1214 /** Implement the Parcelable interface {@hide} */ describeContents()1215 public int describeContents() { 1216 return 0; 1217 } 1218 shouldRedactLocationSensitiveFields(long redactions)1219 private boolean shouldRedactLocationSensitiveFields(long redactions) { 1220 return (redactions & NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION) != 0; 1221 } 1222 shouldRedactLocalMacAddressFields(long redactions)1223 private boolean shouldRedactLocalMacAddressFields(long redactions) { 1224 return (redactions & NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS) != 0; 1225 } 1226 shouldRedactNetworkSettingsFields(long redactions)1227 private boolean shouldRedactNetworkSettingsFields(long redactions) { 1228 return (redactions & NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS) != 0; 1229 } 1230 1231 /** Implement the Parcelable interface {@hide} */ writeToParcel(Parcel dest, int flags)1232 public void writeToParcel(Parcel dest, int flags) { 1233 dest.writeInt(mNetworkId); 1234 dest.writeInt(mRssi); 1235 dest.writeInt(mLinkSpeed); 1236 dest.writeInt(mTxLinkSpeed); 1237 dest.writeInt(mRxLinkSpeed); 1238 dest.writeInt(mFrequency); 1239 if (mIpAddress != null) { 1240 dest.writeByte((byte)1); 1241 dest.writeByteArray(mIpAddress.getAddress()); 1242 } else { 1243 dest.writeByte((byte)0); 1244 } 1245 if (mWifiSsid != null) { 1246 dest.writeInt(1); 1247 mWifiSsid.writeToParcel(dest, flags); 1248 } else { 1249 dest.writeInt(0); 1250 } 1251 dest.writeString(mBSSID); 1252 dest.writeString(mMacAddress); 1253 dest.writeInt(mMeteredHint ? 1 : 0); 1254 dest.writeInt(mEphemeral ? 1 : 0); 1255 dest.writeInt(mTrusted ? 1 : 0); 1256 dest.writeInt(mOemPaid ? 1 : 0); 1257 dest.writeInt(mOemPrivate ? 1 : 0); 1258 dest.writeInt(mCarrierMerged ? 1 : 0); 1259 dest.writeInt(score); 1260 dest.writeLong(txSuccess); 1261 dest.writeDouble(mSuccessfulTxPacketsPerSecond); 1262 dest.writeLong(txRetries); 1263 dest.writeDouble(mTxRetriedTxPacketsPerSecond); 1264 dest.writeLong(txBad); 1265 dest.writeDouble(mLostTxPacketsPerSecond); 1266 dest.writeLong(rxSuccess); 1267 dest.writeDouble(mSuccessfulRxPacketsPerSecond); 1268 mSupplicantState.writeToParcel(dest, flags); 1269 dest.writeInt(mOsuAp ? 1 : 0); 1270 dest.writeString(mRequestingPackageName); 1271 dest.writeString(mFqdn); 1272 dest.writeString(mProviderFriendlyName); 1273 dest.writeInt(mWifiStandard); 1274 dest.writeInt(mMaxSupportedTxLinkSpeed); 1275 dest.writeInt(mMaxSupportedRxLinkSpeed); 1276 dest.writeString(mPasspointUniqueId); 1277 dest.writeInt(mSubscriptionId); 1278 dest.writeTypedList(mInformationElements); 1279 if (SdkLevel.isAtLeastS()) { 1280 dest.writeInt(mIsPrimary); 1281 } 1282 dest.writeInt(mSecurityType); 1283 } 1284 1285 /** Implement the Parcelable interface {@hide} */ 1286 @UnsupportedAppUsage 1287 public static final @android.annotation.NonNull Creator<WifiInfo> CREATOR = 1288 new Creator<WifiInfo>() { 1289 public WifiInfo createFromParcel(Parcel in) { 1290 WifiInfo info = new WifiInfo(); 1291 info.setNetworkId(in.readInt()); 1292 info.setRssi(in.readInt()); 1293 info.setLinkSpeed(in.readInt()); 1294 info.setTxLinkSpeedMbps(in.readInt()); 1295 info.setRxLinkSpeedMbps(in.readInt()); 1296 info.setFrequency(in.readInt()); 1297 if (in.readByte() == 1) { 1298 try { 1299 info.setInetAddress(InetAddress.getByAddress(in.createByteArray())); 1300 } catch (UnknownHostException e) {} 1301 } 1302 if (in.readInt() == 1) { 1303 info.mWifiSsid = WifiSsid.CREATOR.createFromParcel(in); 1304 } 1305 info.mBSSID = in.readString(); 1306 info.mMacAddress = in.readString(); 1307 info.mMeteredHint = in.readInt() != 0; 1308 info.mEphemeral = in.readInt() != 0; 1309 info.mTrusted = in.readInt() != 0; 1310 info.mOemPaid = in.readInt() != 0; 1311 info.mOemPrivate = in.readInt() != 0; 1312 info.mCarrierMerged = in.readInt() != 0; 1313 info.score = in.readInt(); 1314 info.txSuccess = in.readLong(); 1315 info.mSuccessfulTxPacketsPerSecond = in.readDouble(); 1316 info.txRetries = in.readLong(); 1317 info.mTxRetriedTxPacketsPerSecond = in.readDouble(); 1318 info.txBad = in.readLong(); 1319 info.mLostTxPacketsPerSecond = in.readDouble(); 1320 info.rxSuccess = in.readLong(); 1321 info.mSuccessfulRxPacketsPerSecond = in.readDouble(); 1322 info.mSupplicantState = SupplicantState.CREATOR.createFromParcel(in); 1323 info.mOsuAp = in.readInt() != 0; 1324 info.mRequestingPackageName = in.readString(); 1325 info.mFqdn = in.readString(); 1326 info.mProviderFriendlyName = in.readString(); 1327 info.mWifiStandard = in.readInt(); 1328 info.mMaxSupportedTxLinkSpeed = in.readInt(); 1329 info.mMaxSupportedRxLinkSpeed = in.readInt(); 1330 info.mPasspointUniqueId = in.readString(); 1331 info.mSubscriptionId = in.readInt(); 1332 info.mInformationElements = in.createTypedArrayList( 1333 ScanResult.InformationElement.CREATOR); 1334 if (SdkLevel.isAtLeastS()) { 1335 info.mIsPrimary = in.readInt(); 1336 } 1337 info.mSecurityType = in.readInt(); 1338 return info; 1339 } 1340 1341 public WifiInfo[] newArray(int size) { 1342 return new WifiInfo[size]; 1343 } 1344 }; 1345 1346 /** 1347 * Set the Passpoint unique identifier for the current connection 1348 * 1349 * @param passpointUniqueId Unique identifier 1350 * @hide 1351 */ setPasspointUniqueId(@ullable String passpointUniqueId)1352 public void setPasspointUniqueId(@Nullable String passpointUniqueId) { 1353 mPasspointUniqueId = passpointUniqueId; 1354 } 1355 1356 /** 1357 * Get the Passpoint unique identifier for the current connection 1358 * 1359 * @return Passpoint unique identifier 1360 * @hide 1361 */ getPasspointUniqueId()1362 public @Nullable String getPasspointUniqueId() { 1363 return mPasspointUniqueId; 1364 } 1365 1366 /** 1367 * Set the information elements found in the becaon of the connected bssid. 1368 * @hide 1369 */ setInformationElements(@ullable List<ScanResult.InformationElement> infoElements)1370 public void setInformationElements(@Nullable List<ScanResult.InformationElement> infoElements) { 1371 if (infoElements == null) { 1372 mInformationElements = null; 1373 return; 1374 } 1375 mInformationElements = new ArrayList<>(infoElements); 1376 } 1377 1378 /** 1379 * Get all information elements found in the beacon of the connected bssid. 1380 * <p> 1381 * The information elements will be {@code null} if there is no network currently connected or 1382 * if the caller has insufficient permissions to access the info elements. 1383 * </p> 1384 * 1385 * @return List of information elements {@link ScanResult.InformationElement} or null. 1386 */ 1387 @Nullable 1388 @SuppressWarnings("NullableCollection") getInformationElements()1389 public List<ScanResult.InformationElement> getInformationElements() { 1390 if (mInformationElements == null) return null; 1391 return new ArrayList<>(mInformationElements); 1392 } 1393 1394 /** 1395 * @see #isPrimary() 1396 * @hide 1397 */ setIsPrimary(boolean isPrimary)1398 public void setIsPrimary(boolean isPrimary) { 1399 mIsPrimary = isPrimary ? IS_PRIMARY_TRUE : IS_PRIMARY_FALSE; 1400 } 1401 1402 /** 1403 * Returns whether this is the primary wifi connection or not. 1404 * 1405 * Wifi service considers this connection to be the best among all Wifi connections, and this 1406 * connection should be the one surfaced to the user if only one can be displayed. 1407 * 1408 * Note that the default route (chosen by Connectivity Service) may not correspond to the 1409 * primary Wifi connection e.g. when there exists a better cellular network, or if the 1410 * primary Wifi connection doesn't have internet access. 1411 * 1412 * @return whether this is the primary connection or not. 1413 * 1414 * @hide 1415 */ 1416 @RequiresApi(Build.VERSION_CODES.S) 1417 @RequiresPermission(Manifest.permission.NETWORK_SETTINGS) 1418 @SystemApi isPrimary()1419 public boolean isPrimary() { 1420 if (!SdkLevel.isAtLeastS()) { 1421 // Intentional - since we don't support STA + STA on older devices, this field 1422 // is redundant. Don't allow anyone to use this. 1423 throw new UnsupportedOperationException(); 1424 } 1425 if (mIsPrimary == IS_PRIMARY_NO_PERMISSION) { 1426 throw new SecurityException("Not allowed to access this field"); 1427 } 1428 return mIsPrimary == IS_PRIMARY_TRUE; 1429 } 1430 1431 @Override equals(Object that)1432 public boolean equals(Object that) { 1433 if (this == that) return true; 1434 1435 // Potential API behavior change, so don't change behavior on older devices. 1436 if (!SdkLevel.isAtLeastS()) return false; 1437 1438 if (!(that instanceof WifiInfo)) return false; 1439 1440 WifiInfo thatWifiInfo = (WifiInfo) that; 1441 return Objects.equals(mWifiSsid, thatWifiInfo.mWifiSsid) 1442 && Objects.equals(mBSSID, thatWifiInfo.mBSSID) 1443 && Objects.equals(mNetworkId, thatWifiInfo.mNetworkId) 1444 && Objects.equals(mRssi, thatWifiInfo.mRssi) 1445 && Objects.equals(mSupplicantState, thatWifiInfo.mSupplicantState) 1446 && Objects.equals(mLinkSpeed, thatWifiInfo.mLinkSpeed) 1447 && Objects.equals(mTxLinkSpeed, thatWifiInfo.mTxLinkSpeed) 1448 && Objects.equals(mRxLinkSpeed, thatWifiInfo.mRxLinkSpeed) 1449 && Objects.equals(mFrequency, thatWifiInfo.mFrequency) 1450 && Objects.equals(mIpAddress, thatWifiInfo.mIpAddress) 1451 && Objects.equals(mMacAddress, thatWifiInfo.mMacAddress) 1452 && Objects.equals(mMeteredHint, thatWifiInfo.mMeteredHint) 1453 && Objects.equals(mEphemeral, thatWifiInfo.mEphemeral) 1454 && Objects.equals(mTrusted, thatWifiInfo.mTrusted) 1455 && Objects.equals(mOemPaid, thatWifiInfo.mOemPaid) 1456 && Objects.equals(mOemPrivate, thatWifiInfo.mOemPrivate) 1457 && Objects.equals(mCarrierMerged, thatWifiInfo.mCarrierMerged) 1458 && Objects.equals(mRequestingPackageName, thatWifiInfo.mRequestingPackageName) 1459 && Objects.equals(mOsuAp, thatWifiInfo.mOsuAp) 1460 && Objects.equals(mFqdn, thatWifiInfo.mFqdn) 1461 && Objects.equals(mProviderFriendlyName, thatWifiInfo.mProviderFriendlyName) 1462 && Objects.equals(mSubscriptionId, thatWifiInfo.mSubscriptionId) 1463 && Objects.equals(txBad, thatWifiInfo.txBad) 1464 && Objects.equals(txRetries, thatWifiInfo.txRetries) 1465 && Objects.equals(txSuccess, thatWifiInfo.txSuccess) 1466 && Objects.equals(rxSuccess, thatWifiInfo.rxSuccess) 1467 && Objects.equals(mLostTxPacketsPerSecond, thatWifiInfo.mLostTxPacketsPerSecond) 1468 && Objects.equals(mTxRetriedTxPacketsPerSecond, 1469 thatWifiInfo.mTxRetriedTxPacketsPerSecond) 1470 && Objects.equals(mSuccessfulTxPacketsPerSecond, 1471 thatWifiInfo.mSuccessfulTxPacketsPerSecond) 1472 && Objects.equals(mSuccessfulRxPacketsPerSecond, 1473 thatWifiInfo.mSuccessfulRxPacketsPerSecond) 1474 && Objects.equals(score, thatWifiInfo.score) 1475 && Objects.equals(mWifiStandard, thatWifiInfo.mWifiStandard) 1476 && Objects.equals(mMaxSupportedTxLinkSpeed, thatWifiInfo.mMaxSupportedTxLinkSpeed) 1477 && Objects.equals(mMaxSupportedRxLinkSpeed, thatWifiInfo.mMaxSupportedRxLinkSpeed) 1478 && Objects.equals(mPasspointUniqueId, thatWifiInfo.mPasspointUniqueId) 1479 && Objects.equals(mInformationElements, thatWifiInfo.mInformationElements) 1480 && Objects.equals(mIsPrimary, thatWifiInfo.mIsPrimary) 1481 && Objects.equals(mSecurityType, thatWifiInfo.mSecurityType); 1482 } 1483 1484 @Override hashCode()1485 public int hashCode() { 1486 // Potential API behavior change, so don't change behavior on older devices. 1487 if (!SdkLevel.isAtLeastS()) return System.identityHashCode(this); 1488 1489 return Objects.hash(mWifiSsid, 1490 mBSSID, 1491 mNetworkId, 1492 mRssi, 1493 mSupplicantState, 1494 mLinkSpeed, 1495 mTxLinkSpeed, 1496 mRxLinkSpeed, 1497 mFrequency, 1498 mIpAddress, 1499 mMacAddress, 1500 mMeteredHint, 1501 mEphemeral, 1502 mTrusted, 1503 mOemPaid, 1504 mOemPrivate, 1505 mCarrierMerged, 1506 mRequestingPackageName, 1507 mOsuAp, 1508 mFqdn, 1509 mProviderFriendlyName, 1510 mSubscriptionId, 1511 txBad, 1512 txRetries, 1513 txSuccess, 1514 rxSuccess, 1515 mLostTxPacketsPerSecond, 1516 mTxRetriedTxPacketsPerSecond, 1517 mSuccessfulTxPacketsPerSecond, 1518 mSuccessfulRxPacketsPerSecond, 1519 score, 1520 mWifiStandard, 1521 mMaxSupportedTxLinkSpeed, 1522 mMaxSupportedRxLinkSpeed, 1523 mPasspointUniqueId, 1524 mInformationElements, 1525 mIsPrimary, 1526 mSecurityType); 1527 } 1528 1529 /** 1530 * Create a copy of a {@link WifiInfo} with some fields redacted based on the permissions 1531 * held by the receiving app. 1532 * 1533 * @param redactions bitmask of redactions that needs to be performed on this instance. 1534 * @return Copy of this instance with the necessary redactions. 1535 */ 1536 @Override 1537 @NonNull makeCopy(long redactions)1538 public WifiInfo makeCopy(long redactions) { 1539 return new WifiInfo(this, redactions); 1540 } 1541 1542 /** 1543 * Returns a bitmask of all the applicable redactions (based on the permissions held by the 1544 * receiving app) to be performed on this TransportInfo. 1545 * 1546 * @return bitmask of redactions applicable on this instance. 1547 */ 1548 @Override getApplicableRedactions()1549 public long getApplicableRedactions() { 1550 return NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION 1551 | NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS 1552 | NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS; 1553 } 1554 1555 /** 1556 * Set the security type of the current connection 1557 * @hide 1558 */ setCurrentSecurityType(@ifiConfiguration.SecurityType int securityType)1559 public void setCurrentSecurityType(@WifiConfiguration.SecurityType int securityType) { 1560 mSecurityType = convertSecurityTypeToWifiInfo(securityType); 1561 } 1562 1563 /** 1564 * Clear the last set security type 1565 * @hide 1566 */ clearCurrentSecurityType()1567 public void clearCurrentSecurityType() { 1568 mSecurityType = SECURITY_TYPE_UNKNOWN; 1569 } 1570 1571 /** 1572 * Returns the security type of the current 802.11 network connection. 1573 * 1574 * @return the security type, or {@link #SECURITY_TYPE_UNKNOWN} if not currently connected. 1575 */ getCurrentSecurityType()1576 public @SecurityType int getCurrentSecurityType() { 1577 return mSecurityType; 1578 } 1579 convertSecurityTypeToWifiInfo( @ifiConfiguration.SecurityType int securityType)1580 private @SecurityType int convertSecurityTypeToWifiInfo( 1581 @WifiConfiguration.SecurityType int securityType) { 1582 switch (securityType) { 1583 case WifiConfiguration.SECURITY_TYPE_OPEN: 1584 return SECURITY_TYPE_OPEN; 1585 case WifiConfiguration.SECURITY_TYPE_WEP: 1586 return SECURITY_TYPE_WEP; 1587 case WifiConfiguration.SECURITY_TYPE_PSK: 1588 return SECURITY_TYPE_PSK; 1589 case WifiConfiguration.SECURITY_TYPE_EAP: 1590 return SECURITY_TYPE_EAP; 1591 case WifiConfiguration.SECURITY_TYPE_SAE: 1592 return SECURITY_TYPE_SAE; 1593 case WifiConfiguration.SECURITY_TYPE_OWE: 1594 return SECURITY_TYPE_OWE; 1595 case WifiConfiguration.SECURITY_TYPE_WAPI_PSK: 1596 return SECURITY_TYPE_WAPI_PSK; 1597 case WifiConfiguration.SECURITY_TYPE_WAPI_CERT: 1598 return SECURITY_TYPE_WAPI_CERT; 1599 case WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE: 1600 return SECURITY_TYPE_EAP_WPA3_ENTERPRISE; 1601 case WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT: 1602 return SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT; 1603 case WifiConfiguration.SECURITY_TYPE_PASSPOINT_R1_R2: 1604 return SECURITY_TYPE_PASSPOINT_R1_R2; 1605 case WifiConfiguration.SECURITY_TYPE_PASSPOINT_R3: 1606 return SECURITY_TYPE_PASSPOINT_R3; 1607 default: 1608 return SECURITY_TYPE_UNKNOWN; 1609 } 1610 } 1611 } 1612