/*
 * 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;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.Annotation.NetworkType;

import com.android.internal.annotations.VisibleForTesting;

import java.util.EnumMap;

/**
 * Describes the status of a network interface.
 * <p>Use {@link ConnectivityManager#getActiveNetworkInfo()} to get an instance that represents
 * the current network connection.
 *
 * @deprecated Callers should instead use the {@link ConnectivityManager.NetworkCallback} API to
 *             learn about connectivity changes, or switch to use
 *             {@link ConnectivityManager#getNetworkCapabilities} or
 *             {@link ConnectivityManager#getLinkProperties} to get information synchronously. Keep
 *             in mind that while callbacks are guaranteed to be called for every event in order,
 *             synchronous calls have no such constraints, and as such it is unadvisable to use the
 *             synchronous methods inside the callbacks as they will often not offer a view of
 *             networking that is consistent (that is: they may return a past or a future state with
 *             respect to the event being processed by the callback). Instead, callers are advised
 *             to only use the arguments of the callbacks, possibly memorizing the specific bits of
 *             information they need to keep from one callback to another.
 */
@Deprecated
public class NetworkInfo implements Parcelable {

    /**
     * Coarse-grained network state. This is probably what most applications should
     * use, rather than {@link android.net.NetworkInfo.DetailedState DetailedState}.
     * The mapping between the two is as follows:
     * <br/><br/>
     * <table>
     * <tr><td><b>Detailed state</b></td><td><b>Coarse-grained state</b></td></tr>
     * <tr><td><code>IDLE</code></td><td><code>DISCONNECTED</code></td></tr>
     * <tr><td><code>SCANNING</code></td><td><code>DISCONNECTED</code></td></tr>
     * <tr><td><code>CONNECTING</code></td><td><code>CONNECTING</code></td></tr>
     * <tr><td><code>AUTHENTICATING</code></td><td><code>CONNECTING</code></td></tr>
     * <tr><td><code>OBTAINING_IPADDR</code></td><td><code>CONNECTING</code></td></tr>
     * <tr><td><code>VERIFYING_POOR_LINK</code></td><td><code>CONNECTING</code></td></tr>
     * <tr><td><code>CAPTIVE_PORTAL_CHECK</code></td><td><code>CONNECTING</code></td></tr>
     * <tr><td><code>CONNECTED</code></td><td><code>CONNECTED</code></td></tr>
     * <tr><td><code>SUSPENDED</code></td><td><code>SUSPENDED</code></td></tr>
     * <tr><td><code>DISCONNECTING</code></td><td><code>DISCONNECTING</code></td></tr>
     * <tr><td><code>DISCONNECTED</code></td><td><code>DISCONNECTED</code></td></tr>
     * <tr><td><code>FAILED</code></td><td><code>DISCONNECTED</code></td></tr>
     * <tr><td><code>BLOCKED</code></td><td><code>DISCONNECTED</code></td></tr>
     * </table>
     *
     * @deprecated See {@link NetworkInfo}.
     */
    @Deprecated
    public enum State {
        CONNECTING, CONNECTED, SUSPENDED, DISCONNECTING, DISCONNECTED, UNKNOWN
    }

    /**
     * The fine-grained state of a network connection. This level of detail
     * is probably of interest to few applications. Most should use
     * {@link android.net.NetworkInfo.State State} instead.
     *
     * @deprecated See {@link NetworkInfo}.
     */
    @Deprecated
    public enum DetailedState {
        /** Ready to start data connection setup. */
        IDLE,
        /** Searching for an available access point. */
        SCANNING,
        /** Currently setting up data connection. */
        CONNECTING,
        /** Network link established, performing authentication. */
        AUTHENTICATING,
        /** Awaiting response from DHCP server in order to assign IP address information. */
        OBTAINING_IPADDR,
        /** IP traffic should be available. */
        CONNECTED,
        /** IP traffic is suspended */
        SUSPENDED,
        /** Currently tearing down data connection. */
        DISCONNECTING,
        /** IP traffic not available. */
        DISCONNECTED,
        /** Attempt to connect failed. */
        FAILED,
        /** Access to this network is blocked. */
        BLOCKED,
        /** Link has poor connectivity. */
        VERIFYING_POOR_LINK,
        /** Checking if network is a captive portal */
        CAPTIVE_PORTAL_CHECK
    }

    /**
     * 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<DetailedState, State> stateMap =
        new EnumMap<DetailedState, State>(DetailedState.class);

    static {
        stateMap.put(DetailedState.IDLE, State.DISCONNECTED);
        stateMap.put(DetailedState.SCANNING, State.DISCONNECTED);
        stateMap.put(DetailedState.CONNECTING, State.CONNECTING);
        stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING);
        stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING);
        stateMap.put(DetailedState.VERIFYING_POOR_LINK, State.CONNECTING);
        stateMap.put(DetailedState.CAPTIVE_PORTAL_CHECK, State.CONNECTING);
        stateMap.put(DetailedState.CONNECTED, State.CONNECTED);
        stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED);
        stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING);
        stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED);
        stateMap.put(DetailedState.FAILED, State.DISCONNECTED);
        stateMap.put(DetailedState.BLOCKED, State.DISCONNECTED);
    }

    private int mNetworkType;
    private int mSubtype;
    private String mTypeName;
    private String mSubtypeName;
    @NonNull
    private State mState;
    @NonNull
    private DetailedState mDetailedState;
    private String mReason;
    private String mExtraInfo;
    private boolean mIsFailover;
    private boolean mIsAvailable;
    private boolean mIsRoaming;

    /**
     * Create a new instance of NetworkInfo.
     *
     * This may be useful for apps to write unit tests.
     *
     * @param type the legacy type of the network, as one of the ConnectivityManager.TYPE_*
     *             constants.
     * @param subtype the subtype if applicable, as one of the TelephonyManager.NETWORK_TYPE_*
     *                constants.
     * @param typeName a human-readable string for the network type, or an empty string or null.
     * @param subtypeName a human-readable string for the subtype, or an empty string or null.
     */
    public NetworkInfo(int type, @NetworkType int subtype,
            @Nullable String typeName, @Nullable String subtypeName) {
        if (!ConnectivityManager.isNetworkTypeValid(type)
                && type != ConnectivityManager.TYPE_NONE) {
            throw new IllegalArgumentException("Invalid network type: " + type);
        }
        mNetworkType = type;
        mSubtype = subtype;
        mTypeName = typeName;
        mSubtypeName = subtypeName;
        setDetailedState(DetailedState.IDLE, null, null);
        mState = State.UNKNOWN;
    }

    /** {@hide} */
    @UnsupportedAppUsage
    public NetworkInfo(NetworkInfo source) {
        if (source != null) {
            synchronized (source) {
                mNetworkType = source.mNetworkType;
                mSubtype = source.mSubtype;
                mTypeName = source.mTypeName;
                mSubtypeName = source.mSubtypeName;
                mState = source.mState;
                mDetailedState = source.mDetailedState;
                mReason = source.mReason;
                mExtraInfo = source.mExtraInfo;
                mIsFailover = source.mIsFailover;
                mIsAvailable = source.mIsAvailable;
                mIsRoaming = source.mIsRoaming;
            }
        }
    }

    /**
     * Reports the type of network to which the
     * info in this {@code NetworkInfo} pertains.
     * @return one of {@link ConnectivityManager#TYPE_MOBILE}, {@link
     * ConnectivityManager#TYPE_WIFI}, {@link ConnectivityManager#TYPE_WIMAX}, {@link
     * ConnectivityManager#TYPE_ETHERNET},  {@link ConnectivityManager#TYPE_BLUETOOTH}, or other
     * types defined by {@link ConnectivityManager}.
     * @deprecated Callers should switch to checking {@link NetworkCapabilities#hasTransport}
     *             instead with one of the NetworkCapabilities#TRANSPORT_* constants :
     *             {@link #getType} and {@link #getTypeName} cannot account for networks using
     *             multiple transports. Note that generally apps should not care about transport;
     *             {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED} and
     *             {@link NetworkCapabilities#getLinkDownstreamBandwidthKbps} are calls that
     *             apps concerned with meteredness or bandwidth should be looking at, as they
     *             offer this information with much better accuracy.
     */
    @Deprecated
    public int getType() {
        synchronized (this) {
            return mNetworkType;
        }
    }

    /**
     * @deprecated Use {@link NetworkCapabilities} instead
     * @hide
     */
    @Deprecated
    public void setType(int type) {
        synchronized (this) {
            mNetworkType = type;
        }
    }

    /**
     * Return a network-type-specific integer describing the subtype
     * of the network.
     * @return the network subtype
     * @deprecated Use {@link android.telephony.TelephonyManager#getDataNetworkType} instead.
     */
    @Deprecated
    public int getSubtype() {
        synchronized (this) {
            return mSubtype;
        }
    }

    /**
     * @hide
     */
    @UnsupportedAppUsage
    public void setSubtype(int subtype, String subtypeName) {
        synchronized (this) {
            mSubtype = subtype;
            mSubtypeName = subtypeName;
        }
    }

    /**
     * Return a human-readable name describe the type of the network,
     * for example "WIFI" or "MOBILE".
     * @return the name of the network type
     * @deprecated Callers should switch to checking {@link NetworkCapabilities#hasTransport}
     *             instead with one of the NetworkCapabilities#TRANSPORT_* constants :
     *             {@link #getType} and {@link #getTypeName} cannot account for networks using
     *             multiple transports. Note that generally apps should not care about transport;
     *             {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED} and
     *             {@link NetworkCapabilities#getLinkDownstreamBandwidthKbps} are calls that
     *             apps concerned with meteredness or bandwidth should be looking at, as they
     *             offer this information with much better accuracy.
     */
    @Deprecated
    public String getTypeName() {
        synchronized (this) {
            return mTypeName;
        }
    }

    /**
     * Return a human-readable name describing the subtype of the network.
     * @return the name of the network subtype
     * @deprecated Use {@link android.telephony.TelephonyManager#getDataNetworkType} instead.
     */
    @Deprecated
    public String getSubtypeName() {
        synchronized (this) {
            return mSubtypeName;
        }
    }

    /**
     * Indicates whether network connectivity exists or is in the process
     * of being established. This is good for applications that need to
     * do anything related to the network other than read or write data.
     * For the latter, call {@link #isConnected()} instead, which guarantees
     * that the network is fully usable.
     * @return {@code true} if network connectivity exists or is in the process
     * of being established, {@code false} otherwise.
     * @deprecated Apps should instead use the
     *             {@link android.net.ConnectivityManager.NetworkCallback} API to
     *             learn about connectivity changes.
     *             {@link ConnectivityManager#registerDefaultNetworkCallback} and
     *             {@link ConnectivityManager#registerNetworkCallback}. These will
     *             give a more accurate picture of the connectivity state of
     *             the device and let apps react more easily and quickly to changes.
     */
    @Deprecated
    public boolean isConnectedOrConnecting() {
        synchronized (this) {
            return mState == State.CONNECTED || mState == State.CONNECTING;
        }
    }

    /**
     * Indicates whether network connectivity exists and it is possible to establish
     * connections and pass data.
     * <p>Always call this before attempting to perform data transactions.
     * @return {@code true} if network connectivity exists, {@code false} otherwise.
     * @deprecated Apps should instead use the
     *             {@link android.net.ConnectivityManager.NetworkCallback} API to
     *             learn about connectivity changes. See
     *             {@link ConnectivityManager#registerDefaultNetworkCallback} and
     *             {@link ConnectivityManager#registerNetworkCallback}. These will
     *             give a more accurate picture of the connectivity state of
     *             the device and let apps react more easily and quickly to changes.
     */
    @Deprecated
    public boolean isConnected() {
        synchronized (this) {
            return mState == State.CONNECTED;
        }
    }

    /**
     * Indicates whether network connectivity is possible. A network is unavailable
     * when a persistent or semi-persistent condition prevents the possibility
     * of connecting to that network. Examples include
     * <ul>
     * <li>The device is out of the coverage area for any network of this type.</li>
     * <li>The device is on a network other than the home network (i.e., roaming), and
     * data roaming has been disabled.</li>
     * <li>The device's radio is turned off, e.g., because airplane mode is enabled.</li>
     * </ul>
     * Since Android L, this always returns {@code true}, because the system only
     * returns info for available networks.
     * @return {@code true} if the network is available, {@code false} otherwise
     * @deprecated Apps should instead use the
     *             {@link android.net.ConnectivityManager.NetworkCallback} API to
     *             learn about connectivity changes.
     *             {@link ConnectivityManager#registerDefaultNetworkCallback} and
     *             {@link ConnectivityManager#registerNetworkCallback}. These will
     *             give a more accurate picture of the connectivity state of
     *             the device and let apps react more easily and quickly to changes.
     */
    @Deprecated
    public boolean isAvailable() {
        synchronized (this) {
            return mIsAvailable;
        }
    }

    /**
     * Sets if the network is available, ie, if the connectivity is possible.
     * @param isAvailable the new availability value.
     * @deprecated Use {@link NetworkCapabilities} instead
     *
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage
    public void setIsAvailable(boolean isAvailable) {
        synchronized (this) {
            mIsAvailable = isAvailable;
        }
    }

    /**
     * Indicates whether the current attempt to connect to the network
     * resulted from the ConnectivityManager trying to fail over to this
     * network following a disconnect from another network.
     * @return {@code true} if this is a failover attempt, {@code false}
     * otherwise.
     * @deprecated This field is not populated in recent Android releases,
     *             and does not make a lot of sense in a multi-network world.
     */
    @Deprecated
    public boolean isFailover() {
        synchronized (this) {
            return mIsFailover;
        }
    }

    /**
     * Set the failover boolean.
     * @param isFailover {@code true} to mark the current connection attempt
     * as a failover.
     * @deprecated This hasn't been set in any recent Android release.
     * @hide
     */
    @Deprecated
    @UnsupportedAppUsage
    public void setFailover(boolean isFailover) {
        synchronized (this) {
            mIsFailover = isFailover;
        }
    }

    /**
     * Indicates whether the device is currently roaming on this network. When
     * {@code true}, it suggests that use of data on this network may incur
     * extra costs.
     *
     * @return {@code true} if roaming is in effect, {@code false} otherwise.
     * @deprecated Callers should switch to checking
     *             {@link NetworkCapabilities#NET_CAPABILITY_NOT_ROAMING}
     *             instead, since that handles more complex situations, such as
     *             VPNs.
     */
    @Deprecated
    public boolean isRoaming() {
        synchronized (this) {
            return mIsRoaming;
        }
    }

    /**
     * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_NOT_ROAMING} instead.
     * {@hide}
     */
    @VisibleForTesting
    @Deprecated
    @UnsupportedAppUsage
    public void setRoaming(boolean isRoaming) {
        synchronized (this) {
            mIsRoaming = isRoaming;
        }
    }

    /**
     * Reports the current coarse-grained state of the network.
     * @return the coarse-grained state
     * @deprecated Apps should instead use the
     *             {@link android.net.ConnectivityManager.NetworkCallback} API to
     *             learn about connectivity changes.
     *             {@link ConnectivityManager#registerDefaultNetworkCallback} and
     *             {@link ConnectivityManager#registerNetworkCallback}. These will
     *             give a more accurate picture of the connectivity state of
     *             the device and let apps react more easily and quickly to changes.
     */
    @Deprecated
    public State getState() {
        synchronized (this) {
            return mState;
        }
    }

    /**
     * Reports the current fine-grained state of the network.
     * @return the fine-grained state
     * @deprecated Apps should instead use the
     *             {@link android.net.ConnectivityManager.NetworkCallback} API to
     *             learn about connectivity changes. See
     *             {@link ConnectivityManager#registerDefaultNetworkCallback} and
     *             {@link ConnectivityManager#registerNetworkCallback}. These will
     *             give a more accurate picture of the connectivity state of
     *             the device and let apps react more easily and quickly to changes.
     */
    @Deprecated
    public @NonNull DetailedState getDetailedState() {
        synchronized (this) {
            return mDetailedState;
        }
    }

    /**
     * Sets the fine-grained state of the network.
     *
     * This is only useful for testing.
     *
     * @param detailedState the {@link DetailedState}.
     * @param reason a {@code String} indicating the reason for the state change,
     * if one was supplied. May be {@code null}.
     * @param extraInfo an optional {@code String} providing addditional network state
     * information passed up from the lower networking layers.
     * @deprecated Use {@link NetworkCapabilities} instead.
     */
    @Deprecated
    public void setDetailedState(@NonNull DetailedState detailedState, @Nullable String reason,
            @Nullable String extraInfo) {
        synchronized (this) {
            this.mDetailedState = detailedState;
            this.mState = stateMap.get(detailedState);
            this.mReason = reason;
            this.mExtraInfo = extraInfo;
        }
    }

    /**
     * Set the extraInfo field.
     * @param extraInfo an optional {@code String} providing addditional network state
     * information passed up from the lower networking layers.
     * @deprecated See {@link NetworkInfo#getExtraInfo}.
     * @hide
     */
    @Deprecated
    public void setExtraInfo(String extraInfo) {
        synchronized (this) {
            this.mExtraInfo = extraInfo;
        }
    }

    /**
     * Report the reason an attempt to establish connectivity failed,
     * if one is available.
     * @return the reason for failure, or null if not available
     * @deprecated This method does not have a consistent contract that could make it useful
     *             to callers.
     */
    public String getReason() {
        synchronized (this) {
            return mReason;
        }
    }

    /**
     * Report the extra information about the network state, if any was
     * provided by the lower networking layers.
     * @return the extra information, or null if not available
     * @deprecated Use other services e.g. WifiManager to get additional information passed up from
     *             the lower networking layers.
     */
    @Deprecated
    public String getExtraInfo() {
        synchronized (this) {
            return mExtraInfo;
        }
    }

    @Override
    public String toString() {
        synchronized (this) {
            StringBuilder builder = new StringBuilder("[");
            builder.append("type: ").append(getTypeName()).append("[").append(getSubtypeName()).
            append("], state: ").append(mState).append("/").append(mDetailedState).
            append(", reason: ").append(mReason == null ? "(unspecified)" : mReason).
            append(", extra: ").append(mExtraInfo == null ? "(none)" : mExtraInfo).
            append(", failover: ").append(mIsFailover).
            append(", available: ").append(mIsAvailable).
            append(", roaming: ").append(mIsRoaming).
            append("]");
            return builder.toString();
        }
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        synchronized (this) {
            dest.writeInt(mNetworkType);
            dest.writeInt(mSubtype);
            dest.writeString(mTypeName);
            dest.writeString(mSubtypeName);
            dest.writeString(mState.name());
            dest.writeString(mDetailedState.name());
            dest.writeInt(mIsFailover ? 1 : 0);
            dest.writeInt(mIsAvailable ? 1 : 0);
            dest.writeInt(mIsRoaming ? 1 : 0);
            dest.writeString(mReason);
            dest.writeString(mExtraInfo);
        }
    }

    public static final @android.annotation.NonNull Creator<NetworkInfo> CREATOR = new Creator<NetworkInfo>() {
        @Override
        public NetworkInfo createFromParcel(Parcel in) {
            int netType = in.readInt();
            int subtype = in.readInt();
            String typeName = in.readString();
            String subtypeName = in.readString();
            NetworkInfo netInfo = new NetworkInfo(netType, subtype, typeName, subtypeName);
            netInfo.mState = State.valueOf(in.readString());
            netInfo.mDetailedState = DetailedState.valueOf(in.readString());
            netInfo.mIsFailover = in.readInt() != 0;
            netInfo.mIsAvailable = in.readInt() != 0;
            netInfo.mIsRoaming = in.readInt() != 0;
            netInfo.mReason = in.readString();
            netInfo.mExtraInfo = in.readString();
            return netInfo;
        }

        @Override
        public NetworkInfo[] newArray(int size) {
            return new NetworkInfo[size];
        }
    };
}
