/*
* 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 state | Coarse-grained state |
* IDLE | DISCONNECTED |
* SCANNING | DISCONNECTED |
* CONNECTING | CONNECTING |
* AUTHENTICATING | CONNECTING |
* OBTAINING_IPADDR | CONNECTING |
* VERIFYING_POOR_LINK | CONNECTING |
* CAPTIVE_PORTAL_CHECK | CONNECTING |
* CONNECTED | CONNECTED |
* SUSPENDED | SUSPENDED |
* DISCONNECTING | DISCONNECTING |
* DISCONNECTED | DISCONNECTED |
* FAILED | DISCONNECTED |
* BLOCKED | DISCONNECTED |
*
*
* @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
*
* - The device is out of the coverage area for any network of this type.
* - The device is on a network other than the home network (i.e., roaming), and
* data roaming has been disabled.
* - The device's radio is turned off, e.g., because airplane mode is enabled.
*
* 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];
}
};
}