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