2 * Copyright (C) 2008 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 import android.os.Parcelable;
20 import android.os.Parcel;
22 import com.android.internal.annotations.VisibleForTesting;
24 import java.util.EnumMap;
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.
31 public class NetworkInfo implements Parcelable {
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:
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>
52 CONNECTING, CONNECTED, SUSPENDED, DISCONNECTING, DISCONNECTED, UNKNOWN
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.
60 public enum DetailedState {
61 /** Ready to start data connection setup. */
63 /** Searching for an available access point. */
65 /** Currently setting up data connection. */
67 /** Network link established, performing authentication. */
69 /** Awaiting response from DHCP server in order to assign IP address information. */
71 /** IP traffic should be available. */
73 /** IP traffic is suspended */
75 /** Currently tearing down data connection. */
77 /** IP traffic not available. */
79 /** Attempt to connect failed. */
81 /** Access to this network is blocked. */
83 /** Link has poor connectivity. */
85 /** Checking if network is a captive portal */
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>.
94 private static final EnumMap<DetailedState, State> stateMap =
95 new EnumMap<DetailedState, State>(DetailedState.class);
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);
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;
124 * Indicates whether network connectivity is possible:
126 private boolean mIsAvailable;
129 * @param type network type
131 * @hide because this constructor was only meant for internal use (and
132 * has now been superseded by the package-private constructor below).
134 public NetworkInfo(int type) {}
139 public NetworkInfo(int type, int subtype, String typeName, String subtypeName) {
140 if (!ConnectivityManager.isNetworkTypeValid(type)) {
141 throw new IllegalArgumentException("Invalid network type: " + type);
145 mTypeName = typeName;
146 mSubtypeName = subtypeName;
147 setDetailedState(DetailedState.IDLE, null, null);
148 mState = State.UNKNOWN;
149 mIsAvailable = false; // until we're told otherwise, assume unavailable
154 public NetworkInfo(NetworkInfo source) {
155 if (source != null) {
156 mNetworkType = source.mNetworkType;
157 mSubtype = source.mSubtype;
158 mTypeName = source.mTypeName;
159 mSubtypeName = source.mSubtypeName;
160 mState = source.mState;
161 mDetailedState = source.mDetailedState;
162 mReason = source.mReason;
163 mExtraInfo = source.mExtraInfo;
164 mIsFailover = source.mIsFailover;
165 mIsRoaming = source.mIsRoaming;
166 mIsAvailable = source.mIsAvailable;
171 * Reports the type of network to which the
172 * info in this {@code NetworkInfo} pertains.
173 * @return one of {@link ConnectivityManager#TYPE_MOBILE}, {@link
174 * ConnectivityManager#TYPE_WIFI}, {@link ConnectivityManager#TYPE_WIMAX}, {@link
175 * ConnectivityManager#TYPE_ETHERNET}, {@link ConnectivityManager#TYPE_BLUETOOTH}, or other
176 * types defined by {@link ConnectivityManager}
178 public int getType() {
179 synchronized (this) {
185 * Return a network-type-specific integer describing the subtype
187 * @return the network subtype
189 public int getSubtype() {
190 synchronized (this) {
195 void setSubtype(int subtype, String subtypeName) {
196 synchronized (this) {
198 mSubtypeName = subtypeName;
203 * Return a human-readable name describe the type of the network,
204 * for example "WIFI" or "MOBILE".
205 * @return the name of the network type
207 public String getTypeName() {
208 synchronized (this) {
214 * Return a human-readable name describing the subtype of the network.
215 * @return the name of the network subtype
217 public String getSubtypeName() {
218 synchronized (this) {
224 * Indicates whether network connectivity exists or is in the process
225 * of being established. This is good for applications that need to
226 * do anything related to the network other than read or write data.
227 * For the latter, call {@link #isConnected()} instead, which guarantees
228 * that the network is fully usable.
229 * @return {@code true} if network connectivity exists or is in the process
230 * of being established, {@code false} otherwise.
232 public boolean isConnectedOrConnecting() {
233 synchronized (this) {
234 return mState == State.CONNECTED || mState == State.CONNECTING;
239 * Indicates whether network connectivity exists and it is possible to establish
240 * connections and pass data.
241 * <p>Always call this before attempting to perform data transactions.
242 * @return {@code true} if network connectivity exists, {@code false} otherwise.
244 public boolean isConnected() {
245 synchronized (this) {
246 return mState == State.CONNECTED;
251 * Indicates whether network connectivity is possible. A network is unavailable
252 * when a persistent or semi-persistent condition prevents the possibility
253 * of connecting to that network. Examples include
255 * <li>The device is out of the coverage area for any network of this type.</li>
256 * <li>The device is on a network other than the home network (i.e., roaming), and
257 * data roaming has been disabled.</li>
258 * <li>The device's radio is turned off, e.g., because airplane mode is enabled.</li>
260 * @return {@code true} if the network is available, {@code false} otherwise
262 public boolean isAvailable() {
263 synchronized (this) {
269 * Sets if the network is available, ie, if the connectivity is possible.
270 * @param isAvailable the new availability value.
274 public void setIsAvailable(boolean isAvailable) {
275 synchronized (this) {
276 mIsAvailable = isAvailable;
281 * Indicates whether the current attempt to connect to the network
282 * resulted from the ConnectivityManager trying to fail over to this
283 * network following a disconnect from another network.
284 * @return {@code true} if this is a failover attempt, {@code false}
287 public boolean isFailover() {
288 synchronized (this) {
294 * Set the failover boolean.
295 * @param isFailover {@code true} to mark the current connection attempt
299 public void setFailover(boolean isFailover) {
300 synchronized (this) {
301 mIsFailover = isFailover;
306 * Indicates whether the device is currently roaming on this network.
307 * When {@code true}, it suggests that use of data on this network
308 * may incur extra costs.
309 * @return {@code true} if roaming is in effect, {@code false} otherwise.
311 public boolean isRoaming() {
312 synchronized (this) {
319 public void setRoaming(boolean isRoaming) {
320 synchronized (this) {
321 mIsRoaming = isRoaming;
326 * Reports the current coarse-grained state of the network.
327 * @return the coarse-grained state
329 public State getState() {
330 synchronized (this) {
336 * Reports the current fine-grained state of the network.
337 * @return the fine-grained state
339 public DetailedState getDetailedState() {
340 synchronized (this) {
341 return mDetailedState;
346 * Sets the fine-grained state of the network.
347 * @param detailedState the {@link DetailedState}.
348 * @param reason a {@code String} indicating the reason for the state change,
349 * if one was supplied. May be {@code null}.
350 * @param extraInfo an optional {@code String} providing addditional network state
351 * information passed up from the lower networking layers.
354 public void setDetailedState(DetailedState detailedState, String reason, String extraInfo) {
355 synchronized (this) {
356 this.mDetailedState = detailedState;
357 this.mState = stateMap.get(detailedState);
358 this.mReason = reason;
359 this.mExtraInfo = extraInfo;
364 * Set the extraInfo field.
365 * @param extraInfo an optional {@code String} providing addditional network state
366 * information passed up from the lower networking layers.
369 public void setExtraInfo(String extraInfo) {
370 synchronized (this) {
371 this.mExtraInfo = extraInfo;
376 * Report the reason an attempt to establish connectivity failed,
377 * if one is available.
378 * @return the reason for failure, or null if not available
380 public String getReason() {
381 synchronized (this) {
387 * Report the extra information about the network state, if any was
388 * provided by the lower networking layers.,
389 * if one is available.
390 * @return the extra information, or null if not available
392 public String getExtraInfo() {
393 synchronized (this) {
399 public String toString() {
400 synchronized (this) {
401 StringBuilder builder = new StringBuilder("NetworkInfo: ");
402 builder.append("type: ").append(getTypeName()).append("[").append(getSubtypeName()).
403 append("], state: ").append(mState).append("/").append(mDetailedState).
404 append(", reason: ").append(mReason == null ? "(unspecified)" : mReason).
405 append(", extra: ").append(mExtraInfo == null ? "(none)" : mExtraInfo).
406 append(", roaming: ").append(mIsRoaming).
407 append(", failover: ").append(mIsFailover).
408 append(", isAvailable: ").append(mIsAvailable);
409 return builder.toString();
414 * Implement the Parcelable interface
417 public int describeContents() {
422 * Implement the Parcelable interface.
425 public void writeToParcel(Parcel dest, int flags) {
426 synchronized (this) {
427 dest.writeInt(mNetworkType);
428 dest.writeInt(mSubtype);
429 dest.writeString(mTypeName);
430 dest.writeString(mSubtypeName);
431 dest.writeString(mState.name());
432 dest.writeString(mDetailedState.name());
433 dest.writeInt(mIsFailover ? 1 : 0);
434 dest.writeInt(mIsAvailable ? 1 : 0);
435 dest.writeInt(mIsRoaming ? 1 : 0);
436 dest.writeString(mReason);
437 dest.writeString(mExtraInfo);
442 * Implement the Parcelable interface.
445 public static final Creator<NetworkInfo> CREATOR =
446 new Creator<NetworkInfo>() {
447 public NetworkInfo createFromParcel(Parcel in) {
448 int netType = in.readInt();
449 int subtype = in.readInt();
450 String typeName = in.readString();
451 String subtypeName = in.readString();
452 NetworkInfo netInfo = new NetworkInfo(netType, subtype, typeName, subtypeName);
453 netInfo.mState = State.valueOf(in.readString());
454 netInfo.mDetailedState = DetailedState.valueOf(in.readString());
455 netInfo.mIsFailover = in.readInt() != 0;
456 netInfo.mIsAvailable = in.readInt() != 0;
457 netInfo.mIsRoaming = in.readInt() != 0;
458 netInfo.mReason = in.readString();
459 netInfo.mExtraInfo = in.readString();
463 public NetworkInfo[] newArray(int size) {
464 return new NetworkInfo[size];