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.Parcel; 20 import android.os.Parcelable; 21 22 import com.android.internal.annotations.VisibleForTesting; 23 24 import java.util.EnumMap; 25 26 /** 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. 30 */ 31 public class NetworkInfo implements Parcelable { 32 33 /** 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: 37 * <br/><br/> 38 * <table> 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>DISCONNECTED</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>OBTAINING_IPADDR</code></td><td><code>CONNECTING</code></td></tr> 45 * <tr><td><code>VERIFYING_POOR_LINK</code></td><td><code>CONNECTING</code></td></tr> 46 * <tr><td><code>CAPTIVE_PORTAL_CHECK</code></td><td><code>CONNECTING</code></td></tr> 47 * <tr><td><code>CONNECTED</code></td><td><code>CONNECTED</code></td></tr> 48 * <tr><td><code>SUSPENDED</code></td><td><code>SUSPENDED</code></td></tr> 49 * <tr><td><code>DISCONNECTING</code></td><td><code>DISCONNECTING</code></td></tr> 50 * <tr><td><code>DISCONNECTED</code></td><td><code>DISCONNECTED</code></td></tr> 51 * <tr><td><code>FAILED</code></td><td><code>DISCONNECTED</code></td></tr> 52 * <tr><td><code>BLOCKED</code></td><td><code>DISCONNECTED</code></td></tr> 53 * </table> 54 */ 55 public enum State { 56 CONNECTING, CONNECTED, SUSPENDED, DISCONNECTING, DISCONNECTED, UNKNOWN 57 } 58 59 /** 60 * The fine-grained state of a network connection. This level of detail 61 * is probably of interest to few applications. Most should use 62 * {@link android.net.NetworkInfo.State State} instead. 63 */ 64 public enum DetailedState { 65 /** Ready to start data connection setup. */ 66 IDLE, 67 /** Searching for an available access point. */ 68 SCANNING, 69 /** Currently setting up data connection. */ 70 CONNECTING, 71 /** Network link established, performing authentication. */ 72 AUTHENTICATING, 73 /** Awaiting response from DHCP server in order to assign IP address information. */ 74 OBTAINING_IPADDR, 75 /** IP traffic should be available. */ 76 CONNECTED, 77 /** IP traffic is suspended */ 78 SUSPENDED, 79 /** Currently tearing down data connection. */ 80 DISCONNECTING, 81 /** IP traffic not available. */ 82 DISCONNECTED, 83 /** Attempt to connect failed. */ 84 FAILED, 85 /** Access to this network is blocked. */ 86 BLOCKED, 87 /** Link has poor connectivity. */ 88 VERIFYING_POOR_LINK, 89 /** Checking if network is a captive portal */ 90 CAPTIVE_PORTAL_CHECK 91 } 92 93 /** 94 * This is the map described in the Javadoc comment above. The positions 95 * of the elements of the array must correspond to the ordinal values 96 * of <code>DetailedState</code>. 97 */ 98 private static final EnumMap<DetailedState, State> stateMap = 99 new EnumMap<DetailedState, State>(DetailedState.class); 100 101 static { stateMap.put(DetailedState.IDLE, State.DISCONNECTED)102 stateMap.put(DetailedState.IDLE, State.DISCONNECTED); stateMap.put(DetailedState.SCANNING, State.DISCONNECTED)103 stateMap.put(DetailedState.SCANNING, State.DISCONNECTED); stateMap.put(DetailedState.CONNECTING, State.CONNECTING)104 stateMap.put(DetailedState.CONNECTING, State.CONNECTING); stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING)105 stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING); stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING)106 stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING); stateMap.put(DetailedState.VERIFYING_POOR_LINK, State.CONNECTING)107 stateMap.put(DetailedState.VERIFYING_POOR_LINK, State.CONNECTING); stateMap.put(DetailedState.CAPTIVE_PORTAL_CHECK, State.CONNECTING)108 stateMap.put(DetailedState.CAPTIVE_PORTAL_CHECK, State.CONNECTING); stateMap.put(DetailedState.CONNECTED, State.CONNECTED)109 stateMap.put(DetailedState.CONNECTED, State.CONNECTED); stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED)110 stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED); stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING)111 stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING); stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED)112 stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED); stateMap.put(DetailedState.FAILED, State.DISCONNECTED)113 stateMap.put(DetailedState.FAILED, State.DISCONNECTED); stateMap.put(DetailedState.BLOCKED, State.DISCONNECTED)114 stateMap.put(DetailedState.BLOCKED, State.DISCONNECTED); 115 } 116 117 private int mNetworkType; 118 private int mSubtype; 119 private String mTypeName; 120 private String mSubtypeName; 121 private State mState; 122 private DetailedState mDetailedState; 123 private String mReason; 124 private String mExtraInfo; 125 private boolean mIsFailover; 126 private boolean mIsAvailable; 127 private boolean mIsRoaming; 128 129 /** 130 * @hide 131 */ NetworkInfo(int type, int subtype, String typeName, String subtypeName)132 public NetworkInfo(int type, int subtype, String typeName, String subtypeName) { 133 if (!ConnectivityManager.isNetworkTypeValid(type) 134 && type != ConnectivityManager.TYPE_NONE) { 135 throw new IllegalArgumentException("Invalid network type: " + type); 136 } 137 mNetworkType = type; 138 mSubtype = subtype; 139 mTypeName = typeName; 140 mSubtypeName = subtypeName; 141 setDetailedState(DetailedState.IDLE, null, null); 142 mState = State.UNKNOWN; 143 } 144 145 /** {@hide} */ NetworkInfo(NetworkInfo source)146 public NetworkInfo(NetworkInfo source) { 147 if (source != null) { 148 synchronized (source) { 149 mNetworkType = source.mNetworkType; 150 mSubtype = source.mSubtype; 151 mTypeName = source.mTypeName; 152 mSubtypeName = source.mSubtypeName; 153 mState = source.mState; 154 mDetailedState = source.mDetailedState; 155 mReason = source.mReason; 156 mExtraInfo = source.mExtraInfo; 157 mIsFailover = source.mIsFailover; 158 mIsAvailable = source.mIsAvailable; 159 mIsRoaming = source.mIsRoaming; 160 } 161 } 162 } 163 164 /** 165 * Reports the type of network to which the 166 * info in this {@code NetworkInfo} pertains. 167 * @return one of {@link ConnectivityManager#TYPE_MOBILE}, {@link 168 * ConnectivityManager#TYPE_WIFI}, {@link ConnectivityManager#TYPE_WIMAX}, {@link 169 * ConnectivityManager#TYPE_ETHERNET}, {@link ConnectivityManager#TYPE_BLUETOOTH}, or other 170 * types defined by {@link ConnectivityManager}. 171 * @deprecated Callers should switch to checking {@link NetworkCapabilities#hasTransport} 172 * instead with one of the NetworkCapabilities#TRANSPORT_* constants : 173 * {@link #getType} and {@link #getTypeName} cannot account for networks using 174 * multiple transports. Note that generally apps should not care about transport; 175 * {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED} and 176 * {@link NetworkCapabilities#getLinkDownstreamBandwidthKbps} are calls that 177 * apps concerned with meteredness or bandwidth should be looking at, as they 178 * offer this information with much better accuracy. 179 */ 180 @Deprecated getType()181 public int getType() { 182 synchronized (this) { 183 return mNetworkType; 184 } 185 } 186 187 /** 188 * @deprecated Use {@link NetworkCapabilities} instead 189 * @hide 190 */ 191 @Deprecated setType(int type)192 public void setType(int type) { 193 synchronized (this) { 194 mNetworkType = type; 195 } 196 } 197 198 /** 199 * Return a network-type-specific integer describing the subtype 200 * of the network. 201 * @return the network subtype 202 */ getSubtype()203 public int getSubtype() { 204 synchronized (this) { 205 return mSubtype; 206 } 207 } 208 209 /** 210 * @hide 211 */ setSubtype(int subtype, String subtypeName)212 public void setSubtype(int subtype, String subtypeName) { 213 synchronized (this) { 214 mSubtype = subtype; 215 mSubtypeName = subtypeName; 216 } 217 } 218 219 /** 220 * Return a human-readable name describe the type of the network, 221 * for example "WIFI" or "MOBILE". 222 * @return the name of the network type 223 * @deprecated Callers should switch to checking {@link NetworkCapabilities#hasTransport} 224 * instead with one of the NetworkCapabilities#TRANSPORT_* constants : 225 * {@link #getType} and {@link #getTypeName} cannot account for networks using 226 * multiple transports. Note that generally apps should not care about transport; 227 * {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED} and 228 * {@link NetworkCapabilities#getLinkDownstreamBandwidthKbps} are calls that 229 * apps concerned with meteredness or bandwidth should be looking at, as they 230 * offer this information with much better accuracy. 231 */ 232 @Deprecated getTypeName()233 public String getTypeName() { 234 synchronized (this) { 235 return mTypeName; 236 } 237 } 238 239 /** 240 * Return a human-readable name describing the subtype of the network. 241 * @return the name of the network subtype 242 */ getSubtypeName()243 public String getSubtypeName() { 244 synchronized (this) { 245 return mSubtypeName; 246 } 247 } 248 249 /** 250 * Indicates whether network connectivity exists or is in the process 251 * of being established. This is good for applications that need to 252 * do anything related to the network other than read or write data. 253 * For the latter, call {@link #isConnected()} instead, which guarantees 254 * that the network is fully usable. 255 * @return {@code true} if network connectivity exists or is in the process 256 * of being established, {@code false} otherwise. 257 * @deprecated Apps should instead use the 258 * {@link android.net.ConnectivityManager.NetworkCallback} API to 259 * learn about connectivity changes. 260 * {@link ConnectivityManager#registerDefaultNetworkCallback} and 261 * {@link ConnectivityManager#registerNetworkCallback}. These will 262 * give a more accurate picture of the connectivity state of 263 * the device and let apps react more easily and quickly to changes. 264 */ 265 @Deprecated isConnectedOrConnecting()266 public boolean isConnectedOrConnecting() { 267 synchronized (this) { 268 return mState == State.CONNECTED || mState == State.CONNECTING; 269 } 270 } 271 272 /** 273 * Indicates whether network connectivity exists and it is possible to establish 274 * connections and pass data. 275 * <p>Always call this before attempting to perform data transactions. 276 * @return {@code true} if network connectivity exists, {@code false} otherwise. 277 */ isConnected()278 public boolean isConnected() { 279 synchronized (this) { 280 return mState == State.CONNECTED; 281 } 282 } 283 284 /** 285 * Indicates whether network connectivity is possible. A network is unavailable 286 * when a persistent or semi-persistent condition prevents the possibility 287 * of connecting to that network. Examples include 288 * <ul> 289 * <li>The device is out of the coverage area for any network of this type.</li> 290 * <li>The device is on a network other than the home network (i.e., roaming), and 291 * data roaming has been disabled.</li> 292 * <li>The device's radio is turned off, e.g., because airplane mode is enabled.</li> 293 * </ul> 294 * Since Android L, this always returns {@code true}, because the system only 295 * returns info for available networks. 296 * @return {@code true} if the network is available, {@code false} otherwise 297 * @deprecated Apps should instead use the 298 * {@link android.net.ConnectivityManager.NetworkCallback} API to 299 * learn about connectivity changes. 300 * {@link ConnectivityManager#registerDefaultNetworkCallback} and 301 * {@link ConnectivityManager#registerNetworkCallback}. These will 302 * give a more accurate picture of the connectivity state of 303 * the device and let apps react more easily and quickly to changes. 304 */ 305 @Deprecated isAvailable()306 public boolean isAvailable() { 307 synchronized (this) { 308 return mIsAvailable; 309 } 310 } 311 312 /** 313 * Sets if the network is available, ie, if the connectivity is possible. 314 * @param isAvailable the new availability value. 315 * @deprecated Use {@link NetworkCapabilities} instead 316 * 317 * @hide 318 */ 319 @Deprecated setIsAvailable(boolean isAvailable)320 public void setIsAvailable(boolean isAvailable) { 321 synchronized (this) { 322 mIsAvailable = isAvailable; 323 } 324 } 325 326 /** 327 * Indicates whether the current attempt to connect to the network 328 * resulted from the ConnectivityManager trying to fail over to this 329 * network following a disconnect from another network. 330 * @return {@code true} if this is a failover attempt, {@code false} 331 * otherwise. 332 * @deprecated This field is not populated in recent Android releases, 333 * and does not make a lot of sense in a multi-network world. 334 */ 335 @Deprecated isFailover()336 public boolean isFailover() { 337 synchronized (this) { 338 return mIsFailover; 339 } 340 } 341 342 /** 343 * Set the failover boolean. 344 * @param isFailover {@code true} to mark the current connection attempt 345 * as a failover. 346 * @deprecated This hasn't been set in any recent Android release. 347 * @hide 348 */ 349 @Deprecated setFailover(boolean isFailover)350 public void setFailover(boolean isFailover) { 351 synchronized (this) { 352 mIsFailover = isFailover; 353 } 354 } 355 356 /** 357 * Indicates whether the device is currently roaming on this network. When 358 * {@code true}, it suggests that use of data on this network may incur 359 * extra costs. 360 * 361 * @return {@code true} if roaming is in effect, {@code false} otherwise. 362 * @deprecated Callers should switch to checking 363 * {@link NetworkCapabilities#NET_CAPABILITY_NOT_ROAMING} 364 * instead, since that handles more complex situations, such as 365 * VPNs. 366 */ 367 @Deprecated isRoaming()368 public boolean isRoaming() { 369 synchronized (this) { 370 return mIsRoaming; 371 } 372 } 373 374 /** 375 * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_NOT_ROAMING} instead. 376 * {@hide} 377 */ 378 @VisibleForTesting 379 @Deprecated setRoaming(boolean isRoaming)380 public void setRoaming(boolean isRoaming) { 381 synchronized (this) { 382 mIsRoaming = isRoaming; 383 } 384 } 385 386 /** 387 * Reports the current coarse-grained state of the network. 388 * @return the coarse-grained state 389 * @deprecated Apps should instead use the 390 * {@link android.net.ConnectivityManager.NetworkCallback} API to 391 * learn about connectivity changes. 392 * {@link ConnectivityManager#registerDefaultNetworkCallback} and 393 * {@link ConnectivityManager#registerNetworkCallback}. These will 394 * give a more accurate picture of the connectivity state of 395 * the device and let apps react more easily and quickly to changes. 396 */ 397 @Deprecated getState()398 public State getState() { 399 synchronized (this) { 400 return mState; 401 } 402 } 403 404 /** 405 * Reports the current fine-grained state of the network. 406 * @return the fine-grained state 407 */ getDetailedState()408 public DetailedState getDetailedState() { 409 synchronized (this) { 410 return mDetailedState; 411 } 412 } 413 414 /** 415 * Sets the fine-grained state of the network. 416 * @param detailedState the {@link DetailedState}. 417 * @param reason a {@code String} indicating the reason for the state change, 418 * if one was supplied. May be {@code null}. 419 * @param extraInfo an optional {@code String} providing addditional network state 420 * information passed up from the lower networking layers. 421 * @deprecated Use {@link NetworkCapabilities} instead. 422 * @hide 423 */ 424 @Deprecated setDetailedState(DetailedState detailedState, String reason, String extraInfo)425 public void setDetailedState(DetailedState detailedState, String reason, String extraInfo) { 426 synchronized (this) { 427 this.mDetailedState = detailedState; 428 this.mState = stateMap.get(detailedState); 429 this.mReason = reason; 430 this.mExtraInfo = extraInfo; 431 } 432 } 433 434 /** 435 * Set the extraInfo field. 436 * @param extraInfo an optional {@code String} providing addditional network state 437 * information passed up from the lower networking layers. 438 * @hide 439 */ setExtraInfo(String extraInfo)440 public void setExtraInfo(String extraInfo) { 441 synchronized (this) { 442 this.mExtraInfo = extraInfo; 443 } 444 } 445 446 /** 447 * Report the reason an attempt to establish connectivity failed, 448 * if one is available. 449 * @return the reason for failure, or null if not available 450 * @deprecated This method does not have a consistent contract that could make it useful 451 * to callers. 452 */ getReason()453 public String getReason() { 454 synchronized (this) { 455 return mReason; 456 } 457 } 458 459 /** 460 * Report the extra information about the network state, if any was 461 * provided by the lower networking layers. 462 * @return the extra information, or null if not available 463 */ getExtraInfo()464 public String getExtraInfo() { 465 synchronized (this) { 466 return mExtraInfo; 467 } 468 } 469 470 @Override toString()471 public String toString() { 472 synchronized (this) { 473 StringBuilder builder = new StringBuilder("["); 474 builder.append("type: ").append(getTypeName()).append("[").append(getSubtypeName()). 475 append("], state: ").append(mState).append("/").append(mDetailedState). 476 append(", reason: ").append(mReason == null ? "(unspecified)" : mReason). 477 append(", extra: ").append(mExtraInfo == null ? "(none)" : mExtraInfo). 478 append(", failover: ").append(mIsFailover). 479 append(", available: ").append(mIsAvailable). 480 append(", roaming: ").append(mIsRoaming). 481 append("]"); 482 return builder.toString(); 483 } 484 } 485 486 @Override describeContents()487 public int describeContents() { 488 return 0; 489 } 490 491 @Override writeToParcel(Parcel dest, int flags)492 public void writeToParcel(Parcel dest, int flags) { 493 synchronized (this) { 494 dest.writeInt(mNetworkType); 495 dest.writeInt(mSubtype); 496 dest.writeString(mTypeName); 497 dest.writeString(mSubtypeName); 498 dest.writeString(mState.name()); 499 dest.writeString(mDetailedState.name()); 500 dest.writeInt(mIsFailover ? 1 : 0); 501 dest.writeInt(mIsAvailable ? 1 : 0); 502 dest.writeInt(mIsRoaming ? 1 : 0); 503 dest.writeString(mReason); 504 dest.writeString(mExtraInfo); 505 } 506 } 507 508 public static final Creator<NetworkInfo> CREATOR = new Creator<NetworkInfo>() { 509 @Override 510 public NetworkInfo createFromParcel(Parcel in) { 511 int netType = in.readInt(); 512 int subtype = in.readInt(); 513 String typeName = in.readString(); 514 String subtypeName = in.readString(); 515 NetworkInfo netInfo = new NetworkInfo(netType, subtype, typeName, subtypeName); 516 netInfo.mState = State.valueOf(in.readString()); 517 netInfo.mDetailedState = DetailedState.valueOf(in.readString()); 518 netInfo.mIsFailover = in.readInt() != 0; 519 netInfo.mIsAvailable = in.readInt() != 0; 520 netInfo.mIsRoaming = in.readInt() != 0; 521 netInfo.mReason = in.readString(); 522 netInfo.mExtraInfo = in.readString(); 523 return netInfo; 524 } 525 526 @Override 527 public NetworkInfo[] newArray(int size) { 528 return new NetworkInfo[size]; 529 } 530 }; 531 } 532