/*
 * 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.
     */
    @RequiresPermission(allOf = {
            Manifest.permission.LOCAL_MAC_ADDRESS,
            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;
        }
    }
}
