NetworkInfo.java revision 6aecb98a627daa3f66c060ca5177a075e4e9bcca
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    }
79
80    /**
81     * This is the map described in the Javadoc comment above. The positions
82     * of the elements of the array must correspond to the ordinal values
83     * of <code>DetailedState</code>.
84     */
85    private static final EnumMap<DetailedState, State> stateMap =
86        new EnumMap<DetailedState, State>(DetailedState.class);
87
88    static {
89        stateMap.put(DetailedState.IDLE, State.DISCONNECTED);
90        stateMap.put(DetailedState.SCANNING, State.DISCONNECTED);
91        stateMap.put(DetailedState.CONNECTING, State.CONNECTING);
92        stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING);
93        stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING);
94        stateMap.put(DetailedState.CONNECTED, State.CONNECTED);
95        stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED);
96        stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING);
97        stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED);
98        stateMap.put(DetailedState.FAILED, State.DISCONNECTED);
99    }
100
101    private int mNetworkType;
102    private int mSubtype;
103    private String mTypeName;
104    private String mSubtypeName;
105    private State mState;
106    private DetailedState mDetailedState;
107    private String mReason;
108    private String mExtraInfo;
109    private boolean mIsFailover;
110    private boolean mIsRoaming;
111    /**
112     * Indicates whether network connectivity is possible:
113     */
114    private boolean mIsAvailable;
115
116    /**
117     * @param type network type
118     * @deprecated
119     * @hide because this constructor was only meant for internal use (and
120     * has now been superseded by the package-private constructor below).
121     */
122    public NetworkInfo(int type) {}
123
124    /**
125     * @hide
126     */
127    public NetworkInfo(int type, int subtype, String typeName, String subtypeName) {
128        if (!ConnectivityManager.isNetworkTypeValid(type)) {
129            throw new IllegalArgumentException("Invalid network type: " + type);
130        }
131        mNetworkType = type;
132        mSubtype = subtype;
133        mTypeName = typeName;
134        mSubtypeName = subtypeName;
135        setDetailedState(DetailedState.IDLE, null, null);
136        mState = State.UNKNOWN;
137        mIsAvailable = false; // until we're told otherwise, assume unavailable
138        mIsRoaming = false;
139    }
140
141    /** {@hide} */
142    public NetworkInfo(NetworkInfo source) {
143        if (source != null) {
144            mNetworkType = source.mNetworkType;
145            mSubtype = source.mSubtype;
146            mTypeName = source.mTypeName;
147            mSubtypeName = source.mSubtypeName;
148            mState = source.mState;
149            mDetailedState = source.mDetailedState;
150            mReason = source.mReason;
151            mExtraInfo = source.mExtraInfo;
152            mIsFailover = source.mIsFailover;
153            mIsRoaming = source.mIsRoaming;
154            mIsAvailable = source.mIsAvailable;
155        }
156    }
157
158    /**
159     * Reports the type of network (currently mobile or Wi-Fi) to which the
160     * info in this object pertains.
161     * @return the network type
162     */
163    public int getType() {
164        synchronized (this) {
165            return mNetworkType;
166        }
167    }
168
169    /**
170     * Return a network-type-specific integer describing the subtype
171     * of the network.
172     * @return the network subtype
173     */
174    public int getSubtype() {
175        synchronized (this) {
176            return mSubtype;
177        }
178    }
179
180    void setSubtype(int subtype, String subtypeName) {
181        synchronized (this) {
182            mSubtype = subtype;
183            mSubtypeName = subtypeName;
184        }
185    }
186
187    /**
188     * Return a human-readable name describe the type of the network,
189     * for example "WIFI" or "MOBILE".
190     * @return the name of the network type
191     */
192    public String getTypeName() {
193        synchronized (this) {
194            return mTypeName;
195        }
196    }
197
198    /**
199     * Return a human-readable name describing the subtype of the network.
200     * @return the name of the network subtype
201     */
202    public String getSubtypeName() {
203        synchronized (this) {
204            return mSubtypeName;
205        }
206    }
207
208    /**
209     * Indicates whether network connectivity exists or is in the process
210     * of being established. This is good for applications that need to
211     * do anything related to the network other than read or write data.
212     * For the latter, call {@link #isConnected()} instead, which guarantees
213     * that the network is fully usable.
214     * @return {@code true} if network connectivity exists or is in the process
215     * of being established, {@code false} otherwise.
216     */
217    public boolean isConnectedOrConnecting() {
218        synchronized (this) {
219            return mState == State.CONNECTED || mState == State.CONNECTING;
220        }
221    }
222
223    /**
224     * Indicates whether network connectivity exists and it is possible to establish
225     * connections and pass data.
226     * @return {@code true} if network connectivity exists, {@code false} otherwise.
227     */
228    public boolean isConnected() {
229        synchronized (this) {
230            return mState == State.CONNECTED;
231        }
232    }
233
234    /**
235     * Indicates whether network connectivity is possible. A network is unavailable
236     * when a persistent or semi-persistent condition prevents the possibility
237     * of connecting to that network. Examples include
238     * <ul>
239     * <li>The device is out of the coverage area for any network of this type.</li>
240     * <li>The device is on a network other than the home network (i.e., roaming), and
241     * data roaming has been disabled.</li>
242     * <li>The device's radio is turned off, e.g., because airplane mode is enabled.</li>
243     * </ul>
244     * @return {@code true} if the network is available, {@code false} otherwise
245     */
246    public boolean isAvailable() {
247        synchronized (this) {
248            return mIsAvailable;
249        }
250    }
251
252    /**
253     * Sets if the network is available, ie, if the connectivity is possible.
254     * @param isAvailable the new availability value.
255     *
256     * @hide
257     */
258    public void setIsAvailable(boolean isAvailable) {
259        synchronized (this) {
260            mIsAvailable = isAvailable;
261        }
262    }
263
264    /**
265     * Indicates whether the current attempt to connect to the network
266     * resulted from the ConnectivityManager trying to fail over to this
267     * network following a disconnect from another network.
268     * @return {@code true} if this is a failover attempt, {@code false}
269     * otherwise.
270     */
271    public boolean isFailover() {
272        synchronized (this) {
273            return mIsFailover;
274        }
275    }
276
277    /**
278     * Set the failover boolean.
279     * @param isFailover {@code true} to mark the current connection attempt
280     * as a failover.
281     * @hide
282     */
283    public void setFailover(boolean isFailover) {
284        synchronized (this) {
285            mIsFailover = isFailover;
286        }
287    }
288
289    /**
290     * Indicates whether the device is currently roaming on this network.
291     * When {@code true}, it suggests that use of data on this network
292     * may incur extra costs.
293     * @return {@code true} if roaming is in effect, {@code false} otherwise.
294     */
295    public boolean isRoaming() {
296        synchronized (this) {
297            return mIsRoaming;
298        }
299    }
300
301    void setRoaming(boolean isRoaming) {
302        synchronized (this) {
303            mIsRoaming = isRoaming;
304        }
305    }
306
307    /**
308     * Reports the current coarse-grained state of the network.
309     * @return the coarse-grained state
310     */
311    public State getState() {
312        synchronized (this) {
313            return mState;
314        }
315    }
316
317    /**
318     * Reports the current fine-grained state of the network.
319     * @return the fine-grained state
320     */
321    public DetailedState getDetailedState() {
322        synchronized (this) {
323            return mDetailedState;
324        }
325    }
326
327    /**
328     * Sets the fine-grained state of the network.
329     * @param detailedState the {@link DetailedState}.
330     * @param reason a {@code String} indicating the reason for the state change,
331     * if one was supplied. May be {@code null}.
332     * @param extraInfo an optional {@code String} providing addditional network state
333     * information passed up from the lower networking layers.
334     * @hide
335     */
336    public void setDetailedState(DetailedState detailedState, String reason, String extraInfo) {
337        synchronized (this) {
338            this.mDetailedState = detailedState;
339            this.mState = stateMap.get(detailedState);
340            this.mReason = reason;
341            this.mExtraInfo = extraInfo;
342        }
343    }
344
345    /**
346     * Report the reason an attempt to establish connectivity failed,
347     * if one is available.
348     * @return the reason for failure, or null if not available
349     */
350    public String getReason() {
351        synchronized (this) {
352            return mReason;
353        }
354    }
355
356    /**
357     * Report the extra information about the network state, if any was
358     * provided by the lower networking layers.,
359     * if one is available.
360     * @return the extra information, or null if not available
361     */
362    public String getExtraInfo() {
363        synchronized (this) {
364            return mExtraInfo;
365        }
366    }
367
368    @Override
369    public String toString() {
370        synchronized (this) {
371            StringBuilder builder = new StringBuilder("NetworkInfo: ");
372            builder.append("type: ").append(getTypeName()).append("[").append(getSubtypeName()).
373            append("], state: ").append(mState).append("/").append(mDetailedState).
374            append(", reason: ").append(mReason == null ? "(unspecified)" : mReason).
375            append(", extra: ").append(mExtraInfo == null ? "(none)" : mExtraInfo).
376            append(", roaming: ").append(mIsRoaming).
377            append(", failover: ").append(mIsFailover).
378            append(", isAvailable: ").append(mIsAvailable);
379            return builder.toString();
380        }
381    }
382
383    /**
384     * Implement the Parcelable interface
385     * @hide
386     */
387    public int describeContents() {
388        return 0;
389    }
390
391    /**
392     * Implement the Parcelable interface.
393     * @hide
394     */
395    public void writeToParcel(Parcel dest, int flags) {
396        synchronized (this) {
397            dest.writeInt(mNetworkType);
398            dest.writeInt(mSubtype);
399            dest.writeString(mTypeName);
400            dest.writeString(mSubtypeName);
401            dest.writeString(mState.name());
402            dest.writeString(mDetailedState.name());
403            dest.writeInt(mIsFailover ? 1 : 0);
404            dest.writeInt(mIsAvailable ? 1 : 0);
405            dest.writeInt(mIsRoaming ? 1 : 0);
406            dest.writeString(mReason);
407            dest.writeString(mExtraInfo);
408        }
409    }
410
411    /**
412     * Implement the Parcelable interface.
413     * @hide
414     */
415    public static final Creator<NetworkInfo> CREATOR =
416        new Creator<NetworkInfo>() {
417            public NetworkInfo createFromParcel(Parcel in) {
418                int netType = in.readInt();
419                int subtype = in.readInt();
420                String typeName = in.readString();
421                String subtypeName = in.readString();
422                NetworkInfo netInfo = new NetworkInfo(netType, subtype, typeName, subtypeName);
423                netInfo.mState = State.valueOf(in.readString());
424                netInfo.mDetailedState = DetailedState.valueOf(in.readString());
425                netInfo.mIsFailover = in.readInt() != 0;
426                netInfo.mIsAvailable = in.readInt() != 0;
427                netInfo.mIsRoaming = in.readInt() != 0;
428                netInfo.mReason = in.readString();
429                netInfo.mExtraInfo = in.readString();
430                return netInfo;
431            }
432
433            public NetworkInfo[] newArray(int size) {
434                return new NetworkInfo[size];
435            }
436        };
437}
438