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.Parcelable;
     20 import android.os.Parcel;
     21 
     22 import java.util.EnumMap;
     23 
     24 /**
     25  * Describes the status of a network interface.
     26  * <p>Use {@link ConnectivityManager#getActiveNetworkInfo()} to get an instance that represents
     27  * the current network connection.
     28  */
     29 public class NetworkInfo implements Parcelable {
     30 
     31     /**
     32      * Coarse-grained network state. This is probably what most applications should
     33      * use, rather than {@link android.net.NetworkInfo.DetailedState DetailedState}.
     34      * The mapping between the two is as follows:
     35      * <br/><br/>
     36      * <table>
     37      * <tr><td><b>Detailed state</b></td><td><b>Coarse-grained state</b></td></tr>
     38      * <tr><td><code>IDLE</code></td><td><code>DISCONNECTED</code></td></tr>
     39      * <tr><td><code>SCANNING</code></td><td><code>CONNECTING</code></td></tr>
     40      * <tr><td><code>CONNECTING</code></td><td><code>CONNECTING</code></td></tr>
     41      * <tr><td><code>AUTHENTICATING</code></td><td><code>CONNECTING</code></td></tr>
     42      * <tr><td><code>CONNECTED</code></td><td><code>CONNECTED</code></td></tr>
     43      * <tr><td><code>DISCONNECTING</code></td><td><code>DISCONNECTING</code></td></tr>
     44      * <tr><td><code>DISCONNECTED</code></td><td><code>DISCONNECTED</code></td></tr>
     45      * <tr><td><code>UNAVAILABLE</code></td><td><code>DISCONNECTED</code></td></tr>
     46      * <tr><td><code>FAILED</code></td><td><code>DISCONNECTED</code></td></tr>
     47      * </table>
     48      */
     49     public enum State {
     50         CONNECTING, CONNECTED, SUSPENDED, DISCONNECTING, DISCONNECTED, UNKNOWN
     51     }
     52 
     53     /**
     54      * The fine-grained state of a network connection. This level of detail
     55      * is probably of interest to few applications. Most should use
     56      * {@link android.net.NetworkInfo.State State} instead.
     57      */
     58     public enum DetailedState {
     59         /** Ready to start data connection setup. */
     60         IDLE,
     61         /** Searching for an available access point. */
     62         SCANNING,
     63         /** Currently setting up data connection. */
     64         CONNECTING,
     65         /** Network link established, performing authentication. */
     66         AUTHENTICATING,
     67         /** Awaiting response from DHCP server in order to assign IP address information. */
     68         OBTAINING_IPADDR,
     69         /** IP traffic should be available. */
     70         CONNECTED,
     71         /** IP traffic is suspended */
     72         SUSPENDED,
     73         /** Currently tearing down data connection. */
     74         DISCONNECTING,
     75         /** IP traffic not available. */
     76         DISCONNECTED,
     77         /** Attempt to connect failed. */
     78         FAILED,
     79         /** Access to this network is blocked. */
     80         BLOCKED,
     81         /** Link has poor connectivity. */
     82         VERIFYING_POOR_LINK,
     83         /** Checking if network is a captive portal */
     84         CAPTIVE_PORTAL_CHECK,
     85     }
     86 
     87     /**
     88      * This is the map described in the Javadoc comment above. The positions
     89      * of the elements of the array must correspond to the ordinal values
     90      * of <code>DetailedState</code>.
     91      */
     92     private static final EnumMap<DetailedState, State> stateMap =
     93         new EnumMap<DetailedState, State>(DetailedState.class);
     94 
     95     static {
     96         stateMap.put(DetailedState.IDLE, State.DISCONNECTED);
     97         stateMap.put(DetailedState.SCANNING, State.DISCONNECTED);
     98         stateMap.put(DetailedState.CONNECTING, State.CONNECTING);
     99         stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING);
    100         stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING);
    101         stateMap.put(DetailedState.VERIFYING_POOR_LINK, State.CONNECTING);
    102         stateMap.put(DetailedState.CAPTIVE_PORTAL_CHECK, State.CONNECTING);
    103         stateMap.put(DetailedState.CONNECTED, State.CONNECTED);
    104         stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED);
    105         stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING);
    106         stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED);
    107         stateMap.put(DetailedState.FAILED, State.DISCONNECTED);
    108         stateMap.put(DetailedState.BLOCKED, State.DISCONNECTED);
    109     }
    110 
    111     private int mNetworkType;
    112     private int mSubtype;
    113     private String mTypeName;
    114     private String mSubtypeName;
    115     private State mState;
    116     private DetailedState mDetailedState;
    117     private String mReason;
    118     private String mExtraInfo;
    119     private boolean mIsFailover;
    120     private boolean mIsRoaming;
    121     /**
    122      * Indicates whether network connectivity is possible:
    123      */
    124     private boolean mIsAvailable;
    125 
    126     /**
    127      * @param type network type
    128      * @deprecated
    129      * @hide because this constructor was only meant for internal use (and
    130      * has now been superseded by the package-private constructor below).
    131      */
    132     public NetworkInfo(int type) {}
    133 
    134     /**
    135      * @hide
    136      */
    137     public NetworkInfo(int type, int subtype, String typeName, String subtypeName) {
    138         if (!ConnectivityManager.isNetworkTypeValid(type)) {
    139             throw new IllegalArgumentException("Invalid network type: " + type);
    140         }
    141         mNetworkType = type;
    142         mSubtype = subtype;
    143         mTypeName = typeName;
    144         mSubtypeName = subtypeName;
    145         setDetailedState(DetailedState.IDLE, null, null);
    146         mState = State.UNKNOWN;
    147         mIsAvailable = false; // until we're told otherwise, assume unavailable
    148         mIsRoaming = false;
    149     }
    150 
    151     /** {@hide} */
    152     public NetworkInfo(NetworkInfo source) {
    153         if (source != null) {
    154             mNetworkType = source.mNetworkType;
    155             mSubtype = source.mSubtype;
    156             mTypeName = source.mTypeName;
    157             mSubtypeName = source.mSubtypeName;
    158             mState = source.mState;
    159             mDetailedState = source.mDetailedState;
    160             mReason = source.mReason;
    161             mExtraInfo = source.mExtraInfo;
    162             mIsFailover = source.mIsFailover;
    163             mIsRoaming = source.mIsRoaming;
    164             mIsAvailable = source.mIsAvailable;
    165         }
    166     }
    167 
    168     /**
    169      * Reports the type of network to which the
    170      * info in this {@code NetworkInfo} pertains.
    171      * @return one of {@link ConnectivityManager#TYPE_MOBILE}, {@link
    172      * ConnectivityManager#TYPE_WIFI}, {@link ConnectivityManager#TYPE_WIMAX}, {@link
    173      * ConnectivityManager#TYPE_ETHERNET},  {@link ConnectivityManager#TYPE_BLUETOOTH}, or other
    174      * types defined by {@link ConnectivityManager}
    175      */
    176     public int getType() {
    177         synchronized (this) {
    178             return mNetworkType;
    179         }
    180     }
    181 
    182     /**
    183      * Return a network-type-specific integer describing the subtype
    184      * of the network.
    185      * @return the network subtype
    186      */
    187     public int getSubtype() {
    188         synchronized (this) {
    189             return mSubtype;
    190         }
    191     }
    192 
    193     void setSubtype(int subtype, String subtypeName) {
    194         synchronized (this) {
    195             mSubtype = subtype;
    196             mSubtypeName = subtypeName;
    197         }
    198     }
    199 
    200     /**
    201      * Return a human-readable name describe the type of the network,
    202      * for example "WIFI" or "MOBILE".
    203      * @return the name of the network type
    204      */
    205     public String getTypeName() {
    206         synchronized (this) {
    207             return mTypeName;
    208         }
    209     }
    210 
    211     /**
    212      * Return a human-readable name describing the subtype of the network.
    213      * @return the name of the network subtype
    214      */
    215     public String getSubtypeName() {
    216         synchronized (this) {
    217             return mSubtypeName;
    218         }
    219     }
    220 
    221     /**
    222      * Indicates whether network connectivity exists or is in the process
    223      * of being established. This is good for applications that need to
    224      * do anything related to the network other than read or write data.
    225      * For the latter, call {@link #isConnected()} instead, which guarantees
    226      * that the network is fully usable.
    227      * @return {@code true} if network connectivity exists or is in the process
    228      * of being established, {@code false} otherwise.
    229      */
    230     public boolean isConnectedOrConnecting() {
    231         synchronized (this) {
    232             return mState == State.CONNECTED || mState == State.CONNECTING;
    233         }
    234     }
    235 
    236     /**
    237      * Indicates whether network connectivity exists and it is possible to establish
    238      * connections and pass data.
    239      * <p>Always call this before attempting to perform data transactions.
    240      * @return {@code true} if network connectivity exists, {@code false} otherwise.
    241      */
    242     public boolean isConnected() {
    243         synchronized (this) {
    244             return mState == State.CONNECTED;
    245         }
    246     }
    247 
    248     /**
    249      * Indicates whether network connectivity is possible. A network is unavailable
    250      * when a persistent or semi-persistent condition prevents the possibility
    251      * of connecting to that network. Examples include
    252      * <ul>
    253      * <li>The device is out of the coverage area for any network of this type.</li>
    254      * <li>The device is on a network other than the home network (i.e., roaming), and
    255      * data roaming has been disabled.</li>
    256      * <li>The device's radio is turned off, e.g., because airplane mode is enabled.</li>
    257      * </ul>
    258      * @return {@code true} if the network is available, {@code false} otherwise
    259      */
    260     public boolean isAvailable() {
    261         synchronized (this) {
    262             return mIsAvailable;
    263         }
    264     }
    265 
    266     /**
    267      * Sets if the network is available, ie, if the connectivity is possible.
    268      * @param isAvailable the new availability value.
    269      *
    270      * @hide
    271      */
    272     public void setIsAvailable(boolean isAvailable) {
    273         synchronized (this) {
    274             mIsAvailable = isAvailable;
    275         }
    276     }
    277 
    278     /**
    279      * Indicates whether the current attempt to connect to the network
    280      * resulted from the ConnectivityManager trying to fail over to this
    281      * network following a disconnect from another network.
    282      * @return {@code true} if this is a failover attempt, {@code false}
    283      * otherwise.
    284      */
    285     public boolean isFailover() {
    286         synchronized (this) {
    287             return mIsFailover;
    288         }
    289     }
    290 
    291     /**
    292      * Set the failover boolean.
    293      * @param isFailover {@code true} to mark the current connection attempt
    294      * as a failover.
    295      * @hide
    296      */
    297     public void setFailover(boolean isFailover) {
    298         synchronized (this) {
    299             mIsFailover = isFailover;
    300         }
    301     }
    302 
    303     /**
    304      * Indicates whether the device is currently roaming on this network.
    305      * When {@code true}, it suggests that use of data on this network
    306      * may incur extra costs.
    307      * @return {@code true} if roaming is in effect, {@code false} otherwise.
    308      */
    309     public boolean isRoaming() {
    310         synchronized (this) {
    311             return mIsRoaming;
    312         }
    313     }
    314 
    315     void setRoaming(boolean isRoaming) {
    316         synchronized (this) {
    317             mIsRoaming = isRoaming;
    318         }
    319     }
    320 
    321     /**
    322      * Reports the current coarse-grained state of the network.
    323      * @return the coarse-grained state
    324      */
    325     public State getState() {
    326         synchronized (this) {
    327             return mState;
    328         }
    329     }
    330 
    331     /**
    332      * Reports the current fine-grained state of the network.
    333      * @return the fine-grained state
    334      */
    335     public DetailedState getDetailedState() {
    336         synchronized (this) {
    337             return mDetailedState;
    338         }
    339     }
    340 
    341     /**
    342      * Sets the fine-grained state of the network.
    343      * @param detailedState the {@link DetailedState}.
    344      * @param reason a {@code String} indicating the reason for the state change,
    345      * if one was supplied. May be {@code null}.
    346      * @param extraInfo an optional {@code String} providing addditional network state
    347      * information passed up from the lower networking layers.
    348      * @hide
    349      */
    350     public void setDetailedState(DetailedState detailedState, String reason, String extraInfo) {
    351         synchronized (this) {
    352             this.mDetailedState = detailedState;
    353             this.mState = stateMap.get(detailedState);
    354             this.mReason = reason;
    355             this.mExtraInfo = extraInfo;
    356         }
    357     }
    358 
    359     /**
    360      * Set the extraInfo field.
    361      * @param extraInfo an optional {@code String} providing addditional network state
    362      * information passed up from the lower networking layers.
    363      * @hide
    364      */
    365     public void setExtraInfo(String extraInfo) {
    366         synchronized (this) {
    367             this.mExtraInfo = extraInfo;
    368         }
    369     }
    370 
    371     /**
    372      * Report the reason an attempt to establish connectivity failed,
    373      * if one is available.
    374      * @return the reason for failure, or null if not available
    375      */
    376     public String getReason() {
    377         synchronized (this) {
    378             return mReason;
    379         }
    380     }
    381 
    382     /**
    383      * Report the extra information about the network state, if any was
    384      * provided by the lower networking layers.,
    385      * if one is available.
    386      * @return the extra information, or null if not available
    387      */
    388     public String getExtraInfo() {
    389         synchronized (this) {
    390             return mExtraInfo;
    391         }
    392     }
    393 
    394     @Override
    395     public String toString() {
    396         synchronized (this) {
    397             StringBuilder builder = new StringBuilder("NetworkInfo: ");
    398             builder.append("type: ").append(getTypeName()).append("[").append(getSubtypeName()).
    399             append("], state: ").append(mState).append("/").append(mDetailedState).
    400             append(", reason: ").append(mReason == null ? "(unspecified)" : mReason).
    401             append(", extra: ").append(mExtraInfo == null ? "(none)" : mExtraInfo).
    402             append(", roaming: ").append(mIsRoaming).
    403             append(", failover: ").append(mIsFailover).
    404             append(", isAvailable: ").append(mIsAvailable);
    405             return builder.toString();
    406         }
    407     }
    408 
    409     /**
    410      * Implement the Parcelable interface
    411      * @hide
    412      */
    413     public int describeContents() {
    414         return 0;
    415     }
    416 
    417     /**
    418      * Implement the Parcelable interface.
    419      * @hide
    420      */
    421     public void writeToParcel(Parcel dest, int flags) {
    422         synchronized (this) {
    423             dest.writeInt(mNetworkType);
    424             dest.writeInt(mSubtype);
    425             dest.writeString(mTypeName);
    426             dest.writeString(mSubtypeName);
    427             dest.writeString(mState.name());
    428             dest.writeString(mDetailedState.name());
    429             dest.writeInt(mIsFailover ? 1 : 0);
    430             dest.writeInt(mIsAvailable ? 1 : 0);
    431             dest.writeInt(mIsRoaming ? 1 : 0);
    432             dest.writeString(mReason);
    433             dest.writeString(mExtraInfo);
    434         }
    435     }
    436 
    437     /**
    438      * Implement the Parcelable interface.
    439      * @hide
    440      */
    441     public static final Creator<NetworkInfo> CREATOR =
    442         new Creator<NetworkInfo>() {
    443             public NetworkInfo createFromParcel(Parcel in) {
    444                 int netType = in.readInt();
    445                 int subtype = in.readInt();
    446                 String typeName = in.readString();
    447                 String subtypeName = in.readString();
    448                 NetworkInfo netInfo = new NetworkInfo(netType, subtype, typeName, subtypeName);
    449                 netInfo.mState = State.valueOf(in.readString());
    450                 netInfo.mDetailedState = DetailedState.valueOf(in.readString());
    451                 netInfo.mIsFailover = in.readInt() != 0;
    452                 netInfo.mIsAvailable = in.readInt() != 0;
    453                 netInfo.mIsRoaming = in.readInt() != 0;
    454                 netInfo.mReason = in.readString();
    455                 netInfo.mExtraInfo = in.readString();
    456                 return netInfo;
    457             }
    458 
    459             public NetworkInfo[] newArray(int size) {
    460                 return new NetworkInfo[size];
    461             }
    462         };
    463 }
    464