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 { stateMap.put(DetailedState.IDLE, State.DISCONNECTED)96 stateMap.put(DetailedState.IDLE, State.DISCONNECTED); stateMap.put(DetailedState.SCANNING, State.DISCONNECTED)97 stateMap.put(DetailedState.SCANNING, State.DISCONNECTED); stateMap.put(DetailedState.CONNECTING, State.CONNECTING)98 stateMap.put(DetailedState.CONNECTING, State.CONNECTING); stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING)99 stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING); stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING)100 stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING); stateMap.put(DetailedState.VERIFYING_POOR_LINK, State.CONNECTING)101 stateMap.put(DetailedState.VERIFYING_POOR_LINK, State.CONNECTING); stateMap.put(DetailedState.CAPTIVE_PORTAL_CHECK, State.CONNECTING)102 stateMap.put(DetailedState.CAPTIVE_PORTAL_CHECK, State.CONNECTING); stateMap.put(DetailedState.CONNECTED, State.CONNECTED)103 stateMap.put(DetailedState.CONNECTED, State.CONNECTED); stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED)104 stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED); stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING)105 stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING); stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED)106 stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED); stateMap.put(DetailedState.FAILED, State.DISCONNECTED)107 stateMap.put(DetailedState.FAILED, State.DISCONNECTED); stateMap.put(DetailedState.BLOCKED, 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 */ NetworkInfo(int type)132 public NetworkInfo(int type) {} 133 134 /** 135 * @hide 136 */ NetworkInfo(int type, int subtype, String typeName, String subtypeName)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} */ NetworkInfo(NetworkInfo source)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 */ getType()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 */ getSubtype()187 public int getSubtype() { 188 synchronized (this) { 189 return mSubtype; 190 } 191 } 192 setSubtype(int subtype, String subtypeName)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 */ getTypeName()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 */ getSubtypeName()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 */ isConnectedOrConnecting()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 */ isConnected()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 */ isAvailable()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 */ setIsAvailable(boolean isAvailable)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 */ isFailover()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 */ setFailover(boolean isFailover)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 */ isRoaming()309 public boolean isRoaming() { 310 synchronized (this) { 311 return mIsRoaming; 312 } 313 } 314 setRoaming(boolean isRoaming)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 */ getState()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 */ getDetailedState()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 */ setDetailedState(DetailedState detailedState, String reason, String extraInfo)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 */ setExtraInfo(String extraInfo)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 */ getReason()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 */ getExtraInfo()388 public String getExtraInfo() { 389 synchronized (this) { 390 return mExtraInfo; 391 } 392 } 393 394 @Override toString()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 */ describeContents()413 public int describeContents() { 414 return 0; 415 } 416 417 /** 418 * Implement the Parcelable interface. 419 * @hide 420 */ writeToParcel(Parcel dest, int flags)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