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