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