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