NetworkInfo.java revision c006f1aec15454782c35e028ad64d79a5c161cc1
1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.net;
18
19import android.os.Parcelable;
20import android.os.Parcel;
21
22import java.util.EnumMap;
23
24/**
25 * Describes the status of a network interface of a given type
26 * (currently either Mobile or Wifi).
27 */
28public class NetworkInfo implements Parcelable {
29
30    /**
31     * Coarse-grained network state. This is probably what most applications should
32     * use, rather than {@link android.net.NetworkInfo.DetailedState DetailedState}.
33     * The mapping between the two is as follows:
34     * <br/><br/>
35     * <table>
36     * <tr><td><b>Detailed state</b></td><td><b>Coarse-grained state</b></td></tr>
37     * <tr><td><code>IDLE</code></td><td><code>DISCONNECTED</code></td></tr>
38     * <tr><td><code>SCANNING</code></td><td><code>CONNECTING</code></td></tr>
39     * <tr><td><code>CONNECTING</code></td><td><code>CONNECTING</code></td></tr>
40     * <tr><td><code>AUTHENTICATING</code></td><td><code>CONNECTING</code></td></tr>
41     * <tr><td><code>CONNECTED</code></td><td<code>CONNECTED</code></td></tr>
42     * <tr><td><code>DISCONNECTING</code></td><td><code>DISCONNECTING</code></td></tr>
43     * <tr><td><code>DISCONNECTED</code></td><td><code>DISCONNECTED</code></td></tr>
44     * <tr><td><code>UNAVAILABLE</code></td><td><code>DISCONNECTED</code></td></tr>
45     * <tr><td><code>FAILED</code></td><td><code>DISCONNECTED</code></td></tr>
46     * </table>
47     */
48    public enum State {
49        CONNECTING, CONNECTED, SUSPENDED, DISCONNECTING, DISCONNECTED, UNKNOWN
50    }
51
52    /**
53     * The fine-grained state of a network connection. This level of detail
54     * is probably of interest to few applications. Most should use
55     * {@link android.net.NetworkInfo.State State} instead.
56     */
57    public enum DetailedState {
58        /** Ready to start data connection setup. */
59        IDLE,
60        /** Searching for an available access point. */
61        SCANNING,
62        /** Currently setting up data connection. */
63        CONNECTING,
64        /** Network link established, performing authentication. */
65        AUTHENTICATING,
66        /** Awaiting response from DHCP server in order to assign IP address information. */
67        OBTAINING_IPADDR,
68        /** IP traffic should be available. */
69        CONNECTED,
70        /** IP traffic is suspended */
71        SUSPENDED,
72        /** Currently tearing down data connection. */
73        DISCONNECTING,
74        /** IP traffic not available. */
75        DISCONNECTED,
76        /** Attempt to connect failed. */
77        FAILED,
78        /** Access to this network is blocked. */
79        BLOCKED
80    }
81
82    /**
83     * This is the map described in the Javadoc comment above. The positions
84     * of the elements of the array must correspond to the ordinal values
85     * of <code>DetailedState</code>.
86     */
87    private static final EnumMap<DetailedState, State> stateMap =
88        new EnumMap<DetailedState, State>(DetailedState.class);
89
90    static {
91        stateMap.put(DetailedState.IDLE, State.DISCONNECTED);
92        stateMap.put(DetailedState.SCANNING, State.DISCONNECTED);
93        stateMap.put(DetailedState.CONNECTING, State.CONNECTING);
94        stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING);
95        stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING);
96        stateMap.put(DetailedState.CONNECTED, State.CONNECTED);
97        stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED);
98        stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING);
99        stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED);
100        stateMap.put(DetailedState.FAILED, State.DISCONNECTED);
101        stateMap.put(DetailedState.BLOCKED, State.DISCONNECTED);
102    }
103
104    private int mNetworkType;
105    private int mSubtype;
106    private String mTypeName;
107    private String mSubtypeName;
108    private State mState;
109    private DetailedState mDetailedState;
110    private String mReason;
111    private String mExtraInfo;
112    private boolean mIsFailover;
113    private boolean mIsRoaming;
114    /**
115     * Indicates whether network connectivity is possible:
116     */
117    private boolean mIsAvailable;
118
119    /**
120     * @param type network type
121     * @deprecated
122     * @hide because this constructor was only meant for internal use (and
123     * has now been superseded by the package-private constructor below).
124     */
125    public NetworkInfo(int type) {}
126
127    /**
128     * @hide
129     */
130    public NetworkInfo(int type, int subtype, String typeName, String subtypeName) {
131        if (!ConnectivityManager.isNetworkTypeValid(type)) {
132            throw new IllegalArgumentException("Invalid network type: " + type);
133        }
134        mNetworkType = type;
135        mSubtype = subtype;
136        mTypeName = typeName;
137        mSubtypeName = subtypeName;
138        setDetailedState(DetailedState.IDLE, null, null);
139        mState = State.UNKNOWN;
140        mIsAvailable = false; // until we're told otherwise, assume unavailable
141        mIsRoaming = false;
142    }
143
144    /** {@hide} */
145    public NetworkInfo(NetworkInfo source) {
146        if (source != null) {
147            mNetworkType = source.mNetworkType;
148            mSubtype = source.mSubtype;
149            mTypeName = source.mTypeName;
150            mSubtypeName = source.mSubtypeName;
151            mState = source.mState;
152            mDetailedState = source.mDetailedState;
153            mReason = source.mReason;
154            mExtraInfo = source.mExtraInfo;
155            mIsFailover = source.mIsFailover;
156            mIsRoaming = source.mIsRoaming;
157            mIsAvailable = source.mIsAvailable;
158        }
159    }
160
161    /**
162     * Reports the type of network (currently mobile or Wi-Fi) to which the
163     * info in this object pertains.
164     * @return the network type
165     */
166    public int getType() {
167        synchronized (this) {
168            return mNetworkType;
169        }
170    }
171
172    /**
173     * Return a network-type-specific integer describing the subtype
174     * of the network.
175     * @return the network subtype
176     */
177    public int getSubtype() {
178        synchronized (this) {
179            return mSubtype;
180        }
181    }
182
183    void setSubtype(int subtype, String subtypeName) {
184        synchronized (this) {
185            mSubtype = subtype;
186            mSubtypeName = subtypeName;
187        }
188    }
189
190    /**
191     * Return a human-readable name describe the type of the network,
192     * for example "WIFI" or "MOBILE".
193     * @return the name of the network type
194     */
195    public String getTypeName() {
196        synchronized (this) {
197            return mTypeName;
198        }
199    }
200
201    /**
202     * Return a human-readable name describing the subtype of the network.
203     * @return the name of the network subtype
204     */
205    public String getSubtypeName() {
206        synchronized (this) {
207            return mSubtypeName;
208        }
209    }
210
211    /**
212     * Indicates whether network connectivity exists or is in the process
213     * of being established. This is good for applications that need to
214     * do anything related to the network other than read or write data.
215     * For the latter, call {@link #isConnected()} instead, which guarantees
216     * that the network is fully usable.
217     * @return {@code true} if network connectivity exists or is in the process
218     * of being established, {@code false} otherwise.
219     */
220    public boolean isConnectedOrConnecting() {
221        synchronized (this) {
222            return mState == State.CONNECTED || mState == State.CONNECTING;
223        }
224    }
225
226    /**
227     * Indicates whether network connectivity exists and it is possible to establish
228     * connections and pass data.
229     * @return {@code true} if network connectivity exists, {@code false} otherwise.
230     */
231    public boolean isConnected() {
232        synchronized (this) {
233            return mState == State.CONNECTED;
234        }
235    }
236
237    /**
238     * Indicates whether network connectivity is possible. A network is unavailable
239     * when a persistent or semi-persistent condition prevents the possibility
240     * of connecting to that network. Examples include
241     * <ul>
242     * <li>The device is out of the coverage area for any network of this type.</li>
243     * <li>The device is on a network other than the home network (i.e., roaming), and
244     * data roaming has been disabled.</li>
245     * <li>The device's radio is turned off, e.g., because airplane mode is enabled.</li>
246     * </ul>
247     * @return {@code true} if the network is available, {@code false} otherwise
248     */
249    public boolean isAvailable() {
250        synchronized (this) {
251            return mIsAvailable;
252        }
253    }
254
255    /**
256     * Sets if the network is available, ie, if the connectivity is possible.
257     * @param isAvailable the new availability value.
258     *
259     * @hide
260     */
261    public void setIsAvailable(boolean isAvailable) {
262        synchronized (this) {
263            mIsAvailable = isAvailable;
264        }
265    }
266
267    /**
268     * Indicates whether the current attempt to connect to the network
269     * resulted from the ConnectivityManager trying to fail over to this
270     * network following a disconnect from another network.
271     * @return {@code true} if this is a failover attempt, {@code false}
272     * otherwise.
273     */
274    public boolean isFailover() {
275        synchronized (this) {
276            return mIsFailover;
277        }
278    }
279
280    /**
281     * Set the failover boolean.
282     * @param isFailover {@code true} to mark the current connection attempt
283     * as a failover.
284     * @hide
285     */
286    public void setFailover(boolean isFailover) {
287        synchronized (this) {
288            mIsFailover = isFailover;
289        }
290    }
291
292    /**
293     * Indicates whether the device is currently roaming on this network.
294     * When {@code true}, it suggests that use of data on this network
295     * may incur extra costs.
296     * @return {@code true} if roaming is in effect, {@code false} otherwise.
297     */
298    public boolean isRoaming() {
299        synchronized (this) {
300            return mIsRoaming;
301        }
302    }
303
304    void setRoaming(boolean isRoaming) {
305        synchronized (this) {
306            mIsRoaming = isRoaming;
307        }
308    }
309
310    /**
311     * Reports the current coarse-grained state of the network.
312     * @return the coarse-grained state
313     */
314    public State getState() {
315        synchronized (this) {
316            return mState;
317        }
318    }
319
320    /**
321     * Reports the current fine-grained state of the network.
322     * @return the fine-grained state
323     */
324    public DetailedState getDetailedState() {
325        synchronized (this) {
326            return mDetailedState;
327        }
328    }
329
330    /**
331     * Sets the fine-grained state of the network.
332     * @param detailedState the {@link DetailedState}.
333     * @param reason a {@code String} indicating the reason for the state change,
334     * if one was supplied. May be {@code null}.
335     * @param extraInfo an optional {@code String} providing addditional network state
336     * information passed up from the lower networking layers.
337     * @hide
338     */
339    public void setDetailedState(DetailedState detailedState, String reason, String extraInfo) {
340        synchronized (this) {
341            this.mDetailedState = detailedState;
342            this.mState = stateMap.get(detailedState);
343            this.mReason = reason;
344            this.mExtraInfo = extraInfo;
345        }
346    }
347
348    /**
349     * Report the reason an attempt to establish connectivity failed,
350     * if one is available.
351     * @return the reason for failure, or null if not available
352     */
353    public String getReason() {
354        synchronized (this) {
355            return mReason;
356        }
357    }
358
359    /**
360     * Report the extra information about the network state, if any was
361     * provided by the lower networking layers.,
362     * if one is available.
363     * @return the extra information, or null if not available
364     */
365    public String getExtraInfo() {
366        synchronized (this) {
367            return mExtraInfo;
368        }
369    }
370
371    @Override
372    public String toString() {
373        synchronized (this) {
374            StringBuilder builder = new StringBuilder("NetworkInfo: ");
375            builder.append("type: ").append(getTypeName()).append("[").append(getSubtypeName()).
376            append("], state: ").append(mState).append("/").append(mDetailedState).
377            append(", reason: ").append(mReason == null ? "(unspecified)" : mReason).
378            append(", extra: ").append(mExtraInfo == null ? "(none)" : mExtraInfo).
379            append(", roaming: ").append(mIsRoaming).
380            append(", failover: ").append(mIsFailover).
381            append(", isAvailable: ").append(mIsAvailable);
382            return builder.toString();
383        }
384    }
385
386    /**
387     * Implement the Parcelable interface
388     * @hide
389     */
390    public int describeContents() {
391        return 0;
392    }
393
394    /**
395     * Implement the Parcelable interface.
396     * @hide
397     */
398    public void writeToParcel(Parcel dest, int flags) {
399        synchronized (this) {
400            dest.writeInt(mNetworkType);
401            dest.writeInt(mSubtype);
402            dest.writeString(mTypeName);
403            dest.writeString(mSubtypeName);
404            dest.writeString(mState.name());
405            dest.writeString(mDetailedState.name());
406            dest.writeInt(mIsFailover ? 1 : 0);
407            dest.writeInt(mIsAvailable ? 1 : 0);
408            dest.writeInt(mIsRoaming ? 1 : 0);
409            dest.writeString(mReason);
410            dest.writeString(mExtraInfo);
411        }
412    }
413
414    /**
415     * Implement the Parcelable interface.
416     * @hide
417     */
418    public static final Creator<NetworkInfo> CREATOR =
419        new Creator<NetworkInfo>() {
420            public NetworkInfo createFromParcel(Parcel in) {
421                int netType = in.readInt();
422                int subtype = in.readInt();
423                String typeName = in.readString();
424                String subtypeName = in.readString();
425                NetworkInfo netInfo = new NetworkInfo(netType, subtype, typeName, subtypeName);
426                netInfo.mState = State.valueOf(in.readString());
427                netInfo.mDetailedState = DetailedState.valueOf(in.readString());
428                netInfo.mIsFailover = in.readInt() != 0;
429                netInfo.mIsAvailable = in.readInt() != 0;
430                netInfo.mIsRoaming = in.readInt() != 0;
431                netInfo.mReason = in.readString();
432                netInfo.mExtraInfo = in.readString();
433                return netInfo;
434            }
435
436            public NetworkInfo[] newArray(int size) {
437                return new NetworkInfo[size];
438            }
439        };
440}
441