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