/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.net.wifi;

import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID;

import android.Manifest;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo.DetailedState;
import android.net.TransportInfo;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.SubscriptionManager;
import android.text.TextUtils;

import androidx.annotation.RequiresApi;

import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.Inet4AddressUtils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Locale;
import java.util.Objects;

/**
 * Describes the state of any Wi-Fi connection that is active or
 * is in the process of being set up.
 *
 * In the connected state, access to location sensitive fields requires
 * the same permissions as {@link WifiManager#getScanResults}. If such access is not allowed,
 * {@link #getSSID} will return {@link WifiManager#UNKNOWN_SSID} and
 * {@link #getBSSID} will return {@code "02:00:00:00:00:00"}.
 * {@link #getNetworkId()} will return {@code -1}.
 * {@link #getPasspointFqdn()} will return null.
 * {@link #getPasspointProviderFriendlyName()} will return null.
 * {@link #getInformationElements()} will return null.
 * {@link #getMacAddress()} will return {@code "02:00:00:00:00:00"}.
 */
public class WifiInfo implements TransportInfo, Parcelable {
    private static final String TAG = "WifiInfo";
    /**
     * This is the map described in the Javadoc comment above. The positions
     * of the elements of the array must correspond to the ordinal values
     * of <code>DetailedState</code>.
     */
    private static final EnumMap<SupplicantState, DetailedState> stateMap =
            new EnumMap<SupplicantState, DetailedState>(SupplicantState.class);

    /**
     * Default MAC address reported to a client that does not have the
     * android.permission.LOCAL_MAC_ADDRESS permission.
     *
     * @hide
     */
    @SystemApi
    public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00";

    static {
        stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED);
        stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED);
        stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE);
        stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING);
        stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING);
        stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING);
        stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING);
        stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING);
        stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING);
        stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR);
        stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED);
        stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE);
        stateMap.put(SupplicantState.INVALID, DetailedState.FAILED);
    }

    private SupplicantState mSupplicantState;
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private String mBSSID;
    @UnsupportedAppUsage
    private WifiSsid mWifiSsid;
    private int mNetworkId;
    private int mSecurityType;

    /**
     * Used to indicate that the RSSI is invalid, for example if no RSSI measurements are available
     * yet.
     * @hide
     */
    @SystemApi
    public static final int INVALID_RSSI = -127;

    /** @hide **/
    public static final int MIN_RSSI = -126;

    /** @hide **/
    public static final int MAX_RSSI = 200;

    /** Unknown security type. */
    public static final int SECURITY_TYPE_UNKNOWN = -1;
    /** Security type for an open network. */
    public static final int SECURITY_TYPE_OPEN = 0;
    /** Security type for a WEP network. */
    public static final int SECURITY_TYPE_WEP = 1;
    /** Security type for a PSK network. */
    public static final int SECURITY_TYPE_PSK = 2;
    /** Security type for an EAP network. */
    public static final int SECURITY_TYPE_EAP = 3;
    /** Security type for an SAE network. */
    public static final int SECURITY_TYPE_SAE = 4;
    /** Security type for a WPA3-Enterprise in 192-bit security network. */
    public static final int SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT = 5;
    /** Security type for an OWE network. */
    public static final int SECURITY_TYPE_OWE = 6;
    /** Security type for a WAPI PSK network. */
    public static final int SECURITY_TYPE_WAPI_PSK = 7;
    /** Security type for a WAPI Certificate network. */
    public static final int SECURITY_TYPE_WAPI_CERT = 8;
    /** Security type for a WPA3-Enterprise network. */
    public static final int SECURITY_TYPE_EAP_WPA3_ENTERPRISE = 9;
    /** Security type for an OSEN network. */
    public static final int SECURITY_TYPE_OSEN = 10;
    /** Security type for a Passpoint R1/R2 network, where TKIP and WEP are not allowed. */
    public static final int SECURITY_TYPE_PASSPOINT_R1_R2 = 11;
    /**
     * Security type for a Passpoint R3 network, where TKIP and WEP are not allowed,
     * and PMF must be set to Required.
     */
    public static final int SECURITY_TYPE_PASSPOINT_R3 = 12;

    /**
     * Security type of current connection.
     * @hide
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = { "SECURITY_TYPE_" }, value = {
            SECURITY_TYPE_UNKNOWN,
            SECURITY_TYPE_OPEN,
            SECURITY_TYPE_WEP,
            SECURITY_TYPE_PSK,
            SECURITY_TYPE_EAP,
            SECURITY_TYPE_SAE,
            SECURITY_TYPE_OWE,
            SECURITY_TYPE_WAPI_PSK,
            SECURITY_TYPE_WAPI_CERT,
            SECURITY_TYPE_EAP_WPA3_ENTERPRISE,
            SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT,
            SECURITY_TYPE_PASSPOINT_R1_R2,
            SECURITY_TYPE_PASSPOINT_R3,
    })
    public @interface SecurityType {}

    /** @see #isPrimary() - No permission to access the field.  */
    private static final int IS_PRIMARY_NO_PERMISSION = -1;
    /** @see #isPrimary() - false */
    private static final int IS_PRIMARY_FALSE = 0;
    /** @see #isPrimary() - true */
    private static final int IS_PRIMARY_TRUE = 1;
    /** Tri state to store {@link #isPrimary()} field. */
    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = { "IS_PRIMARY_" }, value = {
            IS_PRIMARY_NO_PERMISSION, IS_PRIMARY_FALSE, IS_PRIMARY_TRUE
    })
    public @interface IsPrimaryValues {}

    /**
     * Received Signal Strength Indicator
     */
    private int mRssi;

    /**
     * Wi-Fi standard for the connection
     */
    private @WifiAnnotations.WifiStandard int mWifiStandard;

    /**
     * The unit in which links speeds are expressed.
     */
    public static final String LINK_SPEED_UNITS = "Mbps";
    private int mLinkSpeed;

    /**
     * Constant for unknown link speed.
     */
    public static final int LINK_SPEED_UNKNOWN = -1;

    /**
     * Tx(transmit) Link speed in Mbps
     */
    private int mTxLinkSpeed;

    /**
     * Max supported Tx(transmit) link speed in Mbps
     */
    private int mMaxSupportedTxLinkSpeed;

    /**
     * Rx(receive) Link speed in Mbps
     */
    private int mRxLinkSpeed;

    /**
     * Max supported Rx(receive) link speed in Mbps
     */
    private int mMaxSupportedRxLinkSpeed;

    /**
     * Frequency in MHz
     */
    public static final String FREQUENCY_UNITS = "MHz";
    private int mFrequency;

    @UnsupportedAppUsage
    private InetAddress mIpAddress;
    @UnsupportedAppUsage
    private String mMacAddress = DEFAULT_MAC_ADDRESS;

    /**
     * Whether the network is ephemeral or not.
     */
    private boolean mEphemeral;

    /**
     * Whether the network is trusted or not.
     */
    private boolean mTrusted;

    /**
     * Whether the network is oem paid or not.
     */
    private boolean mOemPaid;

    /**
     * Whether the network is oem private or not.
     */
    private boolean mOemPrivate;

    /**
     * Whether the network is a carrier merged network.
     */
    private boolean mCarrierMerged;

    /**
     * OSU (Online Sign Up) AP for Passpoint R2.
     */
    private boolean mOsuAp;

    /**
     * Fully qualified domain name of a Passpoint configuration
     */
    private String mFqdn;

    /**
     * Name of Passpoint credential provider
     */
    private String mProviderFriendlyName;

    /**
     * If connected to a network suggestion or specifier, store the package name of the app,
     * else null.
     */
    private String mRequestingPackageName;

    /**
     * Identify which Telephony subscription provides this network.
     */
    private int mSubscriptionId;

    /**
     * Running total count of lost (not ACKed) transmitted unicast data packets.
     * @hide
     */
    public long txBad;
    /**
     * Running total count of transmitted unicast data retry packets.
     * @hide
     */
    public long txRetries;
    /**
     * Running total count of successfully transmitted (ACKed) unicast data packets.
     * @hide
     */
    public long txSuccess;
    /**
     * Running total count of received unicast data packets.
     * @hide
     */
    public long rxSuccess;

    private double mLostTxPacketsPerSecond;

    /**
     * Average rate of lost transmitted packets, in units of packets per second.
     * @hide
     */
    @SystemApi
    public double getLostTxPacketsPerSecond() {
        return mLostTxPacketsPerSecond;
    }

    /** @hide */
    public void setLostTxPacketsPerSecond(double lostTxPacketsPerSecond) {
        mLostTxPacketsPerSecond = lostTxPacketsPerSecond;
    }

    private double mTxRetriedTxPacketsPerSecond;

    /**
     * Average rate of transmitted retry packets, in units of packets per second.
     * @hide
     */
    @SystemApi
    public double getRetriedTxPacketsPerSecond() {
        return mTxRetriedTxPacketsPerSecond;
    }

    /** @hide */
    public void setRetriedTxPacketsRate(double txRetriedTxPacketsPerSecond) {
        mTxRetriedTxPacketsPerSecond = txRetriedTxPacketsPerSecond;
    }

    private double mSuccessfulTxPacketsPerSecond;

    /**
     * Average rate of successfully transmitted unicast packets, in units of packets per second.
     * @hide
     */
    @SystemApi
    public double getSuccessfulTxPacketsPerSecond() {
        return mSuccessfulTxPacketsPerSecond;
    }

    /** @hide */
    public void setSuccessfulTxPacketsPerSecond(double successfulTxPacketsPerSecond) {
        mSuccessfulTxPacketsPerSecond = successfulTxPacketsPerSecond;
    }

    private double mSuccessfulRxPacketsPerSecond;

    /**
     * Average rate of received unicast data packets, in units of packets per second.
     * @hide
     */
    @SystemApi
    public double getSuccessfulRxPacketsPerSecond() {
        return mSuccessfulRxPacketsPerSecond;
    }

    /** @hide */
    public void setSuccessfulRxPacketsPerSecond(double successfulRxPacketsPerSecond) {
        mSuccessfulRxPacketsPerSecond = successfulRxPacketsPerSecond;
    }

    /** @hide */
    @UnsupportedAppUsage
    public int score;

    /**
     * The current Wifi score.
     * NOTE: this value should only be used for debugging purposes. Do not rely on this value for
     * any computations. The meaning of this value can and will change at any time without warning.
     * @hide
     */
    @SystemApi
    public int getScore() {
        return score;
    }

    /** @hide */
    public void setScore(int score) {
        this.score = score;
    }

    /**
     * Flag indicating that AP has hinted that upstream connection is metered,
     * and sensitive to heavy data transfers.
     */
    private boolean mMeteredHint;

    /**
     * Passpoint unique key
     */
    private String mPasspointUniqueId;

    /**
     * information elements found in the beacon of the connected bssid.
     */
    @Nullable
    private List<ScanResult.InformationElement> mInformationElements;

    /**
     * @see #isPrimary()
     * The field is stored as an int since is a tristate internally -  true, false, no permission.
     */
    private @IsPrimaryValues int mIsPrimary;

    /** @hide */
    @UnsupportedAppUsage
    public WifiInfo() {
        mWifiSsid = null;
        mBSSID = null;
        mNetworkId = -1;
        mSupplicantState = SupplicantState.UNINITIALIZED;
        mRssi = INVALID_RSSI;
        mLinkSpeed = LINK_SPEED_UNKNOWN;
        mFrequency = -1;
        mSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
        mSecurityType = -1;
        mIsPrimary = IS_PRIMARY_FALSE;
    }

    /** @hide */
    public void reset() {
        setInetAddress(null);
        setBSSID(null);
        setSSID(null);
        setNetworkId(-1);
        setRssi(INVALID_RSSI);
        setLinkSpeed(LINK_SPEED_UNKNOWN);
        setTxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
        setRxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
        setMaxSupportedTxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
        setMaxSupportedRxLinkSpeedMbps(LINK_SPEED_UNKNOWN);
        setFrequency(-1);
        setMeteredHint(false);
        setEphemeral(false);
        setTrusted(false);
        setOemPaid(false);
        setOemPrivate(false);
        setCarrierMerged(false);
        setOsuAp(false);
        setRequestingPackageName(null);
        setFQDN(null);
        setProviderFriendlyName(null);
        setPasspointUniqueId(null);
        setSubscriptionId(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
        setInformationElements(null);
        setIsPrimary(false);
        txBad = 0;
        txSuccess = 0;
        rxSuccess = 0;
        txRetries = 0;
        mLostTxPacketsPerSecond = 0;
        mSuccessfulTxPacketsPerSecond = 0;
        mSuccessfulRxPacketsPerSecond = 0;
        mTxRetriedTxPacketsPerSecond = 0;
        score = 0;
        mSecurityType = -1;
    }

    /**
     * Copy constructor
     * @hide
     */
    public WifiInfo(WifiInfo source) {
        this(source, NetworkCapabilities.REDACT_NONE);
    }

    /**
     * Copy constructor
     * @hide
     */
    private WifiInfo(WifiInfo source, long redactions) {
        if (source != null) {
            mSupplicantState = source.mSupplicantState;
            mBSSID = shouldRedactLocationSensitiveFields(redactions)
                    ? DEFAULT_MAC_ADDRESS : source.mBSSID;
            mWifiSsid = shouldRedactLocationSensitiveFields(redactions)
                    ? WifiSsid.createFromHex(null) : source.mWifiSsid;
            mNetworkId = shouldRedactLocationSensitiveFields(redactions)
                    ? INVALID_NETWORK_ID : source.mNetworkId;
            mRssi = source.mRssi;
            mLinkSpeed = source.mLinkSpeed;
            mTxLinkSpeed = source.mTxLinkSpeed;
            mRxLinkSpeed = source.mRxLinkSpeed;
            mFrequency = source.mFrequency;
            mIpAddress = source.mIpAddress;
            mMacAddress = (shouldRedactLocalMacAddressFields(redactions)
                    || shouldRedactLocationSensitiveFields(redactions))
                            ? DEFAULT_MAC_ADDRESS : source.mMacAddress;
            mMeteredHint = source.mMeteredHint;
            mEphemeral = source.mEphemeral;
            mTrusted = source.mTrusted;
            mOemPaid = source.mOemPaid;
            mOemPrivate = source.mOemPrivate;
            mCarrierMerged = source.mCarrierMerged;
            mRequestingPackageName =
                    source.mRequestingPackageName;
            mOsuAp = source.mOsuAp;
            mFqdn = shouldRedactLocationSensitiveFields(redactions)
                    ? null : source.mFqdn;
            mProviderFriendlyName = shouldRedactLocationSensitiveFields(redactions)
                    ? null : source.mProviderFriendlyName;
            mSubscriptionId = source.mSubscriptionId;
            txBad = source.txBad;
            txRetries = source.txRetries;
            txSuccess = source.txSuccess;
            rxSuccess = source.rxSuccess;
            mLostTxPacketsPerSecond = source.mLostTxPacketsPerSecond;
            mTxRetriedTxPacketsPerSecond = source.mTxRetriedTxPacketsPerSecond;
            mSuccessfulTxPacketsPerSecond = source.mSuccessfulTxPacketsPerSecond;
            mSuccessfulRxPacketsPerSecond = source.mSuccessfulRxPacketsPerSecond;
            score = source.score;
            mWifiStandard = source.mWifiStandard;
            mMaxSupportedTxLinkSpeed = source.mMaxSupportedTxLinkSpeed;
            mMaxSupportedRxLinkSpeed = source.mMaxSupportedRxLinkSpeed;
            mPasspointUniqueId = shouldRedactLocationSensitiveFields(redactions)
                    ? null : source.mPasspointUniqueId;
            if (source.mInformationElements != null
                    && !shouldRedactLocationSensitiveFields(redactions)) {
                mInformationElements = new ArrayList<>(source.mInformationElements);
            }
            mIsPrimary = shouldRedactNetworkSettingsFields(redactions)
                    ? IS_PRIMARY_NO_PERMISSION : source.mIsPrimary;
            mSecurityType = source.mSecurityType;
        }
    }

    /** Builder for WifiInfo */
    public static final class Builder {
        private final WifiInfo mWifiInfo = new WifiInfo();

        /**
         * Set the SSID, in the form of a raw byte array.
         * @see WifiInfo#getSSID()
         */
        @NonNull
        public Builder setSsid(@NonNull byte[] ssid) {
            mWifiInfo.setSSID(WifiSsid.createFromByteArray(ssid));
            return this;
        }

        /**
         * Set the BSSID.
         * @see WifiInfo#getBSSID()
         */
        @NonNull
        public Builder setBssid(@NonNull String bssid) {
            mWifiInfo.setBSSID(bssid);
            return this;
        }

        /**
         * Set the RSSI, in dBm.
         * @see WifiInfo#getRssi()
         */
        @NonNull
        public Builder setRssi(int rssi) {
            mWifiInfo.setRssi(rssi);
            return this;
        }

        /**
         * Set the network ID.
         * @see WifiInfo#getNetworkId()
         */
        @NonNull
        public Builder setNetworkId(int networkId) {
            mWifiInfo.setNetworkId(networkId);
            return this;
        }

        /**
         * Set the current security type
         * @see WifiInfo#getCurrentSecurityType()
         */
        @NonNull
        public Builder setCurrentSecurityType(@WifiConfiguration.SecurityType int securityType) {
            mWifiInfo.setCurrentSecurityType(securityType);
            return this;
        }

        /**
         * Build a WifiInfo object.
         */
        @NonNull
        public WifiInfo build() {
            return new WifiInfo(mWifiInfo);
        }
    }

    /** @hide */
    public void setSSID(WifiSsid wifiSsid) {
        mWifiSsid = wifiSsid;
    }

    /**
     * Returns the service set identifier (SSID) of the current 802.11 network.
     * <p>
     * If the SSID can be decoded as UTF-8, it will be returned surrounded by double
     * quotation marks. Otherwise, it is returned as a string of hex digits.
     * The SSID may be {@link WifiManager#UNKNOWN_SSID}, if there is no network currently connected
     * or if the caller has insufficient permissions to access the SSID.
     * </p>
     * <p>
     * Prior to {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method
     * always returned the SSID with no quotes around it.
     * </p>
     *
     * @return the SSID.
     */
    public String getSSID() {
        if (mWifiSsid != null) {
            String unicode = mWifiSsid.toString();
            if (!TextUtils.isEmpty(unicode)) {
                return "\"" + unicode + "\"";
            } else {
                String hex = mWifiSsid.getHexString();
                return (hex != null) ? hex : WifiManager.UNKNOWN_SSID;
            }
        }
        return WifiManager.UNKNOWN_SSID;
    }

    /** @hide */
    @UnsupportedAppUsage
    public WifiSsid getWifiSsid() {
        return mWifiSsid;
    }

    /** @hide */
    @UnsupportedAppUsage
    public void setBSSID(String BSSID) {
        mBSSID = BSSID;
    }

    /**
     * Return the basic service set identifier (BSSID) of the current access point.
     * <p>
     * The BSSID may be
     * <lt>{@code null}, if there is no network currently connected.</lt>
     * <lt>{@code "02:00:00:00:00:00"}, if the caller has insufficient permissions to access the
     * BSSID.<lt>
     * </p>
     *
     * @return the BSSID, in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX}
     */
    public String getBSSID() {
        return mBSSID;
    }

    /**
     * Returns the received signal strength indicator of the current 802.11
     * network, in dBm.
     *
     * <p>Use {@link android.net.wifi.WifiManager#calculateSignalLevel} to convert this number into
     * an absolute signal level which can be displayed to a user.
     *
     * @return the RSSI.
     */
    public int getRssi() {
        return mRssi;
    }

    /** @hide */
    @UnsupportedAppUsage
    public void setRssi(int rssi) {
        if (rssi < INVALID_RSSI)
            rssi = INVALID_RSSI;
        if (rssi > MAX_RSSI)
            rssi = MAX_RSSI;
        mRssi = rssi;
    }

    /**
     * Sets the Wi-Fi standard
     * @hide
     */
    public void setWifiStandard(@WifiAnnotations.WifiStandard int wifiStandard) {
        mWifiStandard = wifiStandard;
    }

    /**
     * Get connection Wi-Fi standard
     * @return the connection Wi-Fi standard
     */
    public @WifiAnnotations.WifiStandard int getWifiStandard() {
        return mWifiStandard;
    }

    /**
     * Returns the current link speed in {@link #LINK_SPEED_UNITS}.
     * @return the link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown.
     * @see #LINK_SPEED_UNITS
     * @see #LINK_SPEED_UNKNOWN
     */
    public int getLinkSpeed() {
        return mLinkSpeed;
    }

    /** @hide */
    @UnsupportedAppUsage
    public void setLinkSpeed(int linkSpeed) {
        mLinkSpeed = linkSpeed;
    }

    /**
     * Returns the current transmit link speed in Mbps.
     * @return the Tx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown.
     * @see #LINK_SPEED_UNKNOWN
     */
    @IntRange(from = -1)
    public int getTxLinkSpeedMbps() {
        return mTxLinkSpeed;
    }

    /**
     * Returns the maximum supported transmit link speed in Mbps
     * @return the max supported tx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is
     * unknown. @see #LINK_SPEED_UNKNOWN
     */
    public int getMaxSupportedTxLinkSpeedMbps() {
        return mMaxSupportedTxLinkSpeed;
    }

    /**
     * Update the last transmitted packet bit rate in Mbps.
     * @hide
     */
    public void setTxLinkSpeedMbps(int txLinkSpeed) {
        mTxLinkSpeed = txLinkSpeed;
    }

    /**
     * Set the maximum supported transmit link speed in Mbps
     * @hide
     */
    public void setMaxSupportedTxLinkSpeedMbps(int maxSupportedTxLinkSpeed) {
        mMaxSupportedTxLinkSpeed = maxSupportedTxLinkSpeed;
    }

    /**
     * Returns the current receive link speed in Mbps.
     * @return the Rx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown.
     * @see #LINK_SPEED_UNKNOWN
     */
    @IntRange(from = -1)
    public int getRxLinkSpeedMbps() {
        return mRxLinkSpeed;
    }

    /**
     * Returns the maximum supported receive link speed in Mbps
     * @return the max supported Rx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is
     * unknown. @see #LINK_SPEED_UNKNOWN
     */
    public int getMaxSupportedRxLinkSpeedMbps() {
        return mMaxSupportedRxLinkSpeed;
    }

    /**
     * Update the last received packet bit rate in Mbps.
     * @hide
     */
    public void setRxLinkSpeedMbps(int rxLinkSpeed) {
        mRxLinkSpeed = rxLinkSpeed;
    }

    /**
     * Set the maximum supported receive link speed in Mbps
     * @hide
     */
    public void setMaxSupportedRxLinkSpeedMbps(int maxSupportedRxLinkSpeed) {
        mMaxSupportedRxLinkSpeed = maxSupportedRxLinkSpeed;
    }

    /**
     * Returns the current frequency in {@link #FREQUENCY_UNITS}.
     * @return the frequency.
     * @see #FREQUENCY_UNITS
     */
    public int getFrequency() {
        return mFrequency;
    }

    /** @hide */
    public void setFrequency(int frequency) {
        this.mFrequency = frequency;
    }

    /**
     * @hide
     */
    public boolean is24GHz() {
        return ScanResult.is24GHz(mFrequency);
    }

    /**
     * @hide
     */
    @UnsupportedAppUsage
    public boolean is5GHz() {
        return ScanResult.is5GHz(mFrequency);
    }

    /**
     * @hide
     */
    public boolean is6GHz() {
        return ScanResult.is6GHz(mFrequency);
    }

    /**
     * Record the MAC address of the WLAN interface
     * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form
     * @hide
     */
    @UnsupportedAppUsage
    public void setMacAddress(String macAddress) {
        this.mMacAddress = macAddress;
    }

    /**
     * Returns the MAC address used for this connection.
     * @return MAC address of the connection or {@code "02:00:00:00:00:00"} if the caller has
     * insufficient permission.
     *
     * Requires {@code android.Manifest.permission#LOCAL_MAC_ADDRESS} and
     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION}.
     */
    public String getMacAddress() {
        return mMacAddress;
    }

    /**
     * @return true if {@link #getMacAddress()} has a real MAC address.
     *
     * @hide
     */
    public boolean hasRealMacAddress() {
        return mMacAddress != null && !DEFAULT_MAC_ADDRESS.equals(mMacAddress);
    }

    /**
     * Indicates if we've dynamically detected this active network connection as
     * being metered.
     *
     * @see WifiConfiguration#isMetered(WifiConfiguration, WifiInfo)
     * @hide
     */
    public void setMeteredHint(boolean meteredHint) {
        mMeteredHint = meteredHint;
    }

    /** {@hide} */
    @UnsupportedAppUsage
    public boolean getMeteredHint() {
        return mMeteredHint;
    }

    /** {@hide} */
    public void setEphemeral(boolean ephemeral) {
        mEphemeral = ephemeral;
    }

    /**
     * Returns true if the current Wifi network is ephemeral, false otherwise.
     * An ephemeral network is a network that is temporary and not persisted in the system.
     * Ephemeral networks cannot be forgotten, only disabled with
     * {@link WifiManager#disableEphemeralNetwork(String)}.
     *
     * @hide
     */
    @SystemApi
    public boolean isEphemeral() {
        return mEphemeral;
    }

    /** {@hide} */
    public void setTrusted(boolean trusted) {
        mTrusted = trusted;
    }

    /**
     * Returns true if the current Wifi network is a trusted network, false otherwise.
     * @see WifiNetworkSuggestion.Builder#setUntrusted(boolean).
     * {@hide}
     */
    @SystemApi
    public boolean isTrusted() {
        return mTrusted;
    }

    /** {@hide} */
    public void setOemPaid(boolean oemPaid) {
        mOemPaid = oemPaid;
    }

    /**
     * Returns true if the current Wifi network is an oem paid network, false otherwise.
     * @see WifiNetworkSuggestion.Builder#setOemPaid(boolean).
     * {@hide}
     */
    @RequiresApi(Build.VERSION_CODES.S)
    @SystemApi
    public boolean isOemPaid() {
        if (!SdkLevel.isAtLeastS()) {
            throw new UnsupportedOperationException();
        }
        return mOemPaid;
    }

    /** {@hide} */
    public void setOemPrivate(boolean oemPrivate) {
        mOemPrivate = oemPrivate;
    }

    /**
     * Returns true if the current Wifi network is an oem private network, false otherwise.
     * @see WifiNetworkSuggestion.Builder#setOemPrivate(boolean).
     * {@hide}
     */
    @RequiresApi(Build.VERSION_CODES.S)
    @SystemApi
    public boolean isOemPrivate() {
        if (!SdkLevel.isAtLeastS()) {
            throw new UnsupportedOperationException();
        }
        return mOemPrivate;
    }

    /**
     * {@hide}
     */
    public void setCarrierMerged(boolean carrierMerged) {
        mCarrierMerged = carrierMerged;
    }

    /**
     * Returns true if the current Wifi network is a carrier merged network, false otherwise.
     * @see WifiNetworkSuggestion.Builder#setCarrierMerged(boolean).
     * {@hide}
     */
    @SystemApi
    @RequiresApi(Build.VERSION_CODES.S)
    public boolean isCarrierMerged() {
        if (!SdkLevel.isAtLeastS()) {
            throw new UnsupportedOperationException();
        }
        return mCarrierMerged;
    }


    /** {@hide} */
    public void setOsuAp(boolean osuAp) {
        mOsuAp = osuAp;
    }

    /** {@hide} */
    @SystemApi
    public boolean isOsuAp() {
        return mOsuAp;
    }

    /** {@hide} */
    @SystemApi
    public boolean isPasspointAp() {
        return mFqdn != null && mProviderFriendlyName != null;
    }

    /** {@hide} */
    public void setFQDN(@Nullable String fqdn) {
        mFqdn = fqdn;
    }

    /**
     * Returns the Fully Qualified Domain Name of the network if it is a Passpoint network.
     * <p>
     * The FQDN may be
     * <lt>{@code null} if no network currently connected, currently connected network is not
     * passpoint network or the caller has insufficient permissions to access the FQDN.</lt>
     * </p>
     */
    public @Nullable String getPasspointFqdn() {
        return mFqdn;
    }

    /** {@hide} */
    public void setProviderFriendlyName(@Nullable String providerFriendlyName) {
        mProviderFriendlyName = providerFriendlyName;
    }

    /**
     * Returns the Provider Friendly Name of the network if it is a Passpoint network.
     * <p>
     * The Provider Friendly Name may be
     * <lt>{@code null} if no network currently connected, currently connected network is not
     * passpoint network or the caller has insufficient permissions to access the Provider Friendly
     * Name. </lt>
     * </p>
     */
    public @Nullable String getPasspointProviderFriendlyName() {
        return mProviderFriendlyName;
    }

    /** {@hide} */
    public void setRequestingPackageName(@Nullable String packageName) {
        mRequestingPackageName = packageName;
    }

    /**
     * If this network was created in response to an app request (e.g. through Network Suggestion
     * or Network Specifier), return the package name of the app that made the request.
     * Null otherwise.
     * @hide
     */
    @SystemApi
    public @Nullable String getRequestingPackageName() {
        return mRequestingPackageName;
    }

    /** {@hide} */
    public void setSubscriptionId(int subId) {
        mSubscriptionId = subId;
    }

    /**
     * If this network is provisioned by a carrier, returns subscription Id corresponding to the
     * associated SIM on the device. If this network is not provisioned by a carrier, returns
     * {@link android.telephony.SubscriptionManager#INVALID_SUBSCRIPTION_ID}
     *
     * @see WifiNetworkSuggestion.Builder#setSubscriptionId(int)
     * @see android.telephony.SubscriptionInfo#getSubscriptionId()
     */
    @RequiresApi(Build.VERSION_CODES.S)
    public int getSubscriptionId() {
        if (!SdkLevel.isAtLeastS()) {
            throw new UnsupportedOperationException();
        }
        return mSubscriptionId;
    }


    /** @hide */
    @UnsupportedAppUsage
    public void setNetworkId(int id) {
        mNetworkId = id;
    }

    /**
     * Each configured network has a unique small integer ID, used to identify
     * the network. This method returns the ID for the currently connected network.
     * <p>
     * The networkId may be {@code -1} if there is no currently connected network or if the caller
     * has insufficient permissions to access the network ID.
     * </p>
     *
     * @return the network ID.
     */
    public int getNetworkId() {
        return mNetworkId;
    }

    /**
     * Return the detailed state of the supplicant's negotiation with an
     * access point, in the form of a {@link SupplicantState SupplicantState} object.
     * @return the current {@link SupplicantState SupplicantState}
     */
    public SupplicantState getSupplicantState() {
        return mSupplicantState;
    }

    /** @hide */
    @UnsupportedAppUsage
    public void setSupplicantState(SupplicantState state) {
        mSupplicantState = state;
    }

    /** @hide */
    public void setInetAddress(InetAddress address) {
        mIpAddress = address;
    }

    /**
     * @deprecated Use the methods on {@link android.net.LinkProperties} which can be obtained
     * either via {@link NetworkCallback#onLinkPropertiesChanged(Network, LinkProperties)} or
     * {@link ConnectivityManager#getLinkProperties(Network)}.
     */
    @Deprecated
    public int getIpAddress() {
        int result = 0;
        if (mIpAddress instanceof Inet4Address) {
            result = Inet4AddressUtils.inet4AddressToIntHTL((Inet4Address) mIpAddress);
        }
        return result;
    }

    /**
     * @return {@code true} if this network does not broadcast its SSID, so an
     * SSID-specific probe request must be used for scans.
     */
    public boolean getHiddenSSID() {
        if (mWifiSsid == null) return false;
        return mWifiSsid.isHidden();
    }

    /**
     * Map a supplicant state into a fine-grained network connectivity state.
     * @param suppState the supplicant state
     * @return the corresponding {@link DetailedState}
     */
    public static DetailedState getDetailedStateOf(SupplicantState suppState) {
        return stateMap.get(suppState);
    }

    /**
     * Set the <code>SupplicantState</code> from the string name
     * of the state.
     * @param stateName the name of the state, as a <code>String</code> returned
     * in an event sent by {@code wpa_supplicant}.
     */
    @UnsupportedAppUsage
    void setSupplicantState(String stateName) {
        mSupplicantState = valueOf(stateName);
    }

    static SupplicantState valueOf(String stateName) {
        if ("4WAY_HANDSHAKE".equalsIgnoreCase(stateName))
            return SupplicantState.FOUR_WAY_HANDSHAKE;
        else {
            try {
                return SupplicantState.valueOf(stateName.toUpperCase(Locale.ROOT));
            } catch (IllegalArgumentException e) {
                return SupplicantState.INVALID;
            }
        }
    }

    /**
     * Remove double quotes (") surrounding a SSID string, if present. Otherwise, return the
     * string unmodified. Return null if the input string was null.
     * @hide
     */
    @Nullable
    @SystemApi
    public static String sanitizeSsid(@Nullable String string) {
        return removeDoubleQuotes(string);
    }

    /** @hide */
    @UnsupportedAppUsage
    @Nullable
    public static String removeDoubleQuotes(@Nullable String string) {
        if (string == null) return null;
        final int length = string.length();
        if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
            return string.substring(1, length - 1);
        }
        return string;
    }

    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        String none = "<none>";

        sb.append("SSID: ").append(getSSID())
                .append(", BSSID: ").append(mBSSID == null ? none : mBSSID)
                .append(", MAC: ").append(mMacAddress == null ? none : mMacAddress)
                .append(", Security type: ").append(mSecurityType)
                .append(", Supplicant state: ")
                .append(mSupplicantState == null ? none : mSupplicantState)
                .append(", Wi-Fi standard: ").append(mWifiStandard)
                .append(", RSSI: ").append(mRssi)
                .append(", Link speed: ").append(mLinkSpeed).append(LINK_SPEED_UNITS)
                .append(", Tx Link speed: ").append(mTxLinkSpeed).append(LINK_SPEED_UNITS)
                .append(", Max Supported Tx Link speed: ")
                .append(mMaxSupportedTxLinkSpeed).append(LINK_SPEED_UNITS)
                .append(", Rx Link speed: ").append(mRxLinkSpeed).append(LINK_SPEED_UNITS)
                .append(", Max Supported Rx Link speed: ")
                .append(mMaxSupportedRxLinkSpeed).append(LINK_SPEED_UNITS)
                .append(", Frequency: ").append(mFrequency).append(FREQUENCY_UNITS)
                .append(", Net ID: ").append(mNetworkId)
                .append(", Metered hint: ").append(mMeteredHint)
                .append(", score: ").append(Integer.toString(score))
                .append(", CarrierMerged: ").append(mCarrierMerged)
                .append(", SubscriptionId: ").append(mSubscriptionId)
                .append(", IsPrimary: ").append(mIsPrimary);
        return sb.toString();
    }

    /** Implement the Parcelable interface {@hide} */
    public int describeContents() {
        return 0;
    }

    private boolean shouldRedactLocationSensitiveFields(long redactions) {
        return (redactions & NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION) != 0;
    }

    private boolean shouldRedactLocalMacAddressFields(long redactions) {
        return (redactions & NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS) != 0;
    }

    private boolean shouldRedactNetworkSettingsFields(long redactions) {
        return (redactions & NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS) != 0;
    }

    /** Implement the Parcelable interface {@hide} */
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mNetworkId);
        dest.writeInt(mRssi);
        dest.writeInt(mLinkSpeed);
        dest.writeInt(mTxLinkSpeed);
        dest.writeInt(mRxLinkSpeed);
        dest.writeInt(mFrequency);
        if (mIpAddress != null) {
            dest.writeByte((byte)1);
            dest.writeByteArray(mIpAddress.getAddress());
        } else {
            dest.writeByte((byte)0);
        }
        if (mWifiSsid != null) {
            dest.writeInt(1);
            mWifiSsid.writeToParcel(dest, flags);
        } else {
            dest.writeInt(0);
        }
        dest.writeString(mBSSID);
        dest.writeString(mMacAddress);
        dest.writeInt(mMeteredHint ? 1 : 0);
        dest.writeInt(mEphemeral ? 1 : 0);
        dest.writeInt(mTrusted ? 1 : 0);
        dest.writeInt(mOemPaid ? 1 : 0);
        dest.writeInt(mOemPrivate ? 1 : 0);
        dest.writeInt(mCarrierMerged ? 1 : 0);
        dest.writeInt(score);
        dest.writeLong(txSuccess);
        dest.writeDouble(mSuccessfulTxPacketsPerSecond);
        dest.writeLong(txRetries);
        dest.writeDouble(mTxRetriedTxPacketsPerSecond);
        dest.writeLong(txBad);
        dest.writeDouble(mLostTxPacketsPerSecond);
        dest.writeLong(rxSuccess);
        dest.writeDouble(mSuccessfulRxPacketsPerSecond);
        mSupplicantState.writeToParcel(dest, flags);
        dest.writeInt(mOsuAp ? 1 : 0);
        dest.writeString(mRequestingPackageName);
        dest.writeString(mFqdn);
        dest.writeString(mProviderFriendlyName);
        dest.writeInt(mWifiStandard);
        dest.writeInt(mMaxSupportedTxLinkSpeed);
        dest.writeInt(mMaxSupportedRxLinkSpeed);
        dest.writeString(mPasspointUniqueId);
        dest.writeInt(mSubscriptionId);
        dest.writeTypedList(mInformationElements);
        if (SdkLevel.isAtLeastS()) {
            dest.writeInt(mIsPrimary);
        }
        dest.writeInt(mSecurityType);
    }

    /** Implement the Parcelable interface {@hide} */
    @UnsupportedAppUsage
    public static final @android.annotation.NonNull Creator<WifiInfo> CREATOR =
        new Creator<WifiInfo>() {
            public WifiInfo createFromParcel(Parcel in) {
                WifiInfo info = new WifiInfo();
                info.setNetworkId(in.readInt());
                info.setRssi(in.readInt());
                info.setLinkSpeed(in.readInt());
                info.setTxLinkSpeedMbps(in.readInt());
                info.setRxLinkSpeedMbps(in.readInt());
                info.setFrequency(in.readInt());
                if (in.readByte() == 1) {
                    try {
                        info.setInetAddress(InetAddress.getByAddress(in.createByteArray()));
                    } catch (UnknownHostException e) {}
                }
                if (in.readInt() == 1) {
                    info.mWifiSsid = WifiSsid.CREATOR.createFromParcel(in);
                }
                info.mBSSID = in.readString();
                info.mMacAddress = in.readString();
                info.mMeteredHint = in.readInt() != 0;
                info.mEphemeral = in.readInt() != 0;
                info.mTrusted = in.readInt() != 0;
                info.mOemPaid = in.readInt() != 0;
                info.mOemPrivate = in.readInt() != 0;
                info.mCarrierMerged = in.readInt() != 0;
                info.score = in.readInt();
                info.txSuccess = in.readLong();
                info.mSuccessfulTxPacketsPerSecond = in.readDouble();
                info.txRetries = in.readLong();
                info.mTxRetriedTxPacketsPerSecond = in.readDouble();
                info.txBad = in.readLong();
                info.mLostTxPacketsPerSecond = in.readDouble();
                info.rxSuccess = in.readLong();
                info.mSuccessfulRxPacketsPerSecond = in.readDouble();
                info.mSupplicantState = SupplicantState.CREATOR.createFromParcel(in);
                info.mOsuAp = in.readInt() != 0;
                info.mRequestingPackageName = in.readString();
                info.mFqdn = in.readString();
                info.mProviderFriendlyName = in.readString();
                info.mWifiStandard = in.readInt();
                info.mMaxSupportedTxLinkSpeed = in.readInt();
                info.mMaxSupportedRxLinkSpeed = in.readInt();
                info.mPasspointUniqueId = in.readString();
                info.mSubscriptionId = in.readInt();
                info.mInformationElements = in.createTypedArrayList(
                        ScanResult.InformationElement.CREATOR);
                if (SdkLevel.isAtLeastS()) {
                    info.mIsPrimary = in.readInt();
                }
                info.mSecurityType = in.readInt();
                return info;
            }

            public WifiInfo[] newArray(int size) {
                return new WifiInfo[size];
            }
        };

    /**
     * Set the Passpoint unique identifier for the current connection
     *
     * @param passpointUniqueId Unique identifier
     * @hide
     */
    public void setPasspointUniqueId(@Nullable String passpointUniqueId) {
        mPasspointUniqueId = passpointUniqueId;
    }

    /**
     * Get the Passpoint unique identifier for the current connection
     *
     * @return Passpoint unique identifier
     * @hide
     */
    public @Nullable String getPasspointUniqueId() {
        return mPasspointUniqueId;
    }

    /**
     * Set the information elements found in the becaon of the connected bssid.
     * @hide
     */
    public void setInformationElements(@Nullable List<ScanResult.InformationElement> infoElements) {
        if (infoElements == null) {
            mInformationElements = null;
            return;
        }
        mInformationElements = new ArrayList<>(infoElements);
    }

    /**
     * Get all information elements found in the beacon of the connected bssid.
     * <p>
     * The information elements will be {@code null} if there is no network currently connected or
     * if the caller has insufficient permissions to access the info elements.
     * </p>
     *
     * @return List of information elements {@link ScanResult.InformationElement} or null.
     */
    @Nullable
    @SuppressWarnings("NullableCollection")
    public List<ScanResult.InformationElement> getInformationElements() {
        if (mInformationElements == null) return null;
        return new ArrayList<>(mInformationElements);
    }

    /**
     * @see #isPrimary()
     * @hide
     */
    public void setIsPrimary(boolean isPrimary) {
        mIsPrimary = isPrimary ? IS_PRIMARY_TRUE : IS_PRIMARY_FALSE;
    }

    /**
     * Returns whether this is the primary wifi connection or not.
     *
     * Wifi service considers this connection to be the best among all Wifi connections, and this
     * connection should be the one surfaced to the user if only one can be displayed.
     *
     * Note that the default route (chosen by Connectivity Service) may not correspond to the
     * primary Wifi connection e.g. when there exists a better cellular network, or if the
     * primary Wifi connection doesn't have internet access.
     *
     * @return whether this is the primary connection or not.
     *
     * @hide
     */
    @RequiresApi(Build.VERSION_CODES.S)
    @RequiresPermission(Manifest.permission.NETWORK_SETTINGS)
    @SystemApi
    public boolean isPrimary() {
        if (!SdkLevel.isAtLeastS()) {
            // Intentional - since we don't support STA + STA on older devices, this field
            // is redundant. Don't allow anyone to use this.
            throw new UnsupportedOperationException();
        }
        if (mIsPrimary == IS_PRIMARY_NO_PERMISSION) {
            throw new SecurityException("Not allowed to access this field");
        }
        return mIsPrimary == IS_PRIMARY_TRUE;
    }

    @Override
    public boolean equals(Object that) {
        if (this == that) return true;

        // Potential API behavior change, so don't change behavior on older devices.
        if (!SdkLevel.isAtLeastS()) return false;

        if (!(that instanceof WifiInfo)) return false;

        WifiInfo thatWifiInfo = (WifiInfo) that;
        return Objects.equals(mWifiSsid, thatWifiInfo.mWifiSsid)
                && Objects.equals(mBSSID, thatWifiInfo.mBSSID)
                && Objects.equals(mNetworkId, thatWifiInfo.mNetworkId)
                && Objects.equals(mRssi, thatWifiInfo.mRssi)
                && Objects.equals(mSupplicantState, thatWifiInfo.mSupplicantState)
                && Objects.equals(mLinkSpeed, thatWifiInfo.mLinkSpeed)
                && Objects.equals(mTxLinkSpeed, thatWifiInfo.mTxLinkSpeed)
                && Objects.equals(mRxLinkSpeed, thatWifiInfo.mRxLinkSpeed)
                && Objects.equals(mFrequency, thatWifiInfo.mFrequency)
                && Objects.equals(mIpAddress, thatWifiInfo.mIpAddress)
                && Objects.equals(mMacAddress, thatWifiInfo.mMacAddress)
                && Objects.equals(mMeteredHint, thatWifiInfo.mMeteredHint)
                && Objects.equals(mEphemeral, thatWifiInfo.mEphemeral)
                && Objects.equals(mTrusted, thatWifiInfo.mTrusted)
                && Objects.equals(mOemPaid, thatWifiInfo.mOemPaid)
                && Objects.equals(mOemPrivate, thatWifiInfo.mOemPrivate)
                && Objects.equals(mCarrierMerged, thatWifiInfo.mCarrierMerged)
                && Objects.equals(mRequestingPackageName, thatWifiInfo.mRequestingPackageName)
                && Objects.equals(mOsuAp, thatWifiInfo.mOsuAp)
                && Objects.equals(mFqdn, thatWifiInfo.mFqdn)
                && Objects.equals(mProviderFriendlyName, thatWifiInfo.mProviderFriendlyName)
                && Objects.equals(mSubscriptionId, thatWifiInfo.mSubscriptionId)
                && Objects.equals(txBad, thatWifiInfo.txBad)
                && Objects.equals(txRetries, thatWifiInfo.txRetries)
                && Objects.equals(txSuccess, thatWifiInfo.txSuccess)
                && Objects.equals(rxSuccess, thatWifiInfo.rxSuccess)
                && Objects.equals(mLostTxPacketsPerSecond, thatWifiInfo.mLostTxPacketsPerSecond)
                && Objects.equals(mTxRetriedTxPacketsPerSecond,
                thatWifiInfo.mTxRetriedTxPacketsPerSecond)
                && Objects.equals(mSuccessfulTxPacketsPerSecond,
                thatWifiInfo.mSuccessfulTxPacketsPerSecond)
                && Objects.equals(mSuccessfulRxPacketsPerSecond,
                thatWifiInfo.mSuccessfulRxPacketsPerSecond)
                && Objects.equals(score, thatWifiInfo.score)
                && Objects.equals(mWifiStandard, thatWifiInfo.mWifiStandard)
                && Objects.equals(mMaxSupportedTxLinkSpeed, thatWifiInfo.mMaxSupportedTxLinkSpeed)
                && Objects.equals(mMaxSupportedRxLinkSpeed, thatWifiInfo.mMaxSupportedRxLinkSpeed)
                && Objects.equals(mPasspointUniqueId, thatWifiInfo.mPasspointUniqueId)
                && Objects.equals(mInformationElements, thatWifiInfo.mInformationElements)
                && Objects.equals(mIsPrimary, thatWifiInfo.mIsPrimary)
                && Objects.equals(mSecurityType, thatWifiInfo.mSecurityType);
    }

    @Override
    public int hashCode() {
        // Potential API behavior change, so don't change behavior on older devices.
        if (!SdkLevel.isAtLeastS()) return System.identityHashCode(this);

        return Objects.hash(mWifiSsid,
                mBSSID,
                mNetworkId,
                mRssi,
                mSupplicantState,
                mLinkSpeed,
                mTxLinkSpeed,
                mRxLinkSpeed,
                mFrequency,
                mIpAddress,
                mMacAddress,
                mMeteredHint,
                mEphemeral,
                mTrusted,
                mOemPaid,
                mOemPrivate,
                mCarrierMerged,
                mRequestingPackageName,
                mOsuAp,
                mFqdn,
                mProviderFriendlyName,
                mSubscriptionId,
                txBad,
                txRetries,
                txSuccess,
                rxSuccess,
                mLostTxPacketsPerSecond,
                mTxRetriedTxPacketsPerSecond,
                mSuccessfulTxPacketsPerSecond,
                mSuccessfulRxPacketsPerSecond,
                score,
                mWifiStandard,
                mMaxSupportedTxLinkSpeed,
                mMaxSupportedRxLinkSpeed,
                mPasspointUniqueId,
                mInformationElements,
                mIsPrimary,
                mSecurityType);
    }

    /**
     * Create a copy of a {@link WifiInfo} with some fields redacted based on the permissions
     * held by the receiving app.
     *
     * @param redactions bitmask of redactions that needs to be performed on this instance.
     * @return Copy of this instance with the necessary redactions.
     */
    @Override
    @NonNull
    public WifiInfo makeCopy(long redactions) {
        return new WifiInfo(this, redactions);
    }

    /**
     * Returns a bitmask of all the applicable redactions (based on the permissions held by the
     * receiving app) to be performed on this TransportInfo.
     *
     * @return bitmask of redactions applicable on this instance.
     */
    @Override
    public long getApplicableRedactions() {
        return NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION
                | NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS
                | NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
    }

    /**
     * Set the security type of the current connection
     * @hide
     */
    public void setCurrentSecurityType(@WifiConfiguration.SecurityType int securityType) {
        mSecurityType = convertSecurityTypeToWifiInfo(securityType);
    }

    /**
     * Clear the last set security type
     * @hide
     */
    public void clearCurrentSecurityType() {
        mSecurityType = SECURITY_TYPE_UNKNOWN;
    }

    /**
     * Returns the security type of the current 802.11 network connection.
     *
     * @return the security type, or {@link #SECURITY_TYPE_UNKNOWN} if not currently connected.
     */
    public @SecurityType int getCurrentSecurityType() {
        return mSecurityType;
    }

    private @SecurityType int convertSecurityTypeToWifiInfo(
            @WifiConfiguration.SecurityType int securityType) {
        switch (securityType) {
            case WifiConfiguration.SECURITY_TYPE_OPEN:
                return SECURITY_TYPE_OPEN;
            case WifiConfiguration.SECURITY_TYPE_WEP:
                return SECURITY_TYPE_WEP;
            case WifiConfiguration.SECURITY_TYPE_PSK:
                return SECURITY_TYPE_PSK;
            case WifiConfiguration.SECURITY_TYPE_EAP:
                return SECURITY_TYPE_EAP;
            case WifiConfiguration.SECURITY_TYPE_SAE:
                return SECURITY_TYPE_SAE;
            case WifiConfiguration.SECURITY_TYPE_OWE:
                return SECURITY_TYPE_OWE;
            case WifiConfiguration.SECURITY_TYPE_WAPI_PSK:
                return SECURITY_TYPE_WAPI_PSK;
            case WifiConfiguration.SECURITY_TYPE_WAPI_CERT:
                return SECURITY_TYPE_WAPI_CERT;
            case WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE:
                return SECURITY_TYPE_EAP_WPA3_ENTERPRISE;
            case WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT:
                return SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT;
            case WifiConfiguration.SECURITY_TYPE_PASSPOINT_R1_R2:
                return SECURITY_TYPE_PASSPOINT_R1_R2;
            case WifiConfiguration.SECURITY_TYPE_PASSPOINT_R3:
                return SECURITY_TYPE_PASSPOINT_R3;
            default:
                return SECURITY_TYPE_UNKNOWN;
        }
    }
}
