OSDN Git Service

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