Home | History | Annotate | Download | only in net
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.net;
     18 
     19 import android.os.Parcel;
     20 import android.os.Parcelable;
     21 
     22 import com.android.internal.annotations.VisibleForTesting;
     23 
     24 import java.util.EnumMap;
     25 
     26 /**
     27  * Describes the status of a network interface.
     28  * <p>Use {@link ConnectivityManager#getActiveNetworkInfo()} to get an instance that represents
     29  * the current network connection.
     30  */
     31 public class NetworkInfo implements Parcelable {
     32 
     33     /**
     34      * Coarse-grained network state. This is probably what most applications should
     35      * use, rather than {@link android.net.NetworkInfo.DetailedState DetailedState}.
     36      * The mapping between the two is as follows:
     37      * <br/><br/>
     38      * <table>
     39      * <tr><td><b>Detailed state</b></td><td><b>Coarse-grained state</b></td></tr>
     40      * <tr><td><code>IDLE</code></td><td><code>DISCONNECTED</code></td></tr>
     41      * <tr><td><code>SCANNING</code></td><td><code>DISCONNECTED</code></td></tr>
     42      * <tr><td><code>CONNECTING</code></td><td><code>CONNECTING</code></td></tr>
     43      * <tr><td><code>AUTHENTICATING</code></td><td><code>CONNECTING</code></td></tr>
     44      * <tr><td><code>OBTAINING_IPADDR</code></td><td><code>CONNECTING</code></td></tr>
     45      * <tr><td><code>VERIFYING_POOR_LINK</code></td><td><code>CONNECTING</code></td></tr>
     46      * <tr><td><code>CAPTIVE_PORTAL_CHECK</code></td><td><code>CONNECTING</code></td></tr>
     47      * <tr><td><code>CONNECTED</code></td><td><code>CONNECTED</code></td></tr>
     48      * <tr><td><code>SUSPENDED</code></td><td><code>SUSPENDED</code></td></tr>
     49      * <tr><td><code>DISCONNECTING</code></td><td><code>DISCONNECTING</code></td></tr>
     50      * <tr><td><code>DISCONNECTED</code></td><td><code>DISCONNECTED</code></td></tr>
     51      * <tr><td><code>FAILED</code></td><td><code>DISCONNECTED</code></td></tr>
     52      * <tr><td><code>BLOCKED</code></td><td><code>DISCONNECTED</code></td></tr>
     53      * </table>
     54      */
     55     public enum State {
     56         CONNECTING, CONNECTED, SUSPENDED, DISCONNECTING, DISCONNECTED, UNKNOWN
     57     }
     58 
     59     /**
     60      * The fine-grained state of a network connection. This level of detail
     61      * is probably of interest to few applications. Most should use
     62      * {@link android.net.NetworkInfo.State State} instead.
     63      */
     64     public enum DetailedState {
     65         /** Ready to start data connection setup. */
     66         IDLE,
     67         /** Searching for an available access point. */
     68         SCANNING,
     69         /** Currently setting up data connection. */
     70         CONNECTING,
     71         /** Network link established, performing authentication. */
     72         AUTHENTICATING,
     73         /** Awaiting response from DHCP server in order to assign IP address information. */
     74         OBTAINING_IPADDR,
     75         /** IP traffic should be available. */
     76         CONNECTED,
     77         /** IP traffic is suspended */
     78         SUSPENDED,
     79         /** Currently tearing down data connection. */
     80         DISCONNECTING,
     81         /** IP traffic not available. */
     82         DISCONNECTED,
     83         /** Attempt to connect failed. */
     84         FAILED,
     85         /** Access to this network is blocked. */
     86         BLOCKED,
     87         /** Link has poor connectivity. */
     88         VERIFYING_POOR_LINK,
     89         /** Checking if network is a captive portal */
     90         CAPTIVE_PORTAL_CHECK
     91     }
     92 
     93     /**
     94      * This is the map described in the Javadoc comment above. The positions
     95      * of the elements of the array must correspond to the ordinal values
     96      * of <code>DetailedState</code>.
     97      */
     98     private static final EnumMap<DetailedState, State> stateMap =
     99         new EnumMap<DetailedState, State>(DetailedState.class);
    100 
    101     static {
    102         stateMap.put(DetailedState.IDLE, State.DISCONNECTED);
    103         stateMap.put(DetailedState.SCANNING, State.DISCONNECTED);
    104         stateMap.put(DetailedState.CONNECTING, State.CONNECTING);
    105         stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING);
    106         stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING);
    107         stateMap.put(DetailedState.VERIFYING_POOR_LINK, State.CONNECTING);
    108         stateMap.put(DetailedState.CAPTIVE_PORTAL_CHECK, State.CONNECTING);
    109         stateMap.put(DetailedState.CONNECTED, State.CONNECTED);
    110         stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED);
    111         stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING);
    112         stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED);
    113         stateMap.put(DetailedState.FAILED, State.DISCONNECTED);
    114         stateMap.put(DetailedState.BLOCKED, State.DISCONNECTED);
    115     }
    116 
    117     private int mNetworkType;
    118     private int mSubtype;
    119     private String mTypeName;
    120     private String mSubtypeName;
    121     private State mState;
    122     private DetailedState mDetailedState;
    123     private String mReason;
    124     private String mExtraInfo;
    125     private boolean mIsFailover;
    126     private boolean mIsAvailable;
    127     private boolean mIsRoaming;
    128 
    129     /**
    130      * @hide
    131      */
    132     public NetworkInfo(int type, int subtype, String typeName, String subtypeName) {
    133         if (!ConnectivityManager.isNetworkTypeValid(type)
    134                 && type != ConnectivityManager.TYPE_NONE) {
    135             throw new IllegalArgumentException("Invalid network type: " + type);
    136         }
    137         mNetworkType = type;
    138         mSubtype = subtype;
    139         mTypeName = typeName;
    140         mSubtypeName = subtypeName;
    141         setDetailedState(DetailedState.IDLE, null, null);
    142         mState = State.UNKNOWN;
    143     }
    144 
    145     /** {@hide} */
    146     public NetworkInfo(NetworkInfo source) {
    147         if (source != null) {
    148             synchronized (source) {
    149                 mNetworkType = source.mNetworkType;
    150                 mSubtype = source.mSubtype;
    151                 mTypeName = source.mTypeName;
    152                 mSubtypeName = source.mSubtypeName;
    153                 mState = source.mState;
    154                 mDetailedState = source.mDetailedState;
    155                 mReason = source.mReason;
    156                 mExtraInfo = source.mExtraInfo;
    157                 mIsFailover = source.mIsFailover;
    158                 mIsAvailable = source.mIsAvailable;
    159                 mIsRoaming = source.mIsRoaming;
    160             }
    161         }
    162     }
    163 
    164     /**
    165      * Reports the type of network to which the
    166      * info in this {@code NetworkInfo} pertains.
    167      * @return one of {@link ConnectivityManager#TYPE_MOBILE}, {@link
    168      * ConnectivityManager#TYPE_WIFI}, {@link ConnectivityManager#TYPE_WIMAX}, {@link
    169      * ConnectivityManager#TYPE_ETHERNET},  {@link ConnectivityManager#TYPE_BLUETOOTH}, or other
    170      * types defined by {@link ConnectivityManager}.
    171      * @deprecated Callers should switch to checking {@link NetworkCapabilities#hasTransport}
    172      *             instead with one of the NetworkCapabilities#TRANSPORT_* constants :
    173      *             {@link #getType} and {@link #getTypeName} cannot account for networks using
    174      *             multiple transports. Note that generally apps should not care about transport;
    175      *             {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED} and
    176      *             {@link NetworkCapabilities#getLinkDownstreamBandwidthKbps} are calls that
    177      *             apps concerned with meteredness or bandwidth should be looking at, as they
    178      *             offer this information with much better accuracy.
    179      */
    180     @Deprecated
    181     public int getType() {
    182         synchronized (this) {
    183             return mNetworkType;
    184         }
    185     }
    186 
    187     /**
    188      * @deprecated Use {@link NetworkCapabilities} instead
    189      * @hide
    190      */
    191     @Deprecated
    192     public void setType(int type) {
    193         synchronized (this) {
    194             mNetworkType = type;
    195         }
    196     }
    197 
    198     /**
    199      * Return a network-type-specific integer describing the subtype
    200      * of the network.
    201      * @return the network subtype
    202      */
    203     public int getSubtype() {
    204         synchronized (this) {
    205             return mSubtype;
    206         }
    207     }
    208 
    209     /**
    210      * @hide
    211      */
    212     public void setSubtype(int subtype, String subtypeName) {
    213         synchronized (this) {
    214             mSubtype = subtype;
    215             mSubtypeName = subtypeName;
    216         }
    217     }
    218 
    219     /**
    220      * Return a human-readable name describe the type of the network,
    221      * for example "WIFI" or "MOBILE".
    222      * @return the name of the network type
    223      * @deprecated Callers should switch to checking {@link NetworkCapabilities#hasTransport}
    224      *             instead with one of the NetworkCapabilities#TRANSPORT_* constants :
    225      *             {@link #getType} and {@link #getTypeName} cannot account for networks using
    226      *             multiple transports. Note that generally apps should not care about transport;
    227      *             {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED} and
    228      *             {@link NetworkCapabilities#getLinkDownstreamBandwidthKbps} are calls that
    229      *             apps concerned with meteredness or bandwidth should be looking at, as they
    230      *             offer this information with much better accuracy.
    231      */
    232     @Deprecated
    233     public String getTypeName() {
    234         synchronized (this) {
    235             return mTypeName;
    236         }
    237     }
    238 
    239     /**
    240      * Return a human-readable name describing the subtype of the network.
    241      * @return the name of the network subtype
    242      */
    243     public String getSubtypeName() {
    244         synchronized (this) {
    245             return mSubtypeName;
    246         }
    247     }
    248 
    249     /**
    250      * Indicates whether network connectivity exists or is in the process
    251      * of being established. This is good for applications that need to
    252      * do anything related to the network other than read or write data.
    253      * For the latter, call {@link #isConnected()} instead, which guarantees
    254      * that the network is fully usable.
    255      * @return {@code true} if network connectivity exists or is in the process
    256      * of being established, {@code false} otherwise.
    257      * @deprecated Apps should instead use the
    258      *             {@link android.net.ConnectivityManager.NetworkCallback} API to
    259      *             learn about connectivity changes.
    260      *             {@link ConnectivityManager#registerDefaultNetworkCallback} and
    261      *             {@link ConnectivityManager#registerNetworkCallback}. These will
    262      *             give a more accurate picture of the connectivity state of
    263      *             the device and let apps react more easily and quickly to changes.
    264      */
    265     @Deprecated
    266     public boolean isConnectedOrConnecting() {
    267         synchronized (this) {
    268             return mState == State.CONNECTED || mState == State.CONNECTING;
    269         }
    270     }
    271 
    272     /**
    273      * Indicates whether network connectivity exists and it is possible to establish
    274      * connections and pass data.
    275      * <p>Always call this before attempting to perform data transactions.
    276      * @return {@code true} if network connectivity exists, {@code false} otherwise.
    277      */
    278     public boolean isConnected() {
    279         synchronized (this) {
    280             return mState == State.CONNECTED;
    281         }
    282     }
    283 
    284     /**
    285      * Indicates whether network connectivity is possible. A network is unavailable
    286      * when a persistent or semi-persistent condition prevents the possibility
    287      * of connecting to that network. Examples include
    288      * <ul>
    289      * <li>The device is out of the coverage area for any network of this type.</li>
    290      * <li>The device is on a network other than the home network (i.e., roaming), and
    291      * data roaming has been disabled.</li>
    292      * <li>The device's radio is turned off, e.g., because airplane mode is enabled.</li>
    293      * </ul>
    294      * Since Android L, this always returns {@code true}, because the system only
    295      * returns info for available networks.
    296      * @return {@code true} if the network is available, {@code false} otherwise
    297      * @deprecated Apps should instead use the
    298      *             {@link android.net.ConnectivityManager.NetworkCallback} API to
    299      *             learn about connectivity changes.
    300      *             {@link ConnectivityManager#registerDefaultNetworkCallback} and
    301      *             {@link ConnectivityManager#registerNetworkCallback}. These will
    302      *             give a more accurate picture of the connectivity state of
    303      *             the device and let apps react more easily and quickly to changes.
    304      */
    305     @Deprecated
    306     public boolean isAvailable() {
    307         synchronized (this) {
    308             return mIsAvailable;
    309         }
    310     }
    311 
    312     /**
    313      * Sets if the network is available, ie, if the connectivity is possible.
    314      * @param isAvailable the new availability value.
    315      * @deprecated Use {@link NetworkCapabilities} instead
    316      *
    317      * @hide
    318      */
    319     @Deprecated
    320     public void setIsAvailable(boolean isAvailable) {
    321         synchronized (this) {
    322             mIsAvailable = isAvailable;
    323         }
    324     }
    325 
    326     /**
    327      * Indicates whether the current attempt to connect to the network
    328      * resulted from the ConnectivityManager trying to fail over to this
    329      * network following a disconnect from another network.
    330      * @return {@code true} if this is a failover attempt, {@code false}
    331      * otherwise.
    332      * @deprecated This field is not populated in recent Android releases,
    333      *             and does not make a lot of sense in a multi-network world.
    334      */
    335     @Deprecated
    336     public boolean isFailover() {
    337         synchronized (this) {
    338             return mIsFailover;
    339         }
    340     }
    341 
    342     /**
    343      * Set the failover boolean.
    344      * @param isFailover {@code true} to mark the current connection attempt
    345      * as a failover.
    346      * @deprecated This hasn't been set in any recent Android release.
    347      * @hide
    348      */
    349     @Deprecated
    350     public void setFailover(boolean isFailover) {
    351         synchronized (this) {
    352             mIsFailover = isFailover;
    353         }
    354     }
    355 
    356     /**
    357      * Indicates whether the device is currently roaming on this network. When
    358      * {@code true}, it suggests that use of data on this network may incur
    359      * extra costs.
    360      *
    361      * @return {@code true} if roaming is in effect, {@code false} otherwise.
    362      * @deprecated Callers should switch to checking
    363      *             {@link NetworkCapabilities#NET_CAPABILITY_NOT_ROAMING}
    364      *             instead, since that handles more complex situations, such as
    365      *             VPNs.
    366      */
    367     @Deprecated
    368     public boolean isRoaming() {
    369         synchronized (this) {
    370             return mIsRoaming;
    371         }
    372     }
    373 
    374     /**
    375      * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_NOT_ROAMING} instead.
    376      * {@hide}
    377      */
    378     @VisibleForTesting
    379     @Deprecated
    380     public void setRoaming(boolean isRoaming) {
    381         synchronized (this) {
    382             mIsRoaming = isRoaming;
    383         }
    384     }
    385 
    386     /**
    387      * Reports the current coarse-grained state of the network.
    388      * @return the coarse-grained state
    389      * @deprecated Apps should instead use the
    390      *             {@link android.net.ConnectivityManager.NetworkCallback} API to
    391      *             learn about connectivity changes.
    392      *             {@link ConnectivityManager#registerDefaultNetworkCallback} and
    393      *             {@link ConnectivityManager#registerNetworkCallback}. These will
    394      *             give a more accurate picture of the connectivity state of
    395      *             the device and let apps react more easily and quickly to changes.
    396      */
    397     @Deprecated
    398     public State getState() {
    399         synchronized (this) {
    400             return mState;
    401         }
    402     }
    403 
    404     /**
    405      * Reports the current fine-grained state of the network.
    406      * @return the fine-grained state
    407      */
    408     public DetailedState getDetailedState() {
    409         synchronized (this) {
    410             return mDetailedState;
    411         }
    412     }
    413 
    414     /**
    415      * Sets the fine-grained state of the network.
    416      * @param detailedState the {@link DetailedState}.
    417      * @param reason a {@code String} indicating the reason for the state change,
    418      * if one was supplied. May be {@code null}.
    419      * @param extraInfo an optional {@code String} providing addditional network state
    420      * information passed up from the lower networking layers.
    421      * @deprecated Use {@link NetworkCapabilities} instead.
    422      * @hide
    423      */
    424     @Deprecated
    425     public void setDetailedState(DetailedState detailedState, String reason, String extraInfo) {
    426         synchronized (this) {
    427             this.mDetailedState = detailedState;
    428             this.mState = stateMap.get(detailedState);
    429             this.mReason = reason;
    430             this.mExtraInfo = extraInfo;
    431         }
    432     }
    433 
    434     /**
    435      * Set the extraInfo field.
    436      * @param extraInfo an optional {@code String} providing addditional network state
    437      * information passed up from the lower networking layers.
    438      * @hide
    439      */
    440     public void setExtraInfo(String extraInfo) {
    441         synchronized (this) {
    442             this.mExtraInfo = extraInfo;
    443         }
    444     }
    445 
    446     /**
    447      * Report the reason an attempt to establish connectivity failed,
    448      * if one is available.
    449      * @return the reason for failure, or null if not available
    450      * @deprecated This method does not have a consistent contract that could make it useful
    451      *             to callers.
    452      */
    453     public String getReason() {
    454         synchronized (this) {
    455             return mReason;
    456         }
    457     }
    458 
    459     /**
    460      * Report the extra information about the network state, if any was
    461      * provided by the lower networking layers.
    462      * @return the extra information, or null if not available
    463      */
    464     public String getExtraInfo() {
    465         synchronized (this) {
    466             return mExtraInfo;
    467         }
    468     }
    469 
    470     @Override
    471     public String toString() {
    472         synchronized (this) {
    473             StringBuilder builder = new StringBuilder("[");
    474             builder.append("type: ").append(getTypeName()).append("[").append(getSubtypeName()).
    475             append("], state: ").append(mState).append("/").append(mDetailedState).
    476             append(", reason: ").append(mReason == null ? "(unspecified)" : mReason).
    477             append(", extra: ").append(mExtraInfo == null ? "(none)" : mExtraInfo).
    478             append(", failover: ").append(mIsFailover).
    479             append(", available: ").append(mIsAvailable).
    480             append(", roaming: ").append(mIsRoaming).
    481             append("]");
    482             return builder.toString();
    483         }
    484     }
    485 
    486     @Override
    487     public int describeContents() {
    488         return 0;
    489     }
    490 
    491     @Override
    492     public void writeToParcel(Parcel dest, int flags) {
    493         synchronized (this) {
    494             dest.writeInt(mNetworkType);
    495             dest.writeInt(mSubtype);
    496             dest.writeString(mTypeName);
    497             dest.writeString(mSubtypeName);
    498             dest.writeString(mState.name());
    499             dest.writeString(mDetailedState.name());
    500             dest.writeInt(mIsFailover ? 1 : 0);
    501             dest.writeInt(mIsAvailable ? 1 : 0);
    502             dest.writeInt(mIsRoaming ? 1 : 0);
    503             dest.writeString(mReason);
    504             dest.writeString(mExtraInfo);
    505         }
    506     }
    507 
    508     public static final Creator<NetworkInfo> CREATOR = new Creator<NetworkInfo>() {
    509         @Override
    510         public NetworkInfo createFromParcel(Parcel in) {
    511             int netType = in.readInt();
    512             int subtype = in.readInt();
    513             String typeName = in.readString();
    514             String subtypeName = in.readString();
    515             NetworkInfo netInfo = new NetworkInfo(netType, subtype, typeName, subtypeName);
    516             netInfo.mState = State.valueOf(in.readString());
    517             netInfo.mDetailedState = DetailedState.valueOf(in.readString());
    518             netInfo.mIsFailover = in.readInt() != 0;
    519             netInfo.mIsAvailable = in.readInt() != 0;
    520             netInfo.mIsRoaming = in.readInt() != 0;
    521             netInfo.mReason = in.readString();
    522             netInfo.mExtraInfo = in.readString();
    523             return netInfo;
    524         }
    525 
    526         @Override
    527         public NetworkInfo[] newArray(int size) {
    528             return new NetworkInfo[size];
    529         }
    530     };
    531 }
    532