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