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