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