1 /* 2 * Copyright (C) 2014 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.Parcel; 20 import android.os.Parcelable; 21 import android.text.TextUtils; 22 23 import java.util.Objects; 24 25 /** 26 * Defines a request for a network, made through {@link NetworkRequest.Builder} and used 27 * to request a network via {@link ConnectivityManager#requestNetwork} or listen for changes 28 * via {@link ConnectivityManager#registerNetworkCallback}. 29 */ 30 public class NetworkRequest implements Parcelable { 31 /** 32 * The {@link NetworkCapabilities} that define this request. 33 * @hide 34 */ 35 public final NetworkCapabilities networkCapabilities; 36 37 /** 38 * Identifies the request. NetworkRequests should only be constructed by 39 * the Framework and given out to applications as tokens to be used to identify 40 * the request. 41 * @hide 42 */ 43 public final int requestId; 44 45 /** 46 * Set for legacy requests and the default. Set to TYPE_NONE for none. 47 * Causes CONNECTIVITY_ACTION broadcasts to be sent. 48 * @hide 49 */ 50 public final int legacyType; 51 52 /** 53 * A NetworkRequest as used by the system can be one of the following types: 54 * 55 * - LISTEN, for which the framework will issue callbacks about any 56 * and all networks that match the specified NetworkCapabilities, 57 * 58 * - REQUEST, capable of causing a specific network to be created 59 * first (e.g. a telephony DUN request), the framework will issue 60 * callbacks about the single, highest scoring current network 61 * (if any) that matches the specified NetworkCapabilities, or 62 * 63 * - TRACK_DEFAULT, a hybrid of the two designed such that the 64 * framework will issue callbacks for the single, highest scoring 65 * current network (if any) that matches the capabilities of the 66 * default Internet request (mDefaultRequest), but which cannot cause 67 * the framework to either create or retain the existence of any 68 * specific network. Note that from the point of view of the request 69 * matching code, TRACK_DEFAULT is identical to REQUEST: its special 70 * behaviour is not due to different semantics, but to the fact that 71 * the system will only ever create a TRACK_DEFAULT with capabilities 72 * that are identical to the default request's capabilities, thus 73 * causing it to share fate in every way with the default request. 74 * 75 * - BACKGROUND_REQUEST, like REQUEST but does not cause any networks 76 * to retain the NET_CAPABILITY_FOREGROUND capability. A network with 77 * no foreground requests is in the background. A network that has 78 * one or more background requests and loses its last foreground 79 * request to a higher-scoring network will not go into the 80 * background immediately, but will linger and go into the background 81 * after the linger timeout. 82 * 83 * - The value NONE is used only by applications. When an application 84 * creates a NetworkRequest, it does not have a type; the type is set 85 * by the system depending on the method used to file the request 86 * (requestNetwork, registerNetworkCallback, etc.). 87 * 88 * @hide 89 */ 90 public static enum Type { 91 NONE, 92 LISTEN, 93 TRACK_DEFAULT, 94 REQUEST, 95 BACKGROUND_REQUEST, 96 }; 97 98 /** 99 * The type of the request. This is only used by the system and is always NONE elsewhere. 100 * 101 * @hide 102 */ 103 public final Type type; 104 105 /** 106 * @hide 107 */ 108 public NetworkRequest(NetworkCapabilities nc, int legacyType, int rId, Type type) { 109 if (nc == null) { 110 throw new NullPointerException(); 111 } 112 requestId = rId; 113 networkCapabilities = nc; 114 this.legacyType = legacyType; 115 this.type = type; 116 } 117 118 /** 119 * @hide 120 */ 121 public NetworkRequest(NetworkRequest that) { 122 networkCapabilities = new NetworkCapabilities(that.networkCapabilities); 123 requestId = that.requestId; 124 this.legacyType = that.legacyType; 125 this.type = that.type; 126 } 127 128 /** 129 * Builder used to create {@link NetworkRequest} objects. Specify the Network features 130 * needed in terms of {@link NetworkCapabilities} features 131 */ 132 public static class Builder { 133 private final NetworkCapabilities mNetworkCapabilities = new NetworkCapabilities(); 134 135 /** 136 * Default constructor for Builder. 137 */ 138 public Builder() {} 139 140 /** 141 * Build {@link NetworkRequest} give the current set of capabilities. 142 */ 143 public NetworkRequest build() { 144 // Make a copy of mNetworkCapabilities so we don't inadvertently remove NOT_RESTRICTED 145 // when later an unrestricted capability could be added to mNetworkCapabilities, in 146 // which case NOT_RESTRICTED should be returned to mNetworkCapabilities, which 147 // maybeMarkCapabilitiesRestricted() doesn't add back. 148 final NetworkCapabilities nc = new NetworkCapabilities(mNetworkCapabilities); 149 nc.maybeMarkCapabilitiesRestricted(); 150 return new NetworkRequest(nc, ConnectivityManager.TYPE_NONE, 151 ConnectivityManager.REQUEST_ID_UNSET, Type.NONE); 152 } 153 154 /** 155 * Add the given capability requirement to this builder. These represent 156 * the requested network's required capabilities. Note that when searching 157 * for a network to satisfy a request, all capabilities requested must be 158 * satisfied. See {@link NetworkCapabilities} for {@code NET_CAPABILITY_*} 159 * definitions. 160 * 161 * @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to add. 162 * @return The builder to facilitate chaining 163 * {@code builder.addCapability(...).addCapability();}. 164 */ 165 public Builder addCapability(int capability) { 166 mNetworkCapabilities.addCapability(capability); 167 return this; 168 } 169 170 /** 171 * Removes (if found) the given capability from this builder instance. 172 * 173 * @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to remove. 174 * @return The builder to facilitate chaining. 175 */ 176 public Builder removeCapability(int capability) { 177 mNetworkCapabilities.removeCapability(capability); 178 return this; 179 } 180 181 /** 182 * Set the {@code NetworkCapabilities} for this builder instance, 183 * overriding any capabilities that had been previously set. 184 * 185 * @param nc The superseding {@code NetworkCapabilities} instance. 186 * @return The builder to facilitate chaining. 187 * @hide 188 */ 189 public Builder setCapabilities(NetworkCapabilities nc) { 190 mNetworkCapabilities.clearAll(); 191 mNetworkCapabilities.combineCapabilities(nc); 192 return this; 193 } 194 195 /** 196 * Completely clears all the {@code NetworkCapabilities} from this builder instance, 197 * removing even the capabilities that are set by default when the object is constructed. 198 * 199 * @return The builder to facilitate chaining. 200 * @hide 201 */ 202 public Builder clearCapabilities() { 203 mNetworkCapabilities.clearAll(); 204 return this; 205 } 206 207 /** 208 * Adds the given transport requirement to this builder. These represent 209 * the set of allowed transports for the request. Only networks using one 210 * of these transports will satisfy the request. If no particular transports 211 * are required, none should be specified here. See {@link NetworkCapabilities} 212 * for {@code TRANSPORT_*} definitions. 213 * 214 * @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to add. 215 * @return The builder to facilitate chaining. 216 */ 217 public Builder addTransportType(int transportType) { 218 mNetworkCapabilities.addTransportType(transportType); 219 return this; 220 } 221 222 /** 223 * Removes (if found) the given transport from this builder instance. 224 * 225 * @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to remove. 226 * @return The builder to facilitate chaining. 227 */ 228 public Builder removeTransportType(int transportType) { 229 mNetworkCapabilities.removeTransportType(transportType); 230 return this; 231 } 232 233 /** 234 * @hide 235 */ 236 public Builder setLinkUpstreamBandwidthKbps(int upKbps) { 237 mNetworkCapabilities.setLinkUpstreamBandwidthKbps(upKbps); 238 return this; 239 } 240 /** 241 * @hide 242 */ 243 public Builder setLinkDownstreamBandwidthKbps(int downKbps) { 244 mNetworkCapabilities.setLinkDownstreamBandwidthKbps(downKbps); 245 return this; 246 } 247 248 /** 249 * Sets the optional bearer specific network specifier. 250 * This has no meaning if a single transport is also not specified, so calling 251 * this without a single transport set will generate an exception, as will 252 * subsequently adding or removing transports after this is set. 253 * </p> 254 * The interpretation of this {@code String} is bearer specific and bearers that use 255 * it should document their particulars. For example, Bluetooth may use some sort of 256 * device id while WiFi could used ssid and/or bssid. Cellular may use carrier spn. 257 * 258 * @param networkSpecifier An {@code String} of opaque format used to specify the bearer 259 * specific network specifier where the bearer has a choice of 260 * networks. 261 */ 262 public Builder setNetworkSpecifier(String networkSpecifier) { 263 /* 264 * A StringNetworkSpecifier does not accept null or empty ("") strings. When network 265 * specifiers were strings a null string and an empty string were considered equivalent. 266 * Hence no meaning is attached to a null or empty ("") string. 267 */ 268 return setNetworkSpecifier(TextUtils.isEmpty(networkSpecifier) ? null 269 : new StringNetworkSpecifier(networkSpecifier)); 270 } 271 272 /** 273 * Sets the optional bearer specific network specifier. 274 * This has no meaning if a single transport is also not specified, so calling 275 * this without a single transport set will generate an exception, as will 276 * subsequently adding or removing transports after this is set. 277 * </p> 278 * 279 * @param networkSpecifier A concrete, parcelable framework class that extends 280 * NetworkSpecifier. 281 */ 282 public Builder setNetworkSpecifier(NetworkSpecifier networkSpecifier) { 283 MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(networkSpecifier); 284 mNetworkCapabilities.setNetworkSpecifier(networkSpecifier); 285 return this; 286 } 287 288 /** 289 * Sets the signal strength. This is a signed integer, with higher values indicating a 290 * stronger signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same 291 * RSSI units reported by WifiManager. 292 * <p> 293 * Note that when used to register a network callback, this specifies the minimum acceptable 294 * signal strength. When received as the state of an existing network it specifies the 295 * current value. A value of {@code SIGNAL_STRENGTH_UNSPECIFIED} means no value when 296 * received and has no effect when requesting a callback. 297 * 298 * @param signalStrength the bearer-specific signal strength. 299 * @hide 300 */ 301 public Builder setSignalStrength(int signalStrength) { 302 mNetworkCapabilities.setSignalStrength(signalStrength); 303 return this; 304 } 305 } 306 307 // implement the Parcelable interface 308 public int describeContents() { 309 return 0; 310 } 311 public void writeToParcel(Parcel dest, int flags) { 312 dest.writeParcelable(networkCapabilities, flags); 313 dest.writeInt(legacyType); 314 dest.writeInt(requestId); 315 dest.writeString(type.name()); 316 } 317 public static final Creator<NetworkRequest> CREATOR = 318 new Creator<NetworkRequest>() { 319 public NetworkRequest createFromParcel(Parcel in) { 320 NetworkCapabilities nc = (NetworkCapabilities)in.readParcelable(null); 321 int legacyType = in.readInt(); 322 int requestId = in.readInt(); 323 Type type = Type.valueOf(in.readString()); // IllegalArgumentException if invalid. 324 NetworkRequest result = new NetworkRequest(nc, legacyType, requestId, type); 325 return result; 326 } 327 public NetworkRequest[] newArray(int size) { 328 return new NetworkRequest[size]; 329 } 330 }; 331 332 /** 333 * Returns true iff. this NetworkRequest is of type LISTEN. 334 * 335 * @hide 336 */ 337 public boolean isListen() { 338 return type == Type.LISTEN; 339 } 340 341 /** 342 * Returns true iff. the contained NetworkRequest is one that: 343 * 344 * - should be associated with at most one satisfying network 345 * at a time; 346 * 347 * - should cause a network to be kept up, but not necessarily in 348 * the foreground, if it is the best network which can satisfy the 349 * NetworkRequest. 350 * 351 * For full detail of how isRequest() is used for pairing Networks with 352 * NetworkRequests read rematchNetworkAndRequests(). 353 * 354 * @hide 355 */ 356 public boolean isRequest() { 357 return isForegroundRequest() || isBackgroundRequest(); 358 } 359 360 /** 361 * Returns true iff. the contained NetworkRequest is one that: 362 * 363 * - should be associated with at most one satisfying network 364 * at a time; 365 * 366 * - should cause a network to be kept up and in the foreground if 367 * it is the best network which can satisfy the NetworkRequest. 368 * 369 * For full detail of how isRequest() is used for pairing Networks with 370 * NetworkRequests read rematchNetworkAndRequests(). 371 * 372 * @hide 373 */ 374 public boolean isForegroundRequest() { 375 return type == Type.TRACK_DEFAULT || type == Type.REQUEST; 376 } 377 378 /** 379 * Returns true iff. this NetworkRequest is of type BACKGROUND_REQUEST. 380 * 381 * @hide 382 */ 383 public boolean isBackgroundRequest() { 384 return type == Type.BACKGROUND_REQUEST; 385 } 386 387 public String toString() { 388 return "NetworkRequest [ " + type + " id=" + requestId + 389 (legacyType != ConnectivityManager.TYPE_NONE ? ", legacyType=" + legacyType : "") + 390 ", " + networkCapabilities.toString() + " ]"; 391 } 392 393 public boolean equals(Object obj) { 394 if (obj instanceof NetworkRequest == false) return false; 395 NetworkRequest that = (NetworkRequest)obj; 396 return (that.legacyType == this.legacyType && 397 that.requestId == this.requestId && 398 that.type == this.type && 399 Objects.equals(that.networkCapabilities, this.networkCapabilities)); 400 } 401 402 public int hashCode() { 403 return Objects.hash(requestId, legacyType, networkCapabilities, type); 404 } 405 } 406