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