• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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