/* * 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.text.TextUtils; import com.android.internal.annotations.VisibleForTesting; import java.util.EnumMap; /** * Describes the status of a network interface. *

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: *

* * * * * * * * * * * * * * * *
Detailed stateCoarse-grained state
IDLEDISCONNECTED
SCANNINGDISCONNECTED
CONNECTINGCONNECTING
AUTHENTICATINGCONNECTING
OBTAINING_IPADDRCONNECTING
VERIFYING_POOR_LINKCONNECTING
CAPTIVE_PORTAL_CHECKCONNECTING
CONNECTEDCONNECTED
SUSPENDEDSUSPENDED
DISCONNECTINGDISCONNECTING
DISCONNECTEDDISCONNECTED
FAILEDDISCONNECTED
BLOCKEDDISCONNECTED
* * @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 DetailedState. */ private static final EnumMap stateMap = new EnumMap(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, 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. *

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 *

* 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) { final 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(); } } /** * Returns a brief summary string suitable for debugging. * @hide */ public String toShortString() { synchronized (this) { final StringBuilder builder = new StringBuilder(); builder.append(getTypeName()); final String subtype = getSubtypeName(); if (!TextUtils.isEmpty(subtype)) { builder.append("[").append(subtype).append("]"); } builder.append(" "); builder.append(mDetailedState); if (mIsRoaming) { builder.append(" ROAMING"); } if (mExtraInfo != null) { builder.append(" extra: ").append(mExtraInfo); } 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 CREATOR = new Creator() { @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]; } }; }