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