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