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