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 NetworkInfo(int type, int subtype, String typeName, String subtypeName) { 125 if (!ConnectivityManager.isNetworkTypeValid(type)) { 126 throw new IllegalArgumentException("Invalid network type: " + type); 127 } 128 mNetworkType = type; 129 mSubtype = subtype; 130 mTypeName = typeName; 131 mSubtypeName = subtypeName; 132 setDetailedState(DetailedState.IDLE, null, null); 133 mState = State.UNKNOWN; 134 mIsAvailable = true; 135 mIsRoaming = false; 136 } 137 138 /** 139 * Reports the type of network (currently mobile or Wi-Fi) to which the 140 * info in this object pertains. 141 * @return the network type 142 */ 143 public int getType() { 144 return mNetworkType; 145 } 146 147 /** 148 * Return a network-type-specific integer describing the subtype 149 * of the network. 150 * @return the network subtype 151 */ 152 public int getSubtype() { 153 return mSubtype; 154 } 155 156 void setSubtype(int subtype, String subtypeName) { 157 mSubtype = subtype; 158 mSubtypeName = subtypeName; 159 } 160 161 /** 162 * Return a human-readable name describe the type of the network, 163 * for example "WIFI" or "MOBILE". 164 * @return the name of the network type 165 */ 166 public String getTypeName() { 167 return mTypeName; 168 } 169 170 /** 171 * Return a human-readable name describing the subtype of the network. 172 * @return the name of the network subtype 173 */ 174 public String getSubtypeName() { 175 return mSubtypeName; 176 } 177 178 /** 179 * Indicates whether network connectivity exists or is in the process 180 * of being established. This is good for applications that need to 181 * do anything related to the network other than read or write data. 182 * For the latter, call {@link #isConnected()} instead, which guarantees 183 * that the network is fully usable. 184 * @return {@code true} if network connectivity exists or is in the process 185 * of being established, {@code false} otherwise. 186 */ 187 public boolean isConnectedOrConnecting() { 188 return mState == State.CONNECTED || mState == State.CONNECTING; 189 } 190 191 /** 192 * Indicates whether network connectivity exists and it is possible to establish 193 * connections and pass data. 194 * @return {@code true} if network connectivity exists, {@code false} otherwise. 195 */ 196 public boolean isConnected() { 197 return mState == State.CONNECTED; 198 } 199 200 /** 201 * Indicates whether network connectivity is possible. A network is unavailable 202 * when a persistent or semi-persistent condition prevents the possibility 203 * of connecting to that network. Examples include 204 * <ul> 205 * <li>The device is out of the coverage area for any network of this type.</li> 206 * <li>The device is on a network other than the home network (i.e., roaming), and 207 * data roaming has been disabled.</li> 208 * <li>The device's radio is turned off, e.g., because airplane mode is enabled.</li> 209 * </ul> 210 * @return {@code true} if the network is available, {@code false} otherwise 211 */ 212 public boolean isAvailable() { 213 return mIsAvailable; 214 } 215 216 /** 217 * Sets if the network is available, ie, if the connectivity is possible. 218 * @param isAvailable the new availability value. 219 * 220 * @hide 221 */ 222 public void setIsAvailable(boolean isAvailable) { 223 mIsAvailable = isAvailable; 224 } 225 226 /** 227 * Indicates whether the current attempt to connect to the network 228 * resulted from the ConnectivityManager trying to fail over to this 229 * network following a disconnect from another network. 230 * @return {@code true} if this is a failover attempt, {@code false} 231 * otherwise. 232 */ 233 public boolean isFailover() { 234 return mIsFailover; 235 } 236 237 /** 238 * Set the failover boolean. 239 * @param isFailover {@code true} to mark the current connection attempt 240 * as a failover. 241 * @hide 242 */ 243 public void setFailover(boolean isFailover) { 244 mIsFailover = isFailover; 245 } 246 247 /** 248 * Indicates whether the device is currently roaming on this network. 249 * When {@code true}, it suggests that use of data on this network 250 * may incur extra costs. 251 * @return {@code true} if roaming is in effect, {@code false} otherwise. 252 */ 253 public boolean isRoaming() { 254 return mIsRoaming; 255 } 256 257 void setRoaming(boolean isRoaming) { 258 mIsRoaming = isRoaming; 259 } 260 261 /** 262 * Reports the current coarse-grained state of the network. 263 * @return the coarse-grained state 264 */ 265 public State getState() { 266 return mState; 267 } 268 269 /** 270 * Reports the current fine-grained state of the network. 271 * @return the fine-grained state 272 */ 273 public DetailedState getDetailedState() { 274 return mDetailedState; 275 } 276 277 /** 278 * Sets the fine-grained state of the network. 279 * @param detailedState the {@link DetailedState}. 280 * @param reason a {@code String} indicating the reason for the state change, 281 * if one was supplied. May be {@code null}. 282 * @param extraInfo an optional {@code String} providing addditional network state 283 * information passed up from the lower networking layers. 284 */ 285 void setDetailedState(DetailedState detailedState, String reason, String extraInfo) { 286 this.mDetailedState = detailedState; 287 this.mState = stateMap.get(detailedState); 288 this.mReason = reason; 289 this.mExtraInfo = extraInfo; 290 } 291 292 /** 293 * Report the reason an attempt to establish connectivity failed, 294 * if one is available. 295 * @return the reason for failure, or null if not available 296 */ 297 public String getReason() { 298 return mReason; 299 } 300 301 /** 302 * Report the extra information about the network state, if any was 303 * provided by the lower networking layers., 304 * if one is available. 305 * @return the extra information, or null if not available 306 */ 307 public String getExtraInfo() { 308 return mExtraInfo; 309 } 310 311 @Override 312 public String toString() { 313 StringBuilder builder = new StringBuilder("NetworkInfo: "); 314 builder.append("type: ").append(getTypeName()).append("[").append(getSubtypeName()). 315 append("], state: ").append(mState).append("/").append(mDetailedState). 316 append(", reason: ").append(mReason == null ? "(unspecified)" : mReason). 317 append(", extra: ").append(mExtraInfo == null ? "(none)" : mExtraInfo). 318 append(", roaming: ").append(mIsRoaming). 319 append(", failover: ").append(mIsFailover). 320 append(", isAvailable: ").append(mIsAvailable); 321 return builder.toString(); 322 } 323 324 /** 325 * Implement the Parcelable interface 326 * @hide 327 */ 328 public int describeContents() { 329 return 0; 330 } 331 332 /** 333 * Implement the Parcelable interface. 334 * @hide 335 */ 336 public void writeToParcel(Parcel dest, int flags) { 337 dest.writeInt(mNetworkType); 338 dest.writeInt(mSubtype); 339 dest.writeString(mTypeName); 340 dest.writeString(mSubtypeName); 341 dest.writeString(mState.name()); 342 dest.writeString(mDetailedState.name()); 343 dest.writeInt(mIsFailover ? 1 : 0); 344 dest.writeInt(mIsAvailable ? 1 : 0); 345 dest.writeInt(mIsRoaming ? 1 : 0); 346 dest.writeString(mReason); 347 dest.writeString(mExtraInfo); 348 } 349 350 /** 351 * Implement the Parcelable interface. 352 * @hide 353 */ 354 public static final Creator<NetworkInfo> CREATOR = 355 new Creator<NetworkInfo>() { 356 public NetworkInfo createFromParcel(Parcel in) { 357 int netType = in.readInt(); 358 int subtype = in.readInt(); 359 String typeName = in.readString(); 360 String subtypeName = in.readString(); 361 NetworkInfo netInfo = new NetworkInfo(netType, subtype, typeName, subtypeName); 362 netInfo.mState = State.valueOf(in.readString()); 363 netInfo.mDetailedState = DetailedState.valueOf(in.readString()); 364 netInfo.mIsFailover = in.readInt() != 0; 365 netInfo.mIsAvailable = in.readInt() != 0; 366 netInfo.mIsRoaming = in.readInt() != 0; 367 netInfo.mReason = in.readString(); 368 netInfo.mExtraInfo = in.readString(); 369 return netInfo; 370 } 371 372 public NetworkInfo[] newArray(int size) { 373 return new NetworkInfo[size]; 374 } 375 }; 376} 377