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