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