• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.app.admin.DevicePolicyManager;
29 import android.compat.annotation.UnsupportedAppUsage;
30 import android.net.ConnectivityManager;
31 import android.net.ConnectivityManager.NetworkCallback;
32 import android.net.LinkProperties;
33 import android.net.MacAddress;
34 import android.net.Network;
35 import android.net.NetworkCapabilities;
36 import android.net.NetworkInfo.DetailedState;
37 import android.net.TransportInfo;
38 import android.os.Build;
39 import android.os.Parcel;
40 import android.os.Parcelable;
41 import android.telephony.SubscriptionManager;
42 import android.text.TextUtils;
43 
44 import androidx.annotation.RequiresApi;
45 
46 import com.android.modules.utils.build.SdkLevel;
47 import com.android.net.module.util.Inet4AddressUtils;
48 
49 import java.lang.annotation.Retention;
50 import java.lang.annotation.RetentionPolicy;
51 import java.net.Inet4Address;
52 import java.net.InetAddress;
53 import java.net.UnknownHostException;
54 import java.util.ArrayList;
55 import java.util.Collections;
56 import java.util.Comparator;
57 import java.util.EnumMap;
58 import java.util.List;
59 import java.util.Locale;
60 import java.util.Objects;
61 
62 /**
63  * Describes the state of any Wi-Fi connection that is active or
64  * is in the process of being set up.
65  *
66  * In the connected state, access to location sensitive fields requires
67  * the same permissions as {@link WifiManager#getScanResults}. If such access is not allowed,
68  * {@link #getSSID} will return {@link WifiManager#UNKNOWN_SSID} and
69  * {@link #getBSSID} will return {@code "02:00:00:00:00:00"}.
70  * {@link #getApMldMacAddress()} will return null.
71  * {@link #getNetworkId()} will return {@code -1}.
72  * {@link #getPasspointFqdn()} will return null.
73  * {@link #getPasspointProviderFriendlyName()} will return null.
74  * {@link #getInformationElements()} will return null.
75  * {@link #getMacAddress()} will return {@code "02:00:00:00:00:00"}.
76  */
77 public class WifiInfo implements TransportInfo, Parcelable {
78     private static final String TAG = "WifiInfo";
79     /**
80      * This is the map described in the Javadoc comment above. The positions
81      * of the elements of the array must correspond to the ordinal values
82      * of <code>DetailedState</code>.
83      */
84     private static final EnumMap<SupplicantState, DetailedState> stateMap =
85             new EnumMap<SupplicantState, DetailedState>(SupplicantState.class);
86 
87     /**
88      * Default MAC address reported to a client that does not have the
89      * android.permission.LOCAL_MAC_ADDRESS permission.
90      *
91      * @hide
92      */
93     @SystemApi
94     public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00";
95 
96     static {
stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED)97         stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED);
stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED)98         stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED);
stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE)99         stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE);
stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING)100         stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING);
stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING)101         stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING);
stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING)102         stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING);
stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING)103         stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING);
stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING)104         stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING);
stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING)105         stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING);
stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR)106         stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR);
stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED)107         stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED);
stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE)108         stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE);
stateMap.put(SupplicantState.INVALID, DetailedState.FAILED)109         stateMap.put(SupplicantState.INVALID, DetailedState.FAILED);
110     }
111 
112     private SupplicantState mSupplicantState;
113     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
114     private String mBSSID;
115     @UnsupportedAppUsage
116     private WifiSsid mWifiSsid;
117     private boolean mIsHiddenSsid = false;
118     private int mNetworkId;
119     private int mSecurityType;
120 
121     /**
122      * The Multi-Link Device (MLD) MAC Address for the connected access point.
123      * Only applicable for Wi-Fi 7 access points, null otherwise.
124      * This will be set even if the STA is non-MLD
125      */
126     private MacAddress mApMldMacAddress;
127 
128     /**
129      * The Multi-Link Operation (MLO) link-id for the access point.
130      * Only applicable for Wi-Fi 7 access points.
131      */
132     private int mApMloLinkId;
133 
134     /**
135      * The Multi-Link Operation (MLO) affiliated Links.
136      * Only applicable for Wi-Fi 7 access points.
137      */
138     private List<MloLink> mAffiliatedMloLinks;
139 
140     /**
141      * Used to indicate that the RSSI is invalid, for example if no RSSI measurements are available
142      * yet.
143      * @hide
144      */
145     @SystemApi
146     public static final int INVALID_RSSI = -127;
147 
148     /** @hide **/
149     public static final int UNKNOWN_FREQUENCY = -1;
150 
151     /** @hide **/
152     public static final int MIN_RSSI = -126;
153 
154     /** @hide **/
155     public static final int MAX_RSSI = 200;
156 
157     /** Unknown security type. */
158     public static final int SECURITY_TYPE_UNKNOWN = -1;
159     /** Security type for an open network. */
160     public static final int SECURITY_TYPE_OPEN = 0;
161     /** Security type for a WEP network. */
162     public static final int SECURITY_TYPE_WEP = 1;
163     /** Security type for a PSK network. */
164     public static final int SECURITY_TYPE_PSK = 2;
165     /** Security type for an EAP network. */
166     public static final int SECURITY_TYPE_EAP = 3;
167     /** Security type for an SAE network. */
168     public static final int SECURITY_TYPE_SAE = 4;
169     /** Security type for a WPA3-Enterprise in 192-bit security network. */
170     public static final int SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT = 5;
171     /** Security type for an OWE network. */
172     public static final int SECURITY_TYPE_OWE = 6;
173     /** Security type for a WAPI PSK network. */
174     public static final int SECURITY_TYPE_WAPI_PSK = 7;
175     /** Security type for a WAPI Certificate network. */
176     public static final int SECURITY_TYPE_WAPI_CERT = 8;
177     /** Security type for a WPA3-Enterprise network. */
178     public static final int SECURITY_TYPE_EAP_WPA3_ENTERPRISE = 9;
179     /** Security type for an OSEN network. */
180     public static final int SECURITY_TYPE_OSEN = 10;
181     /** Security type for a Passpoint R1/R2 network, where TKIP and WEP are not allowed. */
182     public static final int SECURITY_TYPE_PASSPOINT_R1_R2 = 11;
183     /**
184      * Security type for a Passpoint R3 network, where TKIP and WEP are not allowed,
185      * and PMF must be set to Required.
186      */
187     public static final int SECURITY_TYPE_PASSPOINT_R3 = 12;
188     /** Security type for Easy Connect (DPP) network */
189     public static final int SECURITY_TYPE_DPP = 13;
190 
191     /**
192      * Unknown security type that cannot be converted to
193      * DevicePolicyManager.WifiSecurity security type.
194      * @hide
195      */
196     public static final int DPM_SECURITY_TYPE_UNKNOWN = -1;
197 
198     /** @see #isPrimary() - No permission to access the field.  */
199     private static final int IS_PRIMARY_NO_PERMISSION = -1;
200     /** @see #isPrimary() - false */
201     private static final int IS_PRIMARY_FALSE = 0;
202     /** @see #isPrimary() - true */
203     private static final int IS_PRIMARY_TRUE = 1;
204     /** Tri state to store {@link #isPrimary()} field. */
205     /** @hide */
206     @Retention(RetentionPolicy.SOURCE)
207     @IntDef(prefix = { "IS_PRIMARY_" }, value = {
208             IS_PRIMARY_NO_PERMISSION, IS_PRIMARY_FALSE, IS_PRIMARY_TRUE
209     })
210     public @interface IsPrimaryValues {}
211 
212     /**
213      * Received Signal Strength Indicator
214      */
215     private int mRssi;
216 
217     /**
218      * Wi-Fi standard for the connection
219      */
220     private @WifiAnnotations.WifiStandard int mWifiStandard;
221 
222     /**
223      * The unit in which links speeds are expressed.
224      */
225     public static final String LINK_SPEED_UNITS = "Mbps";
226     private int mLinkSpeed;
227 
228     /**
229      * Constant for unknown link speed.
230      */
231     public static final int LINK_SPEED_UNKNOWN = -1;
232 
233     /**
234      * Tx(transmit) Link speed in Mbps
235      */
236     private int mTxLinkSpeed;
237 
238     /**
239      * Max supported Tx(transmit) link speed in Mbps
240      */
241     private int mMaxSupportedTxLinkSpeed;
242 
243     /**
244      * Rx(receive) Link speed in Mbps
245      */
246     private int mRxLinkSpeed;
247 
248     /**
249      * Max supported Rx(receive) link speed in Mbps
250      */
251     private int mMaxSupportedRxLinkSpeed;
252 
253     /**
254      * Frequency in MHz
255      */
256     public static final String FREQUENCY_UNITS = "MHz";
257     private int mFrequency;
258 
259     @UnsupportedAppUsage
260     private InetAddress mIpAddress;
261     @UnsupportedAppUsage
262     private String mMacAddress = DEFAULT_MAC_ADDRESS;
263 
264     /**
265      * Whether the network is ephemeral or not.
266      */
267     private boolean mEphemeral;
268 
269     /**
270      * Whether the network is trusted or not.
271      */
272     private boolean mTrusted;
273 
274     /**
275      * Whether the network is restricted or not.
276      */
277     private boolean mRestricted;
278 
279     /**
280      * Whether the network is oem paid or not.
281      */
282     private boolean mOemPaid;
283 
284     /**
285      * Whether the network is oem private or not.
286      */
287     private boolean mOemPrivate;
288 
289     /**
290      * Whether the network is a carrier merged network.
291      */
292     private boolean mCarrierMerged;
293 
294     /**
295      * OSU (Online Sign Up) AP for Passpoint R2.
296      */
297     private boolean mOsuAp;
298 
299     /**
300      * Fully qualified domain name of a Passpoint configuration
301      */
302     private String mFqdn;
303 
304     /**
305      * Name of Passpoint credential provider
306      */
307     private String mProviderFriendlyName;
308 
309     /**
310      * If connected to a network suggestion or specifier, store the package name of the app,
311      * else null.
312      */
313     private String mRequestingPackageName;
314 
315     /**
316      * Identify which Telephony subscription provides this network.
317      */
318     private int mSubscriptionId;
319 
320     /**
321      * Running total count of lost (not ACKed) transmitted unicast data packets.
322      * @hide
323      */
324     public long txBad;
325     /**
326      * Running total count of transmitted unicast data retry packets.
327      * @hide
328      */
329     public long txRetries;
330     /**
331      * Running total count of successfully transmitted (ACKed) unicast data packets.
332      * @hide
333      */
334     public long txSuccess;
335     /**
336      * Running total count of received unicast data packets.
337      * @hide
338      */
339     public long rxSuccess;
340 
341     private double mLostTxPacketsPerSecond;
342 
343     /**
344      * TID-to-link mapping negotiation support by the AP.
345      */
346     private boolean mApTidToLinkMappingNegotiationSupported;
347 
348     /**
349      * Average rate of lost transmitted packets, in units of packets per second. In case of Multi
350      * Link Operation (MLO), returned value is the average rate of lost transmitted packets on all
351      * associated links.
352      *
353      * @hide
354      */
355     @SystemApi
getLostTxPacketsPerSecond()356     public double getLostTxPacketsPerSecond() {
357         return mLostTxPacketsPerSecond;
358     }
359 
360     /** @hide */
setLostTxPacketsPerSecond(double lostTxPacketsPerSecond)361     public void setLostTxPacketsPerSecond(double lostTxPacketsPerSecond) {
362         mLostTxPacketsPerSecond = lostTxPacketsPerSecond;
363     }
364 
365     private double mTxRetriedTxPacketsPerSecond;
366 
367     /**
368      * Average rate of transmitted retry packets, in units of packets per second. In case Multi Link
369      * Operation (MLO), the returned value is the average rate of transmitted retry packets on all
370      * associated links.
371      *
372      * @hide
373      */
374     @SystemApi
getRetriedTxPacketsPerSecond()375     public double getRetriedTxPacketsPerSecond() {
376         return mTxRetriedTxPacketsPerSecond;
377     }
378 
379     /** @hide */
setRetriedTxPacketsRate(double txRetriedTxPacketsPerSecond)380     public void setRetriedTxPacketsRate(double txRetriedTxPacketsPerSecond) {
381         mTxRetriedTxPacketsPerSecond = txRetriedTxPacketsPerSecond;
382     }
383 
384     private double mSuccessfulTxPacketsPerSecond;
385 
386     /**
387      * Average rate of successfully transmitted unicast packets, in units of packets per second. In
388      * case Multi Link Operation (MLO), returned value is the average rate of successfully
389      * transmitted unicast packets on all associated links.
390      *
391      * @hide
392      */
393     @SystemApi
getSuccessfulTxPacketsPerSecond()394     public double getSuccessfulTxPacketsPerSecond() {
395         return mSuccessfulTxPacketsPerSecond;
396     }
397 
398     /** @hide */
setSuccessfulTxPacketsPerSecond(double successfulTxPacketsPerSecond)399     public void setSuccessfulTxPacketsPerSecond(double successfulTxPacketsPerSecond) {
400         mSuccessfulTxPacketsPerSecond = successfulTxPacketsPerSecond;
401     }
402 
403     private double mSuccessfulRxPacketsPerSecond;
404 
405     /**
406      * Average rate of received unicast data packets, in units of packets per second. In case of
407      * Multi Link Operation (MLO), the returned value is the average rate of received unicast data
408      * packets on all associated links.
409      *
410      * @hide
411      */
412     @SystemApi
getSuccessfulRxPacketsPerSecond()413     public double getSuccessfulRxPacketsPerSecond() {
414         return mSuccessfulRxPacketsPerSecond;
415     }
416 
417     /** @hide */
setSuccessfulRxPacketsPerSecond(double successfulRxPacketsPerSecond)418     public void setSuccessfulRxPacketsPerSecond(double successfulRxPacketsPerSecond) {
419         mSuccessfulRxPacketsPerSecond = successfulRxPacketsPerSecond;
420     }
421 
422     /** @hide */
423     @UnsupportedAppUsage
424     public int score;
425 
426     /**
427      * The current Wifi score.
428      * NOTE: this value should only be used for debugging purposes. Do not rely on this value for
429      * any computations. The meaning of this value can and will change at any time without warning.
430      * @hide
431      */
432     @SystemApi
getScore()433     public int getScore() {
434         return score;
435     }
436 
437     /** @hide */
setScore(int score)438     public void setScore(int score) {
439         this.score = score;
440     }
441 
442     /** @hide */
443     private boolean mIsUsable = true;
444 
445     /** @hide */
isUsable()446     public boolean isUsable() {
447         return mIsUsable;
448     }
449 
450     /**
451      * This could be set to false by the external scorer when the network quality is bad.
452      * The wifi module could use this information in network selection.
453      * @hide
454      */
setUsable(boolean isUsable)455     public void setUsable(boolean isUsable) {
456         mIsUsable = isUsable;
457     }
458 
459     /**
460      * Flag indicating that AP has hinted that upstream connection is metered,
461      * and sensitive to heavy data transfers.
462      */
463     private boolean mMeteredHint;
464 
465     /**
466      * Passpoint unique key
467      */
468     private String mPasspointUniqueId;
469 
470     /**
471      * information elements found in the beacon of the connected bssid.
472      */
473     @Nullable
474     private List<ScanResult.InformationElement> mInformationElements;
475 
476     /**
477      * @see #isPrimary()
478      * The field is stored as an int since is a tristate internally -  true, false, no permission.
479      */
480     private @IsPrimaryValues int mIsPrimary;
481 
482     /**
483      * Key of the current network.
484      */
485     private String mNetworkKey;
486 
487     /** @hide */
488     @UnsupportedAppUsage
WifiInfo()489     public WifiInfo() {
490         mWifiSsid = null;
491         mBSSID = null;
492         mApMldMacAddress = null;
493         mApMloLinkId = 0;
494         mAffiliatedMloLinks = Collections.emptyList();
495         mNetworkId = -1;
496         mSupplicantState = SupplicantState.UNINITIALIZED;
497         mRssi = INVALID_RSSI;
498         mLinkSpeed = LINK_SPEED_UNKNOWN;
499         mFrequency = UNKNOWN_FREQUENCY;
500         mSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
501         mSecurityType = -1;
502         mIsPrimary = IS_PRIMARY_FALSE;
503         mNetworkKey = null;
504         mApMloLinkId = MloLink.INVALID_MLO_LINK_ID;
505     }
506 
507     /** @hide */
reset()508     public void reset() {
509         setInetAddress(null);
510         setBSSID(null);
511         setSSID(null);
512         setHiddenSSID(false);
513         setNetworkId(-1);
514         setRssi(INVALID_RSSI);
515         setLinkSpeed(LINK_SPEED_UNKNOWN);
516         setTxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
517         setRxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
518         setMaxSupportedTxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
519         setMaxSupportedRxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
520         setFrequency(-1);
521         setMeteredHint(false);
522         setEphemeral(false);
523         setTrusted(false);
524         setOemPaid(false);
525         setOemPrivate(false);
526         setCarrierMerged(false);
527         setOsuAp(false);
528         setRequestingPackageName(null);
529         setFQDN(null);
530         setProviderFriendlyName(null);
531         setPasspointUniqueId(null);
532         setSubscriptionId(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
533         setInformationElements(null);
534         setIsPrimary(false);
535         setRestricted(false);
536         txBad = 0;
537         txSuccess = 0;
538         rxSuccess = 0;
539         txRetries = 0;
540         mLostTxPacketsPerSecond = 0;
541         mSuccessfulTxPacketsPerSecond = 0;
542         mSuccessfulRxPacketsPerSecond = 0;
543         mTxRetriedTxPacketsPerSecond = 0;
544         score = 0;
545         mIsUsable = true;
546         mSecurityType = -1;
547         mNetworkKey = null;
548         resetMultiLinkInfo();
549         enableApTidToLinkMappingNegotiationSupport(false);
550     }
551 
552     /** @hide */
resetMultiLinkInfo()553     public void resetMultiLinkInfo() {
554         setApMldMacAddress(null);
555         mApMloLinkId = MloLink.INVALID_MLO_LINK_ID;
556         mAffiliatedMloLinks = Collections.emptyList();
557     }
558 
559     /**
560      * Copy constructor
561      * @hide
562      */
WifiInfo(WifiInfo source)563     public WifiInfo(WifiInfo source) {
564         this(source, NetworkCapabilities.REDACT_NONE);
565     }
566 
567     /**
568      * Copy constructor
569      * @hide
570      */
WifiInfo(WifiInfo source, long redactions)571     private WifiInfo(WifiInfo source, long redactions) {
572         if (source != null) {
573             mSupplicantState = source.mSupplicantState;
574             mBSSID = shouldRedactLocationSensitiveFields(redactions)
575                     ? DEFAULT_MAC_ADDRESS : source.mBSSID;
576             mApMldMacAddress = shouldRedactLocationSensitiveFields(redactions)
577                     ? null : source.mApMldMacAddress;
578             mApMloLinkId = source.mApMloLinkId;
579             if (source.mApMldMacAddress != null) {
580                 mAffiliatedMloLinks = new ArrayList<MloLink>();
581                 for (MloLink link : source.mAffiliatedMloLinks) {
582                     mAffiliatedMloLinks.add(new MloLink(link, redactions));
583                 }
584             } else {
585                 mAffiliatedMloLinks = Collections.emptyList();
586             }
587             mWifiSsid = shouldRedactLocationSensitiveFields(redactions)
588                     ? null : source.mWifiSsid;
589             mNetworkId = shouldRedactLocationSensitiveFields(redactions)
590                     ? INVALID_NETWORK_ID : source.mNetworkId;
591             mRssi = source.mRssi;
592             mLinkSpeed = source.mLinkSpeed;
593             mTxLinkSpeed = source.mTxLinkSpeed;
594             mRxLinkSpeed = source.mRxLinkSpeed;
595             mFrequency = source.mFrequency;
596             mIpAddress = source.mIpAddress;
597             mMacAddress = (shouldRedactLocalMacAddressFields(redactions)
598                     || shouldRedactLocationSensitiveFields(redactions))
599                             ? DEFAULT_MAC_ADDRESS : source.mMacAddress;
600             mMeteredHint = source.mMeteredHint;
601             mEphemeral = source.mEphemeral;
602             mTrusted = source.mTrusted;
603             mRestricted = source.mRestricted;
604             mOemPaid = source.mOemPaid;
605             mOemPrivate = source.mOemPrivate;
606             mCarrierMerged = source.mCarrierMerged;
607             mRequestingPackageName = shouldRedactNetworkSettingsFields(redactions) ? null
608                     : source.mRequestingPackageName;
609             mOsuAp = source.mOsuAp;
610             mFqdn = shouldRedactLocationSensitiveFields(redactions)
611                     ? null : source.mFqdn;
612             mProviderFriendlyName = shouldRedactLocationSensitiveFields(redactions)
613                     ? null : source.mProviderFriendlyName;
614             mSubscriptionId = source.mSubscriptionId;
615             txBad = source.txBad;
616             txRetries = source.txRetries;
617             txSuccess = source.txSuccess;
618             rxSuccess = source.rxSuccess;
619             mLostTxPacketsPerSecond = source.mLostTxPacketsPerSecond;
620             mTxRetriedTxPacketsPerSecond = source.mTxRetriedTxPacketsPerSecond;
621             mSuccessfulTxPacketsPerSecond = source.mSuccessfulTxPacketsPerSecond;
622             mSuccessfulRxPacketsPerSecond = source.mSuccessfulRxPacketsPerSecond;
623             score = source.score;
624             mIsUsable = source.mIsUsable;
625             mWifiStandard = source.mWifiStandard;
626             mMaxSupportedTxLinkSpeed = source.mMaxSupportedTxLinkSpeed;
627             mMaxSupportedRxLinkSpeed = source.mMaxSupportedRxLinkSpeed;
628             mPasspointUniqueId = shouldRedactLocationSensitiveFields(redactions)
629                     ? null : source.mPasspointUniqueId;
630             if (source.mInformationElements != null
631                     && !shouldRedactLocationSensitiveFields(redactions)) {
632                 mInformationElements = new ArrayList<>(source.mInformationElements);
633             }
634             mIsPrimary = shouldRedactNetworkSettingsFields(redactions)
635                     ? IS_PRIMARY_NO_PERMISSION : source.mIsPrimary;
636             mSecurityType = source.mSecurityType;
637             mNetworkKey = shouldRedactLocationSensitiveFields(redactions)
638                     ? null : source.mNetworkKey;
639             mApTidToLinkMappingNegotiationSupported =
640                     source.mApTidToLinkMappingNegotiationSupported;
641         }
642     }
643 
644     /** Builder for WifiInfo */
645     public static final class Builder {
646         private final WifiInfo mWifiInfo = new WifiInfo();
647 
648         /**
649          * Set the SSID, in the form of a raw byte array.
650          * @see WifiInfo#getSSID()
651          */
652         @NonNull
setSsid(@onNull byte[] ssid)653         public Builder setSsid(@NonNull byte[] ssid) {
654             mWifiInfo.setSSID(WifiSsid.fromBytes(ssid));
655             return this;
656         }
657 
658         /**
659          * Set the BSSID.
660          * @see WifiInfo#getBSSID()
661          */
662         @NonNull
setBssid(@onNull String bssid)663         public Builder setBssid(@NonNull String bssid) {
664             mWifiInfo.setBSSID(bssid);
665             return this;
666         }
667 
668         /**
669          * Set the AP MLD (Multi-Link Device) MAC Address.
670          * @see WifiInfo#getApMldMacAddress()
671          * @hide
672          */
673         @Nullable
setApMldMacAddress(@ullable MacAddress address)674         public Builder setApMldMacAddress(@Nullable MacAddress address) {
675             mWifiInfo.setApMldMacAddress(address);
676             return this;
677         }
678 
679         /**
680          * Set the access point Multi-Link Operation (MLO) link-id.
681          * @see WifiInfo#getApMloLinkId()
682          * @hide
683          */
setApMloLinkId(int linkId)684         public Builder setApMloLinkId(int linkId) {
685             mWifiInfo.setApMloLinkId(linkId);
686             return this;
687         }
688 
689         /**
690          * Set the Multi-Link Operation (MLO) affiliated Links.
691          * Only applicable for Wi-Fi 7 access points.
692          * @see WifiInfo#getAffiliatedMloLinks()
693          * @hide
694          */
setAffiliatedMloLinks(@onNull List<MloLink> links)695         public Builder setAffiliatedMloLinks(@NonNull List<MloLink> links) {
696             mWifiInfo.setAffiliatedMloLinks(links);
697             return this;
698         }
699 
700         /**
701          * Set the RSSI, in dBm.
702          * @see WifiInfo#getRssi()
703          */
704         @NonNull
setRssi(int rssi)705         public Builder setRssi(int rssi) {
706             mWifiInfo.setRssi(rssi);
707             return this;
708         }
709 
710         /**
711          * Set the network ID.
712          * @see WifiInfo#getNetworkId()
713          */
714         @NonNull
setNetworkId(int networkId)715         public Builder setNetworkId(int networkId) {
716             mWifiInfo.setNetworkId(networkId);
717             return this;
718         }
719 
720         /**
721          * Set the current security type
722          * @see WifiInfo#getCurrentSecurityType()
723          */
724         @NonNull
setCurrentSecurityType(@ifiConfiguration.SecurityType int securityType)725         public Builder setCurrentSecurityType(@WifiConfiguration.SecurityType int securityType) {
726             mWifiInfo.setCurrentSecurityType(securityType);
727             return this;
728         }
729 
730         /**
731          * Enable or Disable Peer TID-To-Link Mapping Negotiation Capability.
732          * See {@link WifiInfo#isApTidToLinkMappingNegotiationSupported()}
733          * @hide
734          */
735         @NonNull
enableApTidToLinkMappingNegotiationSupport(boolean enable)736         public Builder enableApTidToLinkMappingNegotiationSupport(boolean enable) {
737             mWifiInfo.enableApTidToLinkMappingNegotiationSupport(enable);
738             return this;
739         }
740 
741         /**
742          * Build a WifiInfo object.
743          */
744         @NonNull
build()745         public WifiInfo build() {
746             return new WifiInfo(mWifiInfo);
747         }
748     }
749 
750     /** @hide */
setSSID(WifiSsid wifiSsid)751     public void setSSID(WifiSsid wifiSsid) {
752         mWifiSsid = wifiSsid;
753     }
754 
755     /**
756      * Returns the service set identifier (SSID) of the current 802.11 network.
757      * <p>
758      * If the SSID can be decoded as UTF-8, it will be returned surrounded by double
759      * quotation marks. Otherwise, it is returned as a string of hex digits.
760      * The SSID may be {@link WifiManager#UNKNOWN_SSID}, if there is no network currently connected
761      * or if the caller has insufficient permissions to access the SSID.
762      * </p>
763      * <p>
764      * Prior to {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method
765      * always returned the SSID with no quotes around it.
766      * </p>
767      *
768      * @return the SSID.
769      */
getSSID()770     public String getSSID() {
771         if (mWifiSsid != null) {
772             String ssidString = mWifiSsid.toString();
773             if (!TextUtils.isEmpty(ssidString)) {
774                 return ssidString;
775             }
776         }
777         return WifiManager.UNKNOWN_SSID;
778     }
779 
780     /** @hide */
781     @UnsupportedAppUsage
getWifiSsid()782     public WifiSsid getWifiSsid() {
783         return mWifiSsid;
784     }
785 
786     /** @hide */
787     @UnsupportedAppUsage
setBSSID(String BSSID)788     public void setBSSID(String BSSID) {
789         mBSSID = BSSID;
790     }
791 
792     /**
793      * Set the access point Multi-Link Device (MLD) MAC Address.
794      * @hide
795      */
setApMldMacAddress(@ullable MacAddress address)796     public void setApMldMacAddress(@Nullable MacAddress address) {
797         mApMldMacAddress = address;
798     }
799 
800     /**
801      * Set the access point Multi-Link Operation (MLO) link-id
802      * @hide
803      */
setApMloLinkId(int linkId)804     public void setApMloLinkId(int linkId) {
805         mApMloLinkId = linkId;
806     }
807 
808     /**
809      * Set the Multi-Link Operation (MLO) affiliated Links.
810      * Only applicable for Wi-Fi 7 access points.
811      *
812      * @hide
813      */
setAffiliatedMloLinks(@onNull List<MloLink> links)814     public void setAffiliatedMloLinks(@NonNull List<MloLink> links) {
815         mAffiliatedMloLinks = new ArrayList<MloLink>(links);
816     }
817 
818     /**
819      * Update the MLO link STA MAC Address
820      *
821      * @param linkId for the link to be updated.
822      * @param macAddress value to be set in the link.
823      *
824      * @return true on success, false on failure
825      *
826      * @hide
827      */
updateMloLinkStaAddress(int linkId, MacAddress macAddress)828     public boolean updateMloLinkStaAddress(int linkId, MacAddress macAddress) {
829         for (MloLink link : mAffiliatedMloLinks) {
830             if (link.getLinkId() == linkId) {
831                 link.setStaMacAddress(macAddress);
832                 return true;
833             }
834         }
835         return false;
836     }
837 
838     /**
839      * Update the MLO link State
840      *
841      * @param linkId for the link to be updated.
842      * @param state value to be set in the link as one of {@link MloLink.MloLinkState}
843      *
844      * @return true on success, false on failure
845      *
846      * @hide
847      */
updateMloLinkState(int linkId, @MloLink.MloLinkState int state)848     public boolean updateMloLinkState(int linkId, @MloLink.MloLinkState int state) {
849         if (!MloLink.isValidState(state)) {
850             return false;
851         }
852 
853         for (MloLink link : mAffiliatedMloLinks) {
854             if (link.getLinkId() == linkId) {
855                 link.setState(state);
856                 return true;
857             }
858         }
859         return false;
860     }
861 
862     /**
863      * Return the basic service set identifier (BSSID) of the current access point. In case of
864      * Multi Link Operation (MLO), the BSSID corresponds to the BSSID of the link used for
865      * association.
866      * <p>
867      * The BSSID may be
868      * <lt>{@code null}, if there is no network currently connected.</lt>
869      * <lt>{@code "02:00:00:00:00:00"}, if the caller has insufficient permissions to access the
870      * BSSID.<lt>
871      * </p>
872      *
873      * @return the BSSID, in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX}
874      */
getBSSID()875     public String getBSSID() {
876         return mBSSID;
877     }
878 
879     /**
880      * Return the Multi-Link Device (MLD) MAC Address for the connected access point.
881      * <p>
882      * The returned MLD MAC Address will be {@code null} in the following cases:
883      * <lt>There is no network currently connected</lt>
884      * <lt>The connected access point is not an MLD access point,
885      * i.e. {@link #getWifiStandard()} returns {@link ScanResult#WIFI_STANDARD_11BE}.</lt>
886      * <lt>The caller has insufficient permissions to access the access point MLD MAC Address.<lt>
887      * </p>
888      *
889      * @return the MLD Mac address
890      */
891     @Nullable
getApMldMacAddress()892     public MacAddress getApMldMacAddress() {
893         return mApMldMacAddress;
894     }
895 
896     /**
897      * Return the access point Multi-Link Operation (MLO) link-id for Wi-Fi 7 access points.
898      * i.e. {@link #getWifiStandard()} returns {@link ScanResult#WIFI_STANDARD_11BE},
899      * otherwise return {@link MloLink#INVALID_MLO_LINK_ID}.
900      *
901      * Valid values are 0-15 as described in IEEE 802.11be Specification, section 9.4.2.295b.2.
902      *
903      * @return {@link MloLink#INVALID_MLO_LINK_ID} or a valid value (0-15).
904      */
905     @IntRange(from = MloLink.INVALID_MLO_LINK_ID, to = MloLink.MAX_MLO_LINK_ID)
getApMloLinkId()906     public int getApMloLinkId() {
907         return mApMloLinkId;
908     }
909 
910     /**
911      * Return the Multi-Link Operation (MLO) affiliated Links for Wi-Fi 7 access points.
912      * i.e. when {@link #getWifiStandard()} returns {@link ScanResult#WIFI_STANDARD_11BE}.
913      *
914      * Affiliated links are the links supported by the Access Point Multi Link Device (AP MLD). The
915      * Station Multi Link Device (STA MLD) gathers affiliated link information from scan results.
916      * Depending on Station's capability, it associates to all or a subset of affiliated links.
917      * <p><b>Note:</b>{@link #getAssociatedMloLinks()} returns associated links.
918      *
919      * @return List of affiliated MLO links, or an empty list if access point is not Wi-Fi 7
920      */
921     @NonNull
getAffiliatedMloLinks()922     public List<MloLink> getAffiliatedMloLinks() {
923         return new ArrayList<MloLink>(mAffiliatedMloLinks);
924     }
925 
926     /**
927      * Return the associated Multi-Link Operation (MLO) Links for Wi-Fi 7 access points.
928      * i.e. when {@link #getWifiStandard()} returns {@link ScanResult#WIFI_STANDARD_11BE}.
929      *
930      * Affiliated links are the links supported by the Access Point Multi Link Device (AP MLD). The
931      * Station Multi Link Device (STA MLD) gathers affiliated link information from scan results.
932      * Depending on Station's capability, it associates to all or a subset of affiliated links.
933      * <p><b>Note:</b>{@link #getAffiliatedMloLinks()} returns affiliated links.
934      *
935      * @return List of associated MLO links, or an empty list if access point is not a multi-link
936      * device.
937      */
938     @NonNull
getAssociatedMloLinks()939     public List<MloLink> getAssociatedMloLinks() {
940         ArrayList associatedMloLinks = new ArrayList<MloLink>();
941         for (MloLink link : getAffiliatedMloLinks()) {
942             if (link.getState() == MloLink.MLO_LINK_STATE_IDLE
943                     || link.getState() == MloLink.MLO_LINK_STATE_ACTIVE) {
944                 associatedMloLinks.add(link);
945             }
946         }
947         return associatedMloLinks;
948     }
949 
950     /**
951      * Returns the received signal strength indicator of the current 802.11 network, in dBm. In
952      * case of Multi Link Operation (MLO), returned RSSI is the highest of all associated links.
953      * <p>
954      * Use {@link android.net.wifi.WifiManager#calculateSignalLevel} to convert this number into
955      * an absolute signal level which can be displayed to a user.
956      * </p>
957      *
958      * @return the RSSI.
959      */
getRssi()960     public int getRssi() {
961         return mRssi;
962     }
963 
964     /** @hide */
965     @UnsupportedAppUsage
setRssi(int rssi)966     public void setRssi(int rssi) {
967         if (rssi < INVALID_RSSI)
968             rssi = INVALID_RSSI;
969         if (rssi > MAX_RSSI)
970             rssi = MAX_RSSI;
971         mRssi = rssi;
972     }
973 
974     /**
975      * Sets the Wi-Fi standard
976      * @hide
977      */
setWifiStandard(@ifiAnnotations.WifiStandard int wifiStandard)978     public void setWifiStandard(@WifiAnnotations.WifiStandard int wifiStandard) {
979         mWifiStandard = wifiStandard;
980     }
981 
982     /**
983      * Get connection Wi-Fi standard
984      * @return the connection Wi-Fi standard
985      */
getWifiStandard()986     public @WifiAnnotations.WifiStandard int getWifiStandard() {
987         return mWifiStandard;
988     }
989 
990     /**
991      * Returns the current link speed in {@link #LINK_SPEED_UNITS}. In case of Multi Link Operation
992      * (MLO), returned value is the current link speed of the associated link with the highest RSSI.
993      *
994      * @return the link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown.
995      * @see #LINK_SPEED_UNITS
996      * @see #LINK_SPEED_UNKNOWN
997      */
getLinkSpeed()998     public int getLinkSpeed() {
999         return mLinkSpeed;
1000     }
1001 
1002     /** @hide */
1003     @UnsupportedAppUsage
setLinkSpeed(int linkSpeed)1004     public void setLinkSpeed(int linkSpeed) {
1005         mLinkSpeed = linkSpeed;
1006     }
1007 
1008     /**
1009      * Returns the current transmit link speed in Mbps. In case of Multi Link Operation (MLO),
1010      * returned value is the current transmit link speed of the associated link with the highest
1011      * RSSI.
1012      *
1013      * @return the Tx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown.
1014      * @see #LINK_SPEED_UNKNOWN
1015      */
1016     @IntRange(from = -1)
getTxLinkSpeedMbps()1017     public int getTxLinkSpeedMbps() {
1018         return mTxLinkSpeed;
1019     }
1020 
1021     /**
1022      * Returns the maximum supported transmit link speed in Mbps
1023      * @return the max supported tx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is
1024      * unknown. @see #LINK_SPEED_UNKNOWN
1025      */
getMaxSupportedTxLinkSpeedMbps()1026     public int getMaxSupportedTxLinkSpeedMbps() {
1027         return mMaxSupportedTxLinkSpeed;
1028     }
1029 
1030     /**
1031      * Update the last transmitted packet bit rate in Mbps.
1032      * @hide
1033      */
setTxLinkSpeedMbps(int txLinkSpeed)1034     public void setTxLinkSpeedMbps(int txLinkSpeed) {
1035         mTxLinkSpeed = txLinkSpeed;
1036     }
1037 
1038     /**
1039      * Set the maximum supported transmit link speed in Mbps
1040      * @hide
1041      */
setMaxSupportedTxLinkSpeedMbps(int maxSupportedTxLinkSpeed)1042     public void setMaxSupportedTxLinkSpeedMbps(int maxSupportedTxLinkSpeed) {
1043         mMaxSupportedTxLinkSpeed = maxSupportedTxLinkSpeed;
1044     }
1045 
1046     /**
1047      * Returns the current receive link speed in Mbps. In case of Multi Link Operation (MLO),
1048      * returned value is the receive link speed of the associated link with the highest RSSI.
1049      *
1050      * @return the Rx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown.
1051      * @see #LINK_SPEED_UNKNOWN
1052      */
1053     @IntRange(from = -1)
getRxLinkSpeedMbps()1054     public int getRxLinkSpeedMbps() {
1055         return mRxLinkSpeed;
1056     }
1057 
1058     /**
1059      * Returns the maximum supported receive link speed in Mbps
1060      * @return the max supported Rx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is
1061      * unknown. @see #LINK_SPEED_UNKNOWN
1062      */
getMaxSupportedRxLinkSpeedMbps()1063     public int getMaxSupportedRxLinkSpeedMbps() {
1064         return mMaxSupportedRxLinkSpeed;
1065     }
1066 
1067     /**
1068      * Update the last received packet bit rate in Mbps.
1069      * @hide
1070      */
setRxLinkSpeedMbps(int rxLinkSpeed)1071     public void setRxLinkSpeedMbps(int rxLinkSpeed) {
1072         mRxLinkSpeed = rxLinkSpeed;
1073     }
1074 
1075     /**
1076      * Set the maximum supported receive link speed in Mbps
1077      * @hide
1078      */
setMaxSupportedRxLinkSpeedMbps(int maxSupportedRxLinkSpeed)1079     public void setMaxSupportedRxLinkSpeedMbps(int maxSupportedRxLinkSpeed) {
1080         mMaxSupportedRxLinkSpeed = maxSupportedRxLinkSpeed;
1081     }
1082 
1083     /**
1084      * Returns the current frequency in {@link #FREQUENCY_UNITS}. In case of Multi Link Operation
1085      * (MLO), returned value is the frequency of the associated link with the highest RSSI.
1086      *
1087      * @return the frequency.
1088      * @see #FREQUENCY_UNITS
1089      */
getFrequency()1090     public int getFrequency() {
1091         return mFrequency;
1092     }
1093 
1094     /** @hide */
setFrequency(int frequency)1095     public void setFrequency(int frequency) {
1096         this.mFrequency = frequency;
1097     }
1098 
1099     /**
1100      * @hide
1101      */
is24GHz()1102     public boolean is24GHz() {
1103         return ScanResult.is24GHz(mFrequency);
1104     }
1105 
1106     /**
1107      * @hide
1108      */
1109     @UnsupportedAppUsage
is5GHz()1110     public boolean is5GHz() {
1111         return ScanResult.is5GHz(mFrequency);
1112     }
1113 
1114     /**
1115      * @hide
1116      */
is6GHz()1117     public boolean is6GHz() {
1118         return ScanResult.is6GHz(mFrequency);
1119     }
1120 
1121     /**
1122      * Record the MAC address of the WLAN interface
1123      * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form
1124      * @hide
1125      */
1126     @UnsupportedAppUsage
setMacAddress(String macAddress)1127     public void setMacAddress(String macAddress) {
1128         this.mMacAddress = macAddress;
1129     }
1130 
1131     /**
1132      * Returns the MAC address used for this connection. In case of Multi Link Operation (MLO),
1133      * returned value is the mac address of the link used for association.
1134      *
1135      * @return MAC address of the connection or {@code "02:00:00:00:00:00"} if the caller has
1136      * insufficient permission.
1137      *
1138      * Requires {@code android.Manifest.permission#LOCAL_MAC_ADDRESS} and
1139      * {@link android.Manifest.permission#ACCESS_FINE_LOCATION}.
1140      */
getMacAddress()1141     public String getMacAddress() {
1142         return mMacAddress;
1143     }
1144 
1145     /**
1146      * @return true if {@link #getMacAddress()} has a real MAC address.
1147      *
1148      * @hide
1149      */
hasRealMacAddress()1150     public boolean hasRealMacAddress() {
1151         return mMacAddress != null && !DEFAULT_MAC_ADDRESS.equals(mMacAddress);
1152     }
1153 
1154     /**
1155      * Indicates if we've dynamically detected this active network connection as
1156      * being metered.
1157      *
1158      * @see WifiConfiguration#isMetered(WifiConfiguration, WifiInfo)
1159      * @hide
1160      */
setMeteredHint(boolean meteredHint)1161     public void setMeteredHint(boolean meteredHint) {
1162         mMeteredHint = meteredHint;
1163     }
1164 
1165     /** @hide */
1166     @UnsupportedAppUsage
getMeteredHint()1167     public boolean getMeteredHint() {
1168         return mMeteredHint;
1169     }
1170 
1171     /** @hide */
setEphemeral(boolean ephemeral)1172     public void setEphemeral(boolean ephemeral) {
1173         mEphemeral = ephemeral;
1174     }
1175 
1176     /**
1177      * Returns true if the current Wifi network is ephemeral, false otherwise.
1178      * An ephemeral network is a network that is temporary and not persisted in the system.
1179      * Ephemeral networks cannot be forgotten, only disabled with
1180      * {@link WifiManager#disableEphemeralNetwork(String)}.
1181      *
1182      * @hide
1183      */
1184     @SystemApi
isEphemeral()1185     public boolean isEphemeral() {
1186         return mEphemeral;
1187     }
1188 
1189     /** @hide */
setTrusted(boolean trusted)1190     public void setTrusted(boolean trusted) {
1191         mTrusted = trusted;
1192     }
1193 
1194     /**
1195      * Returns true if the current Wifi network is a trusted network, false otherwise.
1196      * @see WifiNetworkSuggestion.Builder#setUntrusted(boolean).
1197      * @hide
1198      */
1199     @SystemApi
isTrusted()1200     public boolean isTrusted() {
1201         return mTrusted;
1202     }
1203 
1204     /** @hide */
setRestricted(boolean restricted)1205     public void setRestricted(boolean restricted) {
1206         mRestricted = restricted;
1207     }
1208 
1209     /**
1210      * Returns true if the current Wifi network is a restricted network, false otherwise.
1211      * A restricted network has its {@link NetworkCapabilities#NET_CAPABILITY_NOT_RESTRICTED}
1212      * capability removed.
1213      * @see WifiNetworkSuggestion.Builder#setRestricted(boolean).
1214      */
isRestricted()1215     public boolean isRestricted() {
1216         return mRestricted;
1217     }
1218 
1219     /** @hide */
setOemPaid(boolean oemPaid)1220     public void setOemPaid(boolean oemPaid) {
1221         mOemPaid = oemPaid;
1222     }
1223 
1224     /**
1225      * Returns true if the current Wifi network is an oem paid network, false otherwise.
1226      * @see WifiNetworkSuggestion.Builder#setOemPaid(boolean).
1227      * @hide
1228      */
1229     @RequiresApi(Build.VERSION_CODES.S)
1230     @SystemApi
isOemPaid()1231     public boolean isOemPaid() {
1232         if (!SdkLevel.isAtLeastS()) {
1233             throw new UnsupportedOperationException();
1234         }
1235         return mOemPaid;
1236     }
1237 
1238     /** @hide */
setOemPrivate(boolean oemPrivate)1239     public void setOemPrivate(boolean oemPrivate) {
1240         mOemPrivate = oemPrivate;
1241     }
1242 
1243     /**
1244      * Returns true if the current Wifi network is an oem private network, false otherwise.
1245      * @see WifiNetworkSuggestion.Builder#setOemPrivate(boolean).
1246      * @hide
1247      */
1248     @RequiresApi(Build.VERSION_CODES.S)
1249     @SystemApi
isOemPrivate()1250     public boolean isOemPrivate() {
1251         if (!SdkLevel.isAtLeastS()) {
1252             throw new UnsupportedOperationException();
1253         }
1254         return mOemPrivate;
1255     }
1256 
1257     /**
1258      * @hide
1259      */
setCarrierMerged(boolean carrierMerged)1260     public void setCarrierMerged(boolean carrierMerged) {
1261         mCarrierMerged = carrierMerged;
1262     }
1263 
1264     /**
1265      * Returns true if the current Wifi network is a carrier merged network, false otherwise.
1266      * @see WifiNetworkSuggestion.Builder#setCarrierMerged(boolean).
1267      * @hide
1268      */
1269     @SystemApi
1270     @RequiresApi(Build.VERSION_CODES.S)
isCarrierMerged()1271     public boolean isCarrierMerged() {
1272         if (!SdkLevel.isAtLeastS()) {
1273             throw new UnsupportedOperationException();
1274         }
1275         return mCarrierMerged;
1276     }
1277 
1278 
1279     /** @hide */
setOsuAp(boolean osuAp)1280     public void setOsuAp(boolean osuAp) {
1281         mOsuAp = osuAp;
1282     }
1283 
1284     /** @hide */
1285     @SystemApi
isOsuAp()1286     public boolean isOsuAp() {
1287         return mOsuAp;
1288     }
1289 
1290     /** @hide */
1291     @SystemApi
isPasspointAp()1292     public boolean isPasspointAp() {
1293         return mFqdn != null && mProviderFriendlyName != null;
1294     }
1295 
1296     /** @hide */
setFQDN(@ullable String fqdn)1297     public void setFQDN(@Nullable String fqdn) {
1298         mFqdn = fqdn;
1299     }
1300 
1301     /**
1302      * Returns the Fully Qualified Domain Name of the network if it is a Passpoint network.
1303      * <p>
1304      * The FQDN may be
1305      * <lt>{@code null} if no network currently connected, currently connected network is not
1306      * passpoint network or the caller has insufficient permissions to access the FQDN.</lt>
1307      * </p>
1308      */
getPasspointFqdn()1309     public @Nullable String getPasspointFqdn() {
1310         return mFqdn;
1311     }
1312 
1313     /** @hide */
setProviderFriendlyName(@ullable String providerFriendlyName)1314     public void setProviderFriendlyName(@Nullable String providerFriendlyName) {
1315         mProviderFriendlyName = providerFriendlyName;
1316     }
1317 
1318     /**
1319      * Returns the Provider Friendly Name of the network if it is a Passpoint network.
1320      * <p>
1321      * The Provider Friendly Name may be
1322      * <lt>{@code null} if no network currently connected, currently connected network is not
1323      * passpoint network or the caller has insufficient permissions to access the Provider Friendly
1324      * Name. </lt>
1325      * </p>
1326      */
getPasspointProviderFriendlyName()1327     public @Nullable String getPasspointProviderFriendlyName() {
1328         return mProviderFriendlyName;
1329     }
1330 
1331     /** @hide */
setRequestingPackageName(@ullable String packageName)1332     public void setRequestingPackageName(@Nullable String packageName) {
1333         mRequestingPackageName = packageName;
1334     }
1335 
1336     /**
1337      * If this network was created in response to an app request (e.g. through Network Suggestion
1338      * or Network Specifier), return the package name of the app that made the request.
1339      * Null otherwise.
1340      * @hide
1341      */
1342     @SystemApi
getRequestingPackageName()1343     public @Nullable String getRequestingPackageName() {
1344         return mRequestingPackageName;
1345     }
1346 
1347     /** @hide */
setSubscriptionId(int subId)1348     public void setSubscriptionId(int subId) {
1349         mSubscriptionId = subId;
1350     }
1351 
1352     /**
1353      * If this network is provisioned by a carrier, returns subscription Id corresponding to the
1354      * associated SIM on the device. If this network is not provisioned by a carrier, returns
1355      * {@link android.telephony.SubscriptionManager#INVALID_SUBSCRIPTION_ID}
1356      *
1357      * @see WifiNetworkSuggestion.Builder#setSubscriptionId(int)
1358      * @see android.telephony.SubscriptionInfo#getSubscriptionId()
1359      */
1360     @RequiresApi(Build.VERSION_CODES.S)
getSubscriptionId()1361     public int getSubscriptionId() {
1362         if (!SdkLevel.isAtLeastS()) {
1363             throw new UnsupportedOperationException();
1364         }
1365         return mSubscriptionId;
1366     }
1367 
1368 
1369     /** @hide */
1370     @UnsupportedAppUsage
setNetworkId(int id)1371     public void setNetworkId(int id) {
1372         mNetworkId = id;
1373     }
1374 
1375     /**
1376      * Each configured network has a unique small integer ID, used to identify
1377      * the network. This method returns the ID for the currently connected network.
1378      * <p>
1379      * The networkId may be {@code -1} if there is no currently connected network or if the caller
1380      * has insufficient permissions to access the network ID.
1381      * </p>
1382      *
1383      * @return the network ID.
1384      */
getNetworkId()1385     public int getNetworkId() {
1386         return mNetworkId;
1387     }
1388 
1389     /**
1390      * Return the detailed state of the supplicant's negotiation with an
1391      * access point, in the form of a {@link SupplicantState SupplicantState} object.
1392      * @return the current {@link SupplicantState SupplicantState}
1393      */
getSupplicantState()1394     public SupplicantState getSupplicantState() {
1395         return mSupplicantState;
1396     }
1397 
1398     /** @hide */
1399     @UnsupportedAppUsage
setSupplicantState(SupplicantState state)1400     public void setSupplicantState(SupplicantState state) {
1401         mSupplicantState = state;
1402     }
1403 
1404     /** @hide */
setInetAddress(InetAddress address)1405     public void setInetAddress(InetAddress address) {
1406         mIpAddress = address;
1407     }
1408 
1409     /**
1410      * @deprecated Use the methods on {@link android.net.LinkProperties} which can be obtained
1411      * either via {@link NetworkCallback#onLinkPropertiesChanged(Network, LinkProperties)} or
1412      * {@link ConnectivityManager#getLinkProperties(Network)}.
1413      */
1414     @Deprecated
getIpAddress()1415     public int getIpAddress() {
1416         int result = 0;
1417         if (mIpAddress instanceof Inet4Address) {
1418             result = Inet4AddressUtils.inet4AddressToIntHTL((Inet4Address) mIpAddress);
1419         }
1420         return result;
1421     }
1422 
1423     /**
1424      * @return {@code true} if this network does not broadcast its SSID, so an
1425      * SSID-specific probe request must be used for scans.
1426      */
getHiddenSSID()1427     public boolean getHiddenSSID() {
1428         return mIsHiddenSsid;
1429     }
1430 
1431     /**
1432      * Sets whether or not this network is using a hidden SSID. This value should be set from the
1433      * corresponding {@link WifiConfiguration} of the network.
1434      * @hide
1435      */
setHiddenSSID(boolean isHiddenSsid)1436     public void setHiddenSSID(boolean isHiddenSsid) {
1437         mIsHiddenSsid = isHiddenSsid;
1438     }
1439 
1440     /**
1441      * Map a supplicant state into a fine-grained network connectivity state.
1442      * @param suppState the supplicant state
1443      * @return the corresponding {@link DetailedState}
1444      */
getDetailedStateOf(SupplicantState suppState)1445     public static DetailedState getDetailedStateOf(SupplicantState suppState) {
1446         return stateMap.get(suppState);
1447     }
1448 
1449     /**
1450      * Set the <code>SupplicantState</code> from the string name
1451      * of the state.
1452      * @param stateName the name of the state, as a <code>String</code> returned
1453      * in an event sent by {@code wpa_supplicant}.
1454      */
1455     @UnsupportedAppUsage
setSupplicantState(String stateName)1456     void setSupplicantState(String stateName) {
1457         mSupplicantState = valueOf(stateName);
1458     }
1459 
valueOf(String stateName)1460     static SupplicantState valueOf(String stateName) {
1461         if ("4WAY_HANDSHAKE".equalsIgnoreCase(stateName))
1462             return SupplicantState.FOUR_WAY_HANDSHAKE;
1463         else {
1464             try {
1465                 return SupplicantState.valueOf(stateName.toUpperCase(Locale.ROOT));
1466             } catch (IllegalArgumentException e) {
1467                 return SupplicantState.INVALID;
1468             }
1469         }
1470     }
1471 
1472     /**
1473      * Remove double quotes (") surrounding a SSID string, if present. Otherwise, return the
1474      * string unmodified. Return null if the input string was null.
1475      * @hide
1476      */
1477     @Nullable
1478     @SystemApi
sanitizeSsid(@ullable String string)1479     public static String sanitizeSsid(@Nullable String string) {
1480         return removeDoubleQuotes(string);
1481     }
1482 
1483     /** @hide */
1484     @UnsupportedAppUsage
1485     @Nullable
removeDoubleQuotes(@ullable String string)1486     public static String removeDoubleQuotes(@Nullable String string) {
1487         if (string == null) return null;
1488         final int length = string.length();
1489         if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
1490             return string.substring(1, length - 1);
1491         }
1492         return string;
1493     }
1494 
1495     @Override
toString()1496     public String toString() {
1497         StringBuffer sb = new StringBuffer();
1498         String none = "<none>";
1499 
1500         sb.append("SSID: ").append(getSSID())
1501                 .append(", BSSID: ").append(mBSSID == null ? none : mBSSID)
1502                 .append(", MAC: ").append(mMacAddress == null ? none : mMacAddress)
1503                 .append(", IP: ").append(mIpAddress)
1504                 .append(", Security type: ").append(mSecurityType)
1505                 .append(", Supplicant state: ")
1506                 .append(mSupplicantState == null ? none : mSupplicantState)
1507                 .append(", Wi-Fi standard: ").append(mWifiStandard)
1508                 .append(", RSSI: ").append(mRssi)
1509                 .append(", Link speed: ").append(mLinkSpeed).append(LINK_SPEED_UNITS)
1510                 .append(", Tx Link speed: ").append(mTxLinkSpeed).append(LINK_SPEED_UNITS)
1511                 .append(", Max Supported Tx Link speed: ")
1512                 .append(mMaxSupportedTxLinkSpeed).append(LINK_SPEED_UNITS)
1513                 .append(", Rx Link speed: ").append(mRxLinkSpeed).append(LINK_SPEED_UNITS)
1514                 .append(", Max Supported Rx Link speed: ")
1515                 .append(mMaxSupportedRxLinkSpeed).append(LINK_SPEED_UNITS)
1516                 .append(", Frequency: ").append(mFrequency).append(FREQUENCY_UNITS)
1517                 .append(", Net ID: ").append(mNetworkId)
1518                 .append(", Metered hint: ").append(mMeteredHint)
1519                 .append(", score: ").append(Integer.toString(score))
1520                 .append(", isUsable: ").append(mIsUsable)
1521                 .append(", CarrierMerged: ").append(mCarrierMerged)
1522                 .append(", SubscriptionId: ").append(mSubscriptionId)
1523                 .append(", IsPrimary: ").append(mIsPrimary)
1524                 .append(", Trusted: ").append(mTrusted)
1525                 .append(", Restricted: ").append(mRestricted)
1526                 .append(", Ephemeral: ").append(mEphemeral)
1527                 .append(", OEM paid: ").append(mOemPaid)
1528                 .append(", OEM private: ").append(mOemPrivate)
1529                 .append(", OSU AP: ").append(mOsuAp)
1530                 .append(", FQDN: ").append(mFqdn == null ? none : mFqdn)
1531                 .append(", Provider friendly name: ")
1532                 .append(mProviderFriendlyName == null ? none : mProviderFriendlyName)
1533                 .append(", Requesting package name: ")
1534                 .append(mRequestingPackageName == null ? none : mRequestingPackageName)
1535                 .append(mNetworkKey == null ? none : mNetworkKey)
1536                 .append("MLO Information: ")
1537                 .append(", Is TID-To-Link negotiation supported by the AP: ")
1538                 .append(mApTidToLinkMappingNegotiationSupported)
1539                 .append(", AP MLD Address: ").append(
1540                         mApMldMacAddress == null ? none : mApMldMacAddress.toString())
1541                 .append(", AP MLO Link Id: ").append(
1542                         mApMldMacAddress == null ? none : mApMloLinkId)
1543                 .append(", AP MLO Affiliated links: ").append(
1544                         mApMldMacAddress == null ? none : mAffiliatedMloLinks);
1545 
1546         return sb.toString();
1547     }
1548 
1549     /** Implement the Parcelable interface {@hide} */
describeContents()1550     public int describeContents() {
1551         return 0;
1552     }
1553 
shouldRedactLocationSensitiveFields(long redactions)1554     private boolean shouldRedactLocationSensitiveFields(long redactions) {
1555         return (redactions & NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION) != 0;
1556     }
1557 
shouldRedactLocalMacAddressFields(long redactions)1558     private boolean shouldRedactLocalMacAddressFields(long redactions) {
1559         return (redactions & NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS) != 0;
1560     }
1561 
shouldRedactNetworkSettingsFields(long redactions)1562     private boolean shouldRedactNetworkSettingsFields(long redactions) {
1563         return (redactions & NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS) != 0;
1564     }
1565 
1566     /** Implement the Parcelable interface {@hide} */
writeToParcel(Parcel dest, int flags)1567     public void writeToParcel(Parcel dest, int flags) {
1568         dest.writeInt(mNetworkId);
1569         dest.writeInt(mRssi);
1570         dest.writeInt(mLinkSpeed);
1571         dest.writeInt(mTxLinkSpeed);
1572         dest.writeInt(mRxLinkSpeed);
1573         dest.writeInt(mFrequency);
1574         if (mIpAddress != null) {
1575             dest.writeByte((byte)1);
1576             dest.writeByteArray(mIpAddress.getAddress());
1577         } else {
1578             dest.writeByte((byte)0);
1579         }
1580         if (mWifiSsid != null) {
1581             dest.writeInt(1);
1582             mWifiSsid.writeToParcel(dest, flags);
1583         } else {
1584             dest.writeInt(0);
1585         }
1586         dest.writeString(mBSSID);
1587         dest.writeString(mMacAddress);
1588         dest.writeInt(mMeteredHint ? 1 : 0);
1589         dest.writeInt(mEphemeral ? 1 : 0);
1590         dest.writeInt(mTrusted ? 1 : 0);
1591         dest.writeInt(mOemPaid ? 1 : 0);
1592         dest.writeInt(mOemPrivate ? 1 : 0);
1593         dest.writeInt(mCarrierMerged ? 1 : 0);
1594         dest.writeInt(score);
1595         dest.writeBoolean(mIsUsable);
1596         dest.writeLong(txSuccess);
1597         dest.writeDouble(mSuccessfulTxPacketsPerSecond);
1598         dest.writeLong(txRetries);
1599         dest.writeDouble(mTxRetriedTxPacketsPerSecond);
1600         dest.writeLong(txBad);
1601         dest.writeDouble(mLostTxPacketsPerSecond);
1602         dest.writeLong(rxSuccess);
1603         dest.writeDouble(mSuccessfulRxPacketsPerSecond);
1604         mSupplicantState.writeToParcel(dest, flags);
1605         dest.writeInt(mOsuAp ? 1 : 0);
1606         dest.writeString(mRequestingPackageName);
1607         dest.writeString(mFqdn);
1608         dest.writeString(mProviderFriendlyName);
1609         dest.writeInt(mWifiStandard);
1610         dest.writeInt(mMaxSupportedTxLinkSpeed);
1611         dest.writeInt(mMaxSupportedRxLinkSpeed);
1612         dest.writeString(mPasspointUniqueId);
1613         dest.writeInt(mSubscriptionId);
1614         dest.writeTypedList(mInformationElements);
1615         if (SdkLevel.isAtLeastS()) {
1616             dest.writeInt(mIsPrimary);
1617         }
1618         dest.writeInt(mSecurityType);
1619         dest.writeInt(mRestricted ? 1 : 0);
1620         dest.writeString(mNetworkKey);
1621         dest.writeParcelable(mApMldMacAddress, flags);
1622         dest.writeInt(mApMloLinkId);
1623         dest.writeTypedList(mAffiliatedMloLinks);
1624         dest.writeBoolean(mApTidToLinkMappingNegotiationSupported);
1625     }
1626 
1627     /** Implement the Parcelable interface {@hide} */
1628     @UnsupportedAppUsage
1629     public static final @android.annotation.NonNull Creator<WifiInfo> CREATOR =
1630         new Creator<WifiInfo>() {
1631             public WifiInfo createFromParcel(Parcel in) {
1632                 WifiInfo info = new WifiInfo();
1633                 info.setNetworkId(in.readInt());
1634                 info.setRssi(in.readInt());
1635                 info.setLinkSpeed(in.readInt());
1636                 info.setTxLinkSpeedMbps(in.readInt());
1637                 info.setRxLinkSpeedMbps(in.readInt());
1638                 info.setFrequency(in.readInt());
1639                 if (in.readByte() == 1) {
1640                     try {
1641                         info.setInetAddress(InetAddress.getByAddress(in.createByteArray()));
1642                     } catch (UnknownHostException e) {}
1643                 }
1644                 if (in.readInt() == 1) {
1645                     info.mWifiSsid = WifiSsid.CREATOR.createFromParcel(in);
1646                 }
1647                 info.mBSSID = in.readString();
1648                 info.mMacAddress = in.readString();
1649                 info.mMeteredHint = in.readInt() != 0;
1650                 info.mEphemeral = in.readInt() != 0;
1651                 info.mTrusted = in.readInt() != 0;
1652                 info.mOemPaid = in.readInt() != 0;
1653                 info.mOemPrivate = in.readInt() != 0;
1654                 info.mCarrierMerged = in.readInt() != 0;
1655                 info.score = in.readInt();
1656                 info.mIsUsable = in.readBoolean();
1657                 info.txSuccess = in.readLong();
1658                 info.mSuccessfulTxPacketsPerSecond = in.readDouble();
1659                 info.txRetries = in.readLong();
1660                 info.mTxRetriedTxPacketsPerSecond = in.readDouble();
1661                 info.txBad = in.readLong();
1662                 info.mLostTxPacketsPerSecond = in.readDouble();
1663                 info.rxSuccess = in.readLong();
1664                 info.mSuccessfulRxPacketsPerSecond = in.readDouble();
1665                 info.mSupplicantState = SupplicantState.CREATOR.createFromParcel(in);
1666                 info.mOsuAp = in.readInt() != 0;
1667                 info.mRequestingPackageName = in.readString();
1668                 info.mFqdn = in.readString();
1669                 info.mProviderFriendlyName = in.readString();
1670                 info.mWifiStandard = in.readInt();
1671                 info.mMaxSupportedTxLinkSpeed = in.readInt();
1672                 info.mMaxSupportedRxLinkSpeed = in.readInt();
1673                 info.mPasspointUniqueId = in.readString();
1674                 info.mSubscriptionId = in.readInt();
1675                 info.mInformationElements = in.createTypedArrayList(
1676                         ScanResult.InformationElement.CREATOR);
1677                 if (SdkLevel.isAtLeastS()) {
1678                     info.mIsPrimary = in.readInt();
1679                 }
1680                 info.mSecurityType = in.readInt();
1681                 info.mRestricted = in.readInt() != 0;
1682                 info.mNetworkKey = in.readString();
1683 
1684                 info.mApMldMacAddress = in.readParcelable(MacAddress.class.getClassLoader());
1685                 info.mApMloLinkId = in.readInt();
1686                 info.mAffiliatedMloLinks = in.createTypedArrayList(MloLink.CREATOR);
1687                 info.mApTidToLinkMappingNegotiationSupported = in.readBoolean();
1688                 return info;
1689             }
1690 
1691             public WifiInfo[] newArray(int size) {
1692                 return new WifiInfo[size];
1693             }
1694         };
1695 
1696     /**
1697      * Set the Passpoint unique identifier for the current connection
1698      *
1699      * @param passpointUniqueId Unique identifier
1700      * @hide
1701      */
setPasspointUniqueId(@ullable String passpointUniqueId)1702     public void setPasspointUniqueId(@Nullable String passpointUniqueId) {
1703         mPasspointUniqueId = passpointUniqueId;
1704     }
1705 
1706     /**
1707      * Get the Passpoint unique identifier for the current connection
1708      *
1709      * @return Passpoint unique identifier
1710      * @hide
1711      */
getPasspointUniqueId()1712     public @Nullable String getPasspointUniqueId() {
1713         return mPasspointUniqueId;
1714     }
1715 
1716     /**
1717      * Set the information elements found in the becaon of the connected bssid.
1718      * @hide
1719      */
setInformationElements(@ullable List<ScanResult.InformationElement> infoElements)1720     public void setInformationElements(@Nullable List<ScanResult.InformationElement> infoElements) {
1721         if (infoElements == null) {
1722             mInformationElements = null;
1723             return;
1724         }
1725         mInformationElements = new ArrayList<>(infoElements);
1726     }
1727 
1728     /**
1729      * Get all information elements found in the beacon of the connected bssid.
1730      * <p>
1731      * The information elements will be {@code null} if there is no network currently connected or
1732      * if the caller has insufficient permissions to access the info elements.
1733      * </p>
1734      *
1735      * @return List of information elements {@link ScanResult.InformationElement} or null.
1736      */
1737     @Nullable
1738     @SuppressWarnings("NullableCollection")
getInformationElements()1739     public List<ScanResult.InformationElement> getInformationElements() {
1740         if (mInformationElements == null) return null;
1741         return new ArrayList<>(mInformationElements);
1742     }
1743 
1744     /**
1745      * @see #isPrimary()
1746      * @hide
1747      */
setIsPrimary(boolean isPrimary)1748     public void setIsPrimary(boolean isPrimary) {
1749         mIsPrimary = isPrimary ? IS_PRIMARY_TRUE : IS_PRIMARY_FALSE;
1750     }
1751 
1752     /**
1753      * Returns whether this is the primary wifi connection or not.
1754      *
1755      * Wifi service considers this connection to be the best among all Wifi connections, and this
1756      * connection should be the one surfaced to the user if only one can be displayed.
1757      *
1758      * Note that the default route (chosen by Connectivity Service) may not correspond to the
1759      * primary Wifi connection e.g. when there exists a better cellular network, or if the
1760      * primary Wifi connection doesn't have internet access.
1761      *
1762      * @return whether this is the primary connection or not.
1763      *
1764      * @hide
1765      */
1766     @RequiresApi(Build.VERSION_CODES.S)
1767     @RequiresPermission(Manifest.permission.NETWORK_SETTINGS)
1768     @SystemApi
isPrimary()1769     public boolean isPrimary() {
1770         if (!SdkLevel.isAtLeastS()) {
1771             // Intentional - since we don't support STA + STA on older devices, this field
1772             // is redundant. Don't allow anyone to use this.
1773             throw new UnsupportedOperationException();
1774         }
1775         if (mIsPrimary == IS_PRIMARY_NO_PERMISSION) {
1776             throw new SecurityException("Not allowed to access this field");
1777         }
1778         return mIsPrimary == IS_PRIMARY_TRUE;
1779     }
1780 
getSortedMloLinkList(List<MloLink> list)1781     private List<MloLink> getSortedMloLinkList(List<MloLink> list) {
1782         List<MloLink> newList = new ArrayList<MloLink>(list);
1783         Collections.sort(newList, new Comparator<MloLink>() {
1784             @Override
1785             public int compare(MloLink lhs, MloLink rhs) {
1786                 return lhs.getLinkId() -  rhs.getLinkId();
1787             }
1788         });
1789 
1790         return newList;
1791     }
1792 
1793     @Override
equals(Object that)1794     public boolean equals(Object that) {
1795         if (this == that) return true;
1796 
1797         // Potential API behavior change, so don't change behavior on older devices.
1798         if (!SdkLevel.isAtLeastS()) return false;
1799 
1800         if (!(that instanceof WifiInfo)) return false;
1801 
1802         WifiInfo thatWifiInfo = (WifiInfo) that;
1803 
1804         // compare the MLO affiliated links irrespective of the order
1805         if (!Objects.equals(getSortedMloLinkList(mAffiliatedMloLinks),
1806                   getSortedMloLinkList(thatWifiInfo.mAffiliatedMloLinks))) {
1807             return false;
1808         }
1809 
1810         return Objects.equals(mWifiSsid, thatWifiInfo.mWifiSsid)
1811                 && Objects.equals(mBSSID, thatWifiInfo.mBSSID)
1812                 && Objects.equals(mApMldMacAddress, thatWifiInfo.mApMldMacAddress)
1813                 && mApMloLinkId == thatWifiInfo.mApMloLinkId
1814                 && Objects.equals(mNetworkId, thatWifiInfo.mNetworkId)
1815                 && Objects.equals(mRssi, thatWifiInfo.mRssi)
1816                 && Objects.equals(mSupplicantState, thatWifiInfo.mSupplicantState)
1817                 && Objects.equals(mLinkSpeed, thatWifiInfo.mLinkSpeed)
1818                 && Objects.equals(mTxLinkSpeed, thatWifiInfo.mTxLinkSpeed)
1819                 && Objects.equals(mRxLinkSpeed, thatWifiInfo.mRxLinkSpeed)
1820                 && Objects.equals(mFrequency, thatWifiInfo.mFrequency)
1821                 && Objects.equals(mIpAddress, thatWifiInfo.mIpAddress)
1822                 && Objects.equals(mMacAddress, thatWifiInfo.mMacAddress)
1823                 && Objects.equals(mMeteredHint, thatWifiInfo.mMeteredHint)
1824                 && Objects.equals(mEphemeral, thatWifiInfo.mEphemeral)
1825                 && Objects.equals(mTrusted, thatWifiInfo.mTrusted)
1826                 && Objects.equals(mOemPaid, thatWifiInfo.mOemPaid)
1827                 && Objects.equals(mOemPrivate, thatWifiInfo.mOemPrivate)
1828                 && Objects.equals(mCarrierMerged, thatWifiInfo.mCarrierMerged)
1829                 && Objects.equals(mRequestingPackageName, thatWifiInfo.mRequestingPackageName)
1830                 && Objects.equals(mOsuAp, thatWifiInfo.mOsuAp)
1831                 && Objects.equals(mFqdn, thatWifiInfo.mFqdn)
1832                 && Objects.equals(mProviderFriendlyName, thatWifiInfo.mProviderFriendlyName)
1833                 && Objects.equals(mSubscriptionId, thatWifiInfo.mSubscriptionId)
1834                 && Objects.equals(txBad, thatWifiInfo.txBad)
1835                 && Objects.equals(txRetries, thatWifiInfo.txRetries)
1836                 && Objects.equals(txSuccess, thatWifiInfo.txSuccess)
1837                 && Objects.equals(rxSuccess, thatWifiInfo.rxSuccess)
1838                 && Objects.equals(mLostTxPacketsPerSecond, thatWifiInfo.mLostTxPacketsPerSecond)
1839                 && Objects.equals(mTxRetriedTxPacketsPerSecond,
1840                 thatWifiInfo.mTxRetriedTxPacketsPerSecond)
1841                 && Objects.equals(mSuccessfulTxPacketsPerSecond,
1842                 thatWifiInfo.mSuccessfulTxPacketsPerSecond)
1843                 && Objects.equals(mSuccessfulRxPacketsPerSecond,
1844                 thatWifiInfo.mSuccessfulRxPacketsPerSecond)
1845                 && Objects.equals(score, thatWifiInfo.score)
1846                 && Objects.equals(mIsUsable, thatWifiInfo.mIsUsable)
1847                 && Objects.equals(mWifiStandard, thatWifiInfo.mWifiStandard)
1848                 && Objects.equals(mMaxSupportedTxLinkSpeed, thatWifiInfo.mMaxSupportedTxLinkSpeed)
1849                 && Objects.equals(mMaxSupportedRxLinkSpeed, thatWifiInfo.mMaxSupportedRxLinkSpeed)
1850                 && Objects.equals(mPasspointUniqueId, thatWifiInfo.mPasspointUniqueId)
1851                 && Objects.equals(mInformationElements, thatWifiInfo.mInformationElements)
1852                 && mIsPrimary == thatWifiInfo.mIsPrimary
1853                 && mSecurityType == thatWifiInfo.mSecurityType
1854                 && mRestricted == thatWifiInfo.mRestricted
1855                 && Objects.equals(mNetworkKey, thatWifiInfo.mNetworkKey)
1856                 && mApTidToLinkMappingNegotiationSupported
1857                 == thatWifiInfo.mApTidToLinkMappingNegotiationSupported;
1858     }
1859 
1860     @Override
hashCode()1861     public int hashCode() {
1862         // Potential API behavior change, so don't change behavior on older devices.
1863         if (!SdkLevel.isAtLeastS()) return System.identityHashCode(this);
1864 
1865         return Objects.hash(mWifiSsid,
1866                 mBSSID,
1867                 mApMldMacAddress,
1868                 mApMloLinkId,
1869                 mAffiliatedMloLinks,
1870                 mNetworkId,
1871                 mRssi,
1872                 mSupplicantState,
1873                 mLinkSpeed,
1874                 mTxLinkSpeed,
1875                 mRxLinkSpeed,
1876                 mFrequency,
1877                 mIpAddress,
1878                 mMacAddress,
1879                 mMeteredHint,
1880                 mEphemeral,
1881                 mTrusted,
1882                 mOemPaid,
1883                 mOemPrivate,
1884                 mCarrierMerged,
1885                 mRequestingPackageName,
1886                 mOsuAp,
1887                 mFqdn,
1888                 mProviderFriendlyName,
1889                 mSubscriptionId,
1890                 txBad,
1891                 txRetries,
1892                 txSuccess,
1893                 rxSuccess,
1894                 mLostTxPacketsPerSecond,
1895                 mTxRetriedTxPacketsPerSecond,
1896                 mSuccessfulTxPacketsPerSecond,
1897                 mSuccessfulRxPacketsPerSecond,
1898                 score,
1899                 mIsUsable,
1900                 mWifiStandard,
1901                 mMaxSupportedTxLinkSpeed,
1902                 mMaxSupportedRxLinkSpeed,
1903                 mPasspointUniqueId,
1904                 mInformationElements,
1905                 mIsPrimary,
1906                 mSecurityType,
1907                 mRestricted,
1908                 mNetworkKey,
1909                 mApTidToLinkMappingNegotiationSupported);
1910     }
1911 
1912     /**
1913      * Create a copy of a {@link WifiInfo} with some fields redacted based on the permissions
1914      * held by the receiving app.
1915      *
1916      * @param redactions bitmask of redactions that needs to be performed on this instance.
1917      * @return Copy of this instance with the necessary redactions.
1918      */
1919     @Override
1920     @NonNull
makeCopy(long redactions)1921     public WifiInfo makeCopy(long redactions) {
1922         return new WifiInfo(this, redactions);
1923     }
1924 
1925     /**
1926      * Returns a bitmask of all the applicable redactions (based on the permissions held by the
1927      * receiving app) to be performed on this TransportInfo.
1928      *
1929      * @return bitmask of redactions applicable on this instance.
1930      */
1931     @Override
getApplicableRedactions()1932     public long getApplicableRedactions() {
1933         return NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION
1934                 | NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS
1935                 | NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
1936     }
1937 
1938     /**
1939      * Set the security type of the current connection
1940      * @hide
1941      */
setCurrentSecurityType(@ifiConfiguration.SecurityType int securityType)1942     public void setCurrentSecurityType(@WifiConfiguration.SecurityType int securityType) {
1943         mSecurityType = convertWifiConfigurationSecurityType(securityType);
1944     }
1945 
1946     /**
1947      * Clear the last set security type
1948      * @hide
1949      */
clearCurrentSecurityType()1950     public void clearCurrentSecurityType() {
1951         mSecurityType = SECURITY_TYPE_UNKNOWN;
1952     }
1953 
1954     /**
1955      * Returns the security type of the current 802.11 network connection.
1956      *
1957      * @return the security type, or {@link #SECURITY_TYPE_UNKNOWN} if not currently connected.
1958      */
getCurrentSecurityType()1959     public @WifiAnnotations.SecurityType int getCurrentSecurityType() {
1960         return mSecurityType;
1961     }
1962 
1963     /**
1964      * Converts the WifiConfiguration.SecurityType to a WifiInfo.SecurityType
1965      * @param wifiConfigSecurity WifiConfiguration.SecurityType to convert
1966      * @return security type as a WifiInfo.SecurityType
1967      * @hide
1968      */
convertWifiConfigurationSecurityType( @ifiConfiguration.SecurityType int wifiConfigSecurity)1969     public static @WifiAnnotations.SecurityType int convertWifiConfigurationSecurityType(
1970             @WifiConfiguration.SecurityType int wifiConfigSecurity) {
1971         switch (wifiConfigSecurity) {
1972             case WifiConfiguration.SECURITY_TYPE_OPEN:
1973                 return SECURITY_TYPE_OPEN;
1974             case WifiConfiguration.SECURITY_TYPE_WEP:
1975                 return SECURITY_TYPE_WEP;
1976             case WifiConfiguration.SECURITY_TYPE_PSK:
1977                 return SECURITY_TYPE_PSK;
1978             case WifiConfiguration.SECURITY_TYPE_EAP:
1979                 return SECURITY_TYPE_EAP;
1980             case WifiConfiguration.SECURITY_TYPE_SAE:
1981                 return SECURITY_TYPE_SAE;
1982             case WifiConfiguration.SECURITY_TYPE_OWE:
1983                 return SECURITY_TYPE_OWE;
1984             case WifiConfiguration.SECURITY_TYPE_WAPI_PSK:
1985                 return SECURITY_TYPE_WAPI_PSK;
1986             case WifiConfiguration.SECURITY_TYPE_WAPI_CERT:
1987                 return SECURITY_TYPE_WAPI_CERT;
1988             case WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE:
1989                 return SECURITY_TYPE_EAP_WPA3_ENTERPRISE;
1990             case WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT:
1991                 return SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT;
1992             case WifiConfiguration.SECURITY_TYPE_PASSPOINT_R1_R2:
1993                 return SECURITY_TYPE_PASSPOINT_R1_R2;
1994             case WifiConfiguration.SECURITY_TYPE_PASSPOINT_R3:
1995                 return SECURITY_TYPE_PASSPOINT_R3;
1996             case WifiConfiguration.SECURITY_TYPE_DPP:
1997                 return SECURITY_TYPE_DPP;
1998             default:
1999                 return SECURITY_TYPE_UNKNOWN;
2000         }
2001     }
2002 
2003     /**
2004      * Utility method to convert WifiInfo.SecurityType to DevicePolicyManager.WifiSecurity
2005      * @param securityType WifiInfo.SecurityType to convert
2006      * @return DevicePolicyManager.WifiSecurity security level, or
2007      * {@link #DPM_SECURITY_TYPE_UNKNOWN} for unknown security types
2008      * @hide
2009      */
convertSecurityTypeToDpmWifiSecurity( @ifiAnnotations.SecurityType int securityType)2010     public static int convertSecurityTypeToDpmWifiSecurity(
2011             @WifiAnnotations.SecurityType int securityType) {
2012         switch (securityType) {
2013             case SECURITY_TYPE_OPEN:
2014             case SECURITY_TYPE_OWE:
2015                 return DevicePolicyManager.WIFI_SECURITY_OPEN;
2016             case SECURITY_TYPE_WEP:
2017             case SECURITY_TYPE_PSK:
2018             case SECURITY_TYPE_SAE:
2019             case SECURITY_TYPE_WAPI_PSK:
2020                 return DevicePolicyManager.WIFI_SECURITY_PERSONAL;
2021             case SECURITY_TYPE_EAP:
2022             case SECURITY_TYPE_EAP_WPA3_ENTERPRISE:
2023             case SECURITY_TYPE_PASSPOINT_R1_R2:
2024             case SECURITY_TYPE_PASSPOINT_R3:
2025             case SECURITY_TYPE_WAPI_CERT:
2026                 return DevicePolicyManager.WIFI_SECURITY_ENTERPRISE_EAP;
2027             case SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT:
2028                 return DevicePolicyManager.WIFI_SECURITY_ENTERPRISE_192;
2029             default:
2030                 return DPM_SECURITY_TYPE_UNKNOWN;
2031         }
2032     }
2033 
2034     /**
2035      * Set the network key for the current Wi-Fi network.
2036      *
2037      * Now we are using this identity to be a key when storing Wi-Fi data usage data.
2038      * See: {@link WifiConfiguration#getNetworkKeyFromSecurityType(int)}.
2039      *
2040      * @param currentNetworkKey the network key of the current Wi-Fi network.
2041      * @hide
2042      */
setNetworkKey(@onNull String currentNetworkKey)2043     public void setNetworkKey(@NonNull String currentNetworkKey) {
2044         mNetworkKey = currentNetworkKey;
2045     }
2046 
2047     /**
2048      * Returns the network key of the current Wi-Fi network.
2049      *
2050      * The network key may be {@code null}, if there is no network currently connected
2051      * or if the caller has insufficient permissions to access the network key.
2052      *
2053      * @hide
2054      */
2055     @SystemApi
2056     @Nullable
getNetworkKey()2057     public String getNetworkKey() {
2058         return mNetworkKey;
2059     }
2060 
2061     /**
2062      * TID-to-Link mapping negotiation is an optional feature. This API returns whether the feature
2063      * is supported by the AP.
2064      *
2065      * @return Return true if TID-to-Link mapping negotiation is supported by the AP, otherwise
2066      * false.
2067      *
2068      * @hide
2069      */
2070     @SystemApi
isApTidToLinkMappingNegotiationSupported()2071     public boolean isApTidToLinkMappingNegotiationSupported() {
2072         return mApTidToLinkMappingNegotiationSupported;
2073     }
2074 
2075     /** @hide */
enableApTidToLinkMappingNegotiationSupport(boolean enable)2076     public void enableApTidToLinkMappingNegotiationSupport(boolean enable) {
2077         mApTidToLinkMappingNegotiationSupported = enable;
2078     }
2079 }
2080