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 this network is suspended. 338 * @deprecated Apps should instead use the 339 * {@link android.net.ConnectivityManager.NetworkCallback} API to 340 * learn about connectivity changes. See 341 * {@link ConnectivityManager#registerDefaultNetworkCallback} and 342 * {@link ConnectivityManager#registerNetworkCallback}. These will 343 * give a more accurate picture of the connectivity state of 344 * the device and let apps react more easily and quickly to changes. 345 * @hide 346 */ 347 @Deprecated isSuspended()348 public boolean isSuspended() { 349 synchronized (this) { 350 return mState == State.SUSPENDED; 351 } 352 } 353 354 /** 355 * Indicates whether network connectivity is possible. A network is unavailable 356 * when a persistent or semi-persistent condition prevents the possibility 357 * of connecting to that network. Examples include 358 * <ul> 359 * <li>The device is out of the coverage area for any network of this type.</li> 360 * <li>The device is on a network other than the home network (i.e., roaming), and 361 * data roaming has been disabled.</li> 362 * <li>The device's radio is turned off, e.g., because airplane mode is enabled.</li> 363 * </ul> 364 * Since Android L, this always returns {@code true}, because the system only 365 * returns info for available networks. 366 * @return {@code true} if the network is available, {@code false} otherwise 367 * @deprecated Apps should instead use the 368 * {@link android.net.ConnectivityManager.NetworkCallback} API to 369 * learn about connectivity changes. 370 * {@link ConnectivityManager#registerDefaultNetworkCallback} and 371 * {@link ConnectivityManager#registerNetworkCallback}. These will 372 * give a more accurate picture of the connectivity state of 373 * the device and let apps react more easily and quickly to changes. 374 */ 375 @Deprecated isAvailable()376 public boolean isAvailable() { 377 synchronized (this) { 378 return mIsAvailable; 379 } 380 } 381 382 /** 383 * Sets if the network is available, ie, if the connectivity is possible. 384 * @param isAvailable the new availability value. 385 * @deprecated Use {@link NetworkCapabilities} instead 386 * 387 * @hide 388 */ 389 @Deprecated 390 @UnsupportedAppUsage setIsAvailable(boolean isAvailable)391 public void setIsAvailable(boolean isAvailable) { 392 synchronized (this) { 393 mIsAvailable = isAvailable; 394 } 395 } 396 397 /** 398 * Indicates whether the current attempt to connect to the network 399 * resulted from the ConnectivityManager trying to fail over to this 400 * network following a disconnect from another network. 401 * @return {@code true} if this is a failover attempt, {@code false} 402 * otherwise. 403 * @deprecated This field is not populated in recent Android releases, 404 * and does not make a lot of sense in a multi-network world. 405 */ 406 @Deprecated isFailover()407 public boolean isFailover() { 408 synchronized (this) { 409 return mIsFailover; 410 } 411 } 412 413 /** 414 * Set the failover boolean. 415 * @param isFailover {@code true} to mark the current connection attempt 416 * as a failover. 417 * @deprecated This hasn't been set in any recent Android release. 418 * @hide 419 */ 420 @Deprecated 421 @UnsupportedAppUsage setFailover(boolean isFailover)422 public void setFailover(boolean isFailover) { 423 synchronized (this) { 424 mIsFailover = isFailover; 425 } 426 } 427 428 /** 429 * Indicates whether the device is currently roaming on this network. When 430 * {@code true}, it suggests that use of data on this network may incur 431 * extra costs. 432 * 433 * @return {@code true} if roaming is in effect, {@code false} otherwise. 434 * @deprecated Callers should switch to checking 435 * {@link NetworkCapabilities#NET_CAPABILITY_NOT_ROAMING} 436 * instead, since that handles more complex situations, such as 437 * VPNs. 438 */ 439 @Deprecated isRoaming()440 public boolean isRoaming() { 441 synchronized (this) { 442 return mIsRoaming; 443 } 444 } 445 446 /** 447 * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_NOT_ROAMING} instead. 448 * {@hide} 449 */ 450 @VisibleForTesting 451 @Deprecated 452 @UnsupportedAppUsage setRoaming(boolean isRoaming)453 public void setRoaming(boolean isRoaming) { 454 synchronized (this) { 455 mIsRoaming = isRoaming; 456 } 457 } 458 459 /** 460 * Reports the current coarse-grained state of the network. 461 * @return the coarse-grained state 462 * @deprecated Apps should instead use the 463 * {@link android.net.ConnectivityManager.NetworkCallback} API to 464 * learn about connectivity changes. 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 getState()471 public State getState() { 472 synchronized (this) { 473 return mState; 474 } 475 } 476 477 /** 478 * Reports the current fine-grained state of the network. 479 * @return the fine-grained state 480 * @deprecated Apps should instead use the 481 * {@link android.net.ConnectivityManager.NetworkCallback} API to 482 * learn about connectivity changes. See 483 * {@link ConnectivityManager#registerDefaultNetworkCallback} and 484 * {@link ConnectivityManager#registerNetworkCallback}. These will 485 * give a more accurate picture of the connectivity state of 486 * the device and let apps react more easily and quickly to changes. 487 */ 488 @Deprecated getDetailedState()489 public @NonNull DetailedState getDetailedState() { 490 synchronized (this) { 491 return mDetailedState; 492 } 493 } 494 495 /** 496 * Sets the fine-grained state of the network. 497 * 498 * This is only useful for testing. 499 * 500 * @param detailedState the {@link DetailedState}. 501 * @param reason a {@code String} indicating the reason for the state change, 502 * if one was supplied. May be {@code null}. 503 * @param extraInfo an optional {@code String} providing additional network state 504 * information passed up from the lower networking layers. 505 * @deprecated Use {@link NetworkCapabilities} instead. 506 */ 507 @Deprecated setDetailedState(@onNull DetailedState detailedState, @Nullable String reason, @Nullable String extraInfo)508 public void setDetailedState(@NonNull DetailedState detailedState, @Nullable String reason, 509 @Nullable String extraInfo) { 510 synchronized (this) { 511 this.mDetailedState = detailedState; 512 this.mState = stateMap.get(detailedState); 513 this.mReason = reason; 514 this.mExtraInfo = extraInfo; 515 // Catch both the case where detailedState is null and the case where it's some 516 // unknown value. This is clearly incorrect usage, but S- didn't use to crash (at 517 // least immediately) so keep the old behavior on older frameworks for safety. 518 if (null == mState && SdkLevel.isAtLeastT()) { 519 throw new NullPointerException("Unknown DetailedState : " + detailedState); 520 } 521 } 522 } 523 524 /** 525 * Set the extraInfo field. 526 * @param extraInfo an optional {@code String} providing addditional network state 527 * information passed up from the lower networking layers. 528 * @deprecated See {@link NetworkInfo#getExtraInfo}. 529 * @hide 530 */ 531 @Deprecated setExtraInfo(String extraInfo)532 public void setExtraInfo(String extraInfo) { 533 synchronized (this) { 534 this.mExtraInfo = extraInfo; 535 } 536 } 537 538 /** 539 * Report the reason an attempt to establish connectivity failed, 540 * if one is available. 541 * @return the reason for failure, or null if not available 542 * @deprecated This method does not have a consistent contract that could make it useful 543 * to callers. 544 */ getReason()545 public String getReason() { 546 synchronized (this) { 547 return mReason; 548 } 549 } 550 551 /** 552 * Report the extra information about the network state, if any was 553 * provided by the lower networking layers. 554 * @return the extra information, or null if not available 555 * @deprecated Use other services e.g. WifiManager to get additional information passed up from 556 * the lower networking layers. 557 */ 558 @Deprecated getExtraInfo()559 public String getExtraInfo() { 560 synchronized (this) { 561 return mExtraInfo; 562 } 563 } 564 565 @Override toString()566 public String toString() { 567 synchronized (this) { 568 final StringBuilder builder = new StringBuilder("["); 569 builder.append("type: ").append(getTypeName()).append("[").append(getSubtypeName()). 570 append("], state: ").append(mState).append("/").append(mDetailedState). 571 append(", reason: ").append(mReason == null ? "(unspecified)" : mReason). 572 append(", extra: ").append(mExtraInfo == null ? "(none)" : mExtraInfo). 573 append(", failover: ").append(mIsFailover). 574 append(", available: ").append(mIsAvailable). 575 append(", roaming: ").append(mIsRoaming). 576 append("]"); 577 return builder.toString(); 578 } 579 } 580 581 /** 582 * Returns a brief summary string suitable for debugging. 583 * @hide 584 */ toShortString()585 public String toShortString() { 586 synchronized (this) { 587 final StringBuilder builder = new StringBuilder(); 588 builder.append(getTypeName()); 589 590 final String subtype = getSubtypeName(); 591 if (!TextUtils.isEmpty(subtype)) { 592 builder.append("[").append(subtype).append("]"); 593 } 594 595 builder.append(" "); 596 builder.append(mDetailedState); 597 if (mIsRoaming) { 598 builder.append(" ROAMING"); 599 } 600 if (mExtraInfo != null) { 601 builder.append(" extra: ").append(mExtraInfo); 602 } 603 return builder.toString(); 604 } 605 } 606 607 @Override describeContents()608 public int describeContents() { 609 return 0; 610 } 611 612 @Override writeToParcel(Parcel dest, int flags)613 public void writeToParcel(Parcel dest, int flags) { 614 synchronized (this) { 615 dest.writeInt(mNetworkType); 616 dest.writeInt(mSubtype); 617 dest.writeString(mTypeName); 618 dest.writeString(mSubtypeName); 619 dest.writeString(mState.name()); 620 dest.writeString(mDetailedState.name()); 621 dest.writeInt(mIsFailover ? 1 : 0); 622 dest.writeInt(mIsAvailable ? 1 : 0); 623 dest.writeInt(mIsRoaming ? 1 : 0); 624 dest.writeString(mReason); 625 dest.writeString(mExtraInfo); 626 } 627 } 628 629 public static final @android.annotation.NonNull Creator<NetworkInfo> CREATOR = new Creator<NetworkInfo>() { 630 @Override 631 public NetworkInfo createFromParcel(Parcel in) { 632 int netType = in.readInt(); 633 int subtype = in.readInt(); 634 String typeName = in.readString(); 635 String subtypeName = in.readString(); 636 NetworkInfo netInfo = new NetworkInfo(netType, subtype, typeName, subtypeName); 637 netInfo.mState = State.valueOf(in.readString()); 638 netInfo.mDetailedState = DetailedState.valueOf(in.readString()); 639 netInfo.mIsFailover = in.readInt() != 0; 640 netInfo.mIsAvailable = in.readInt() != 0; 641 netInfo.mIsRoaming = in.readInt() != 0; 642 netInfo.mReason = in.readString(); 643 netInfo.mExtraInfo = in.readString(); 644 return netInfo; 645 } 646 647 @Override 648 public NetworkInfo[] newArray(int size) { 649 return new NetworkInfo[size]; 650 } 651 }; 652 } 653