• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
stateMap.put(DetailedState.IDLE, State.DISCONNECTED)91         stateMap.put(DetailedState.IDLE, State.DISCONNECTED);
stateMap.put(DetailedState.SCANNING, State.DISCONNECTED)92         stateMap.put(DetailedState.SCANNING, State.DISCONNECTED);
stateMap.put(DetailedState.CONNECTING, State.CONNECTING)93         stateMap.put(DetailedState.CONNECTING, State.CONNECTING);
stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING)94         stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING);
stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING)95         stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING);
stateMap.put(DetailedState.CONNECTED, State.CONNECTED)96         stateMap.put(DetailedState.CONNECTED, State.CONNECTED);
stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED)97         stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED);
stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING)98         stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING);
stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED)99         stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED);
stateMap.put(DetailedState.FAILED, State.DISCONNECTED)100         stateMap.put(DetailedState.FAILED, State.DISCONNECTED);
stateMap.put(DetailedState.BLOCKED, 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      */
NetworkInfo(int type)125     public NetworkInfo(int type) {}
126 
127     /**
128      * @hide
129      */
NetworkInfo(int type, int subtype, String typeName, String subtypeName)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} */
NetworkInfo(NetworkInfo source)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      */
getType()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      */
getSubtype()177     public int getSubtype() {
178         synchronized (this) {
179             return mSubtype;
180         }
181     }
182 
setSubtype(int subtype, String subtypeName)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      */
getTypeName()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      */
getSubtypeName()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      */
isConnectedOrConnecting()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      */
isConnected()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      */
isAvailable()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      */
setIsAvailable(boolean isAvailable)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      */
isFailover()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      */
setFailover(boolean isFailover)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      */
isRoaming()298     public boolean isRoaming() {
299         synchronized (this) {
300             return mIsRoaming;
301         }
302     }
303 
setRoaming(boolean isRoaming)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      */
getState()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      */
getDetailedState()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      */
setDetailedState(DetailedState detailedState, String reason, String extraInfo)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      */
getReason()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      */
getExtraInfo()365     public String getExtraInfo() {
366         synchronized (this) {
367             return mExtraInfo;
368         }
369     }
370 
371     @Override
toString()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      */
describeContents()390     public int describeContents() {
391         return 0;
392     }
393 
394     /**
395      * Implement the Parcelable interface.
396      * @hide
397      */
writeToParcel(Parcel dest, int flags)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