NetworkInfo.java revision 54b6cfa9a9e5b861a9930af873580d6dc20f773c
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 State mState;
103    private DetailedState mDetailedState;
104    private String mReason;
105    private String mExtraInfo;
106    private boolean mIsFailover;
107    /**
108     * Indicates whether network connectivity is possible:
109     */
110    private boolean mIsAvailable;
111
112    public NetworkInfo(int type) {
113        if (!ConnectivityManager.isNetworkTypeValid(type)) {
114            throw new IllegalArgumentException("Invalid network type: " + type);
115        }
116        this.mNetworkType = type;
117        setDetailedState(DetailedState.IDLE, null, null);
118        mState = State.UNKNOWN;
119        mIsAvailable = true;
120    }
121
122    /**
123     * Reports the type of network (currently mobile or Wi-Fi) to which the
124     * info in this object pertains.
125     * @return the network type
126     */
127    public int getType() {
128        return mNetworkType;
129    }
130
131    /**
132     * Indicates whether network connectivity exists or is in the process
133     * of being established. This is good for applications that need to
134     * do anything related to the network other than read or write data.
135     * For the latter, call {@link #isConnected()} instead, which guarantees
136     * that the network is fully usable.
137     * @return {@code true} if network connectivity exists or is in the process
138     * of being established, {@code false} otherwise.
139     */
140    public boolean isConnectedOrConnecting() {
141        return mState == State.CONNECTED || mState == State.CONNECTING;
142    }
143
144    /**
145     * Indicates whether network connectivity exists and it is possible to establish
146     * connections and pass data.
147     * @return {@code true} if network connectivity exists, {@code false} otherwise.
148     */
149    public boolean isConnected() {
150        return mState == State.CONNECTED;
151    }
152
153    /**
154     * Indicates whether network connectivity is possible. A network is unavailable
155     * when a persistent or semi-persistent condition prevents the possibility
156     * of connecting to that network. Examples include
157     * <ul>
158     * <li>The device is out of the coverage area for any network of this type.</li>
159     * <li>The device is on a network other than the home network (i.e., roaming), and
160     * data roaming has been disabled.</li>
161     * <li>The device's radio is turned off, e.g., because airplane mode is enabled.</li>
162     * </ul>
163     * @return {@code true} if the network is available, {@code false} otherwise
164     */
165    public boolean isAvailable() {
166        return mIsAvailable;
167    }
168
169    /**
170     * Sets if the network is available, ie, if the connectivity is possible.
171     * @param isAvailable the new availability value.
172     *
173     * {@hide}
174     */
175    public void setIsAvailable(boolean isAvailable) {
176        mIsAvailable = isAvailable;
177    }
178
179    /**
180     * Indicates whether the current attempt to connect to the network
181     * resulted from the ConnectivityManager trying to fail over to this
182     * network following a disconnect from another network.
183     * @return {@code true} if this is a failover attempt, {@code false}
184     * otherwise.
185     */
186    public boolean isFailover() {
187        return mIsFailover;
188    }
189
190    /** {@hide} */
191    public void setFailover(boolean isFailover) {
192        mIsFailover = isFailover;
193    }
194
195    /**
196     * Reports the current coarse-grained state of the network.
197     * @return the coarse-grained state
198     */
199    public State getState() {
200        return mState;
201    }
202
203    /**
204     * Reports the current fine-grained state of the network.
205     * @return the fine-grained state
206     */
207    public DetailedState getDetailedState() {
208        return mDetailedState;
209    }
210
211    /**
212     * Sets the fine-grained state of the network.
213     * @param detailedState the {@link DetailedState}.
214     * @param reason a {@code String} indicating the reason for the state change,
215     * if one was supplied. May be {@code null}.
216     * @param extraInfo an optional {@code String} providing addditional network state
217     * information passed up from the lower networking layers.
218     *
219     * {@hide}
220     */
221    void setDetailedState(DetailedState detailedState, String reason, String extraInfo) {
222        this.mDetailedState = detailedState;
223        this.mState = stateMap.get(detailedState);
224        this.mReason = reason;
225        this.mExtraInfo = extraInfo;
226    }
227
228    /**
229     * Report the reason an attempt to establish connectivity failed,
230     * if one is available.
231     * @return the reason for failure, or null if not available
232     */
233    public String getReason() {
234        return mReason;
235    }
236
237    /**
238     * Report the extra information about the network state, if any was
239     * provided by the lower networking layers.,
240     * if one is available.
241     * @return the extra information, or null if not available
242     */
243    public String getExtraInfo() {
244        return mExtraInfo;
245    }
246
247    @Override
248    public String toString() {
249        StringBuilder builder = new StringBuilder("NetworkInfo: ");
250        builder.append("type: ").append(getTypeName()).append(", state: ").append(mState).
251                append("/").append(mDetailedState).
252                append(", reason: ").append(mReason == null ? "(unspecified)" : mReason).
253                append(", extra: ").append(mExtraInfo == null ? "(none)" : mExtraInfo).
254                append(", failover: ").append(mIsFailover).
255                append(", isAvailable: ").append(mIsAvailable);
256        return builder.toString();
257    }
258
259    public String getTypeName() {
260        switch (mNetworkType) {
261            case ConnectivityManager.TYPE_WIFI:
262                return "WIFI";
263            case ConnectivityManager.TYPE_MOBILE:
264                return "MOBILE";
265            default:
266                return "<invalid>";
267        }
268    }
269
270    /** Implement the Parcelable interface {@hide} */
271    public int describeContents() {
272        return 0;
273    }
274
275    /** Implement the Parcelable interface {@hide} */
276    public void writeToParcel(Parcel dest, int flags) {
277        dest.writeInt(mNetworkType);
278        dest.writeString(mState.name());
279        dest.writeString(mDetailedState.name());
280        dest.writeInt(mIsFailover ? 1 : 0);
281        dest.writeInt(mIsAvailable ? 1 : 0);
282        dest.writeString(mReason);
283        dest.writeString(mExtraInfo);
284    }
285
286    /** Implement the Parcelable interface {@hide} */
287    public static final Creator<NetworkInfo> CREATOR =
288        new Creator<NetworkInfo>() {
289            public NetworkInfo createFromParcel(Parcel in) {
290                int netType = in.readInt();
291                NetworkInfo netInfo = new NetworkInfo(netType);
292                netInfo.mState = State.valueOf(in.readString());
293                netInfo.mDetailedState = DetailedState.valueOf(in.readString());
294                netInfo.mIsFailover = in.readInt() != 0;
295                netInfo.mIsAvailable = in.readInt() != 0;
296                netInfo.mReason = in.readString();
297                netInfo.mExtraInfo = in.readString();
298                return netInfo;
299            }
300
301            public NetworkInfo[] newArray(int size) {
302                return new NetworkInfo[size];
303            }
304        };
305}
306