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