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 static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
20 import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
21 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
22 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
23 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED;
24 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
25 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
26 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
27 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
28 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
29 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
30 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
31 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
32 import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED;
33 import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
34 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
35 import static android.net.NetworkCapabilities.TRANSPORT_TEST;
36 
37 import android.annotation.FlaggedApi;
38 import android.annotation.NonNull;
39 import android.annotation.Nullable;
40 import android.annotation.RequiresPermission;
41 import android.annotation.SuppressLint;
42 import android.annotation.SystemApi;
43 import android.compat.annotation.UnsupportedAppUsage;
44 import android.net.NetworkCapabilities.NetCapability;
45 import android.net.NetworkCapabilities.Transport;
46 import android.os.Build;
47 import android.os.Parcel;
48 import android.os.Parcelable;
49 import android.os.Process;
50 import android.text.TextUtils;
51 import android.util.Range;
52 
53 import java.util.Arrays;
54 import java.util.List;
55 import java.util.Objects;
56 import java.util.Set;
57 
58 /**
59  * An object describing a network that the application is interested in.
60  *
61  * <p>@see <a href="https://developer.android.com/training/basics/network-ops/reading-network-state>
62  * this general guide</a> on how to use NetworkCapabilities and related classes.
63  *
64  * NetworkRequest defines a request for a network, made through
65  * {@link NetworkRequest.Builder} and used to request a network via
66  * {@link ConnectivityManager#requestNetwork} or to listen for changes
67  * via the {@link ConnectivityManager#registerNetworkCallback} family of
68  * functions.
69  *
70  * <p>{@link ConnectivityManager#requestNetwork} will try to find a connected
71  * network matching the NetworkRequest, and return it if there is one.
72  * As long as the request is outstanding, the system will try to find the best
73  * possible network that matches the request. The request will keep up the
74  * currently best connected network, and if a better one is found (e.g. cheaper
75  * or faster) the system will bring up that better network to better serve the
76  * request. A request filed with {@link ConnectivityManager#requestNetwork} will
77  * only match one network at a time (the one the system thinks is best), even if
78  * other networks can match the request that are being kept up by other requests.
79  *
80  * For example, an application needing a network with
81  * {@link NetworkCapabilities#NET_CAPABILITY_INTERNET} should use
82  * {@link ConnectivityManager#requestNetwork} to request the system keeps one up.
83  * A general cellular network can satisfy this request, but if the system finds
84  * a free Wi-Fi network which is expected to be faster, it will try and connect
85  * to that Wi-Fi network and switch the request over to it once it is connected.
86  * The cell network may stay connected if there are outstanding requests (from
87  * the same app or from other apps on the system) that match the cell network
88  * but not the Wi-Fi network, such as a request with {@link NetworkCapabilities#NET_CAPABILITY_MMS}.
89  *
90  * When a network is no longer needed to serve any request, the system can
91  * tear it down at any time and usually does so immediately, so make sure to
92  * keep up requests for the networks your app needs.
93  *
94  * <p>By contrast, requests filed with {@link ConnectivityManager#registerNetworkCallback}
95  * will receive callbacks for all matching networks, and will not cause the system to
96  * keep up the networks they match. Use this to listen to networks that the device is
97  * connected to, but that you don't want the system to keep up for your use case.
98  *
99  * <p>Applications build a NetworkRequest and pass it to one of the
100  * {@link ConnectivityManager} methods above together with a
101  * {@link ConnectivityManager.NetworkCallback} object. The callback
102  * will then start receiving method calls about networks that match
103  * the request.
104  *
105  * <p>Networks are brought up and/or matched according to the capabilities
106  * set in the builder. For example, a request with
107  * {@link NetworkCapabilities#NET_CAPABILITY_MMS} lets the system match
108  * and/or bring up a network that is capable to send MMS. A request with
109  * {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED} matches a network
110  * that doesn't charge the user for usage. See
111  * {@link NetworkCapabilities} for a list of capabilities and their
112  * description.
113  *
114  * <p>While all capabilities can be matched with the
115  * {@link ConnectivityManager#registerNetworkCallback} family of methods,
116  * not all capabilities can be used to request that the system brings
117  * up a network with {@link ConnectivityManager#requestNetwork}. For example,
118  * an application cannot use {@link ConnectivityManager#requestNetwork} to
119  * ask the system to bring up a network with
120  * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}, because the
121  * system won't know if a network has a captive portal before it connects
122  * to that network. Similarly, some capabilities may require a specific
123  * permission or privilege to be requested.
124  *
125  * Look up the specific capability and the {@link ConnectivityManager#requestNetwork}
126  * method for limitations applicable to each capability.
127  *
128  * <p>Also, starting with {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, some capabilities
129  * require the application to self-certify by explicitly adding the
130  * {@link android.content.pm.PackageManager#PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES}
131  * property in the AndroidManifest.xml, which points to an XML resource file. In the
132  * XML resource file, the application declares what kind of network capabilities the application
133  * wants to have.
134  *
135  * Here is an example self-certification XML resource file :
136  * <pre>
137  *  {@code
138  *  <network-capabilities-declaration xmlns:android="http://schemas.android.com/apk/res/android">
139  *     <uses-network-capability android:name="NET_CAPABILITY_PRIORITIZE_LATENCY"/>
140  *     <uses-network-capability android:name="NET_CAPABILITY_PRIORITIZE_BANDWIDTH"/>
141  * </network-capabilities-declaration>
142  *  }
143  *  </pre>
144  * Look up the specific capability to learn whether its usage requires this self-certification.
145  */
146 public class NetworkRequest implements Parcelable {
147 
148     /** @hide */
149     public static class Flags {
150         static final String REQUEST_RESTRICTED_WIFI =
151                 "com.android.net.flags.request_restricted_wifi";
152     }
153     /**
154      * The first requestId value that will be allocated.
155      * @hide only used by ConnectivityService.
156      */
157     public static final int FIRST_REQUEST_ID = 1;
158 
159     /**
160      * The requestId value that represents the absence of a request.
161      * @hide only used by ConnectivityService.
162      */
163     public static final int REQUEST_ID_NONE = -1;
164 
165     /**
166      * The {@link NetworkCapabilities} that define this request.
167      * @hide
168      */
169     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
170     public final @NonNull NetworkCapabilities networkCapabilities;
171 
172     /**
173      * Identifies the request.  NetworkRequests should only be constructed by
174      * the Framework and given out to applications as tokens to be used to identify
175      * the request.
176      * @hide
177      */
178     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
179     public final int requestId;
180 
181     /**
182      * Set for legacy requests and the default.  Set to TYPE_NONE for none.
183      * Causes CONNECTIVITY_ACTION broadcasts to be sent.
184      * @hide
185      */
186     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
187     public final int legacyType;
188 
189     /**
190      * A NetworkRequest as used by the system can be one of the following types:
191      *
192      *     - LISTEN, for which the framework will issue callbacks about any
193      *       and all networks that match the specified NetworkCapabilities,
194      *
195      *     - REQUEST, capable of causing a specific network to be created
196      *       first (e.g. a telephony DUN request), the framework will issue
197      *       callbacks about the single, highest scoring current network
198      *       (if any) that matches the specified NetworkCapabilities, or
199      *
200      *     - TRACK_DEFAULT, which causes the framework to issue callbacks for
201      *       the single, highest scoring current network (if any) that will
202      *       be chosen for an app, but which cannot cause the framework to
203      *       either create or retain the existence of any specific network.
204      *
205      *     - TRACK_SYSTEM_DEFAULT, which causes the framework to send callbacks
206      *       for the network (if any) that satisfies the default Internet
207      *       request.
208      *
209      *     - TRACK_BEST, which causes the framework to send callbacks about
210      *       the single, highest scoring current network (if any) that matches
211      *       the specified NetworkCapabilities.
212      *
213      *     - BACKGROUND_REQUEST, like REQUEST but does not cause any networks
214      *       to retain the NET_CAPABILITY_FOREGROUND capability. A network with
215      *       no foreground requests is in the background. A network that has
216      *       one or more background requests and loses its last foreground
217      *       request to a higher-scoring network will not go into the
218      *       background immediately, but will linger and go into the background
219      *       after the linger timeout.
220      *
221      *     - The value NONE is used only by applications. When an application
222      *       creates a NetworkRequest, it does not have a type; the type is set
223      *       by the system depending on the method used to file the request
224      *       (requestNetwork, registerNetworkCallback, etc.).
225      *
226      * @hide
227      */
228     public static enum Type {
229         NONE,
230         LISTEN,
231         TRACK_DEFAULT,
232         REQUEST,
233         BACKGROUND_REQUEST,
234         TRACK_SYSTEM_DEFAULT,
235         LISTEN_FOR_BEST,
236     };
237 
238     /**
239      * The type of the request. This is only used by the system and is always NONE elsewhere.
240      *
241      * @hide
242      */
243     public final Type type;
244 
245     /**
246      * @hide
247      */
NetworkRequest(NetworkCapabilities nc, int legacyType, int rId, Type type)248     public NetworkRequest(NetworkCapabilities nc, int legacyType, int rId, Type type) {
249         if (nc == null) {
250             throw new NullPointerException();
251         }
252         requestId = rId;
253         networkCapabilities = nc;
254         this.legacyType = legacyType;
255         this.type = type;
256     }
257 
258     /**
259      * @hide
260      */
NetworkRequest(NetworkRequest that)261     public NetworkRequest(NetworkRequest that) {
262         networkCapabilities = new NetworkCapabilities(that.networkCapabilities);
263         requestId = that.requestId;
264         this.legacyType = that.legacyType;
265         this.type = that.type;
266     }
267 
268     /**
269      * Builder used to create {@link NetworkRequest} objects.  Specify the Network features
270      * needed in terms of {@link NetworkCapabilities} features
271      */
272     public static class Builder {
273         /**
274          * Capabilities that are currently compatible with VCN networks.
275          */
276         private static final List<Integer> VCN_SUPPORTED_CAPABILITIES = Arrays.asList(
277                 NET_CAPABILITY_CAPTIVE_PORTAL,
278                 NET_CAPABILITY_DUN,
279                 NET_CAPABILITY_FOREGROUND,
280                 NET_CAPABILITY_INTERNET,
281                 NET_CAPABILITY_NOT_CONGESTED,
282                 NET_CAPABILITY_NOT_METERED,
283                 NET_CAPABILITY_NOT_RESTRICTED,
284                 NET_CAPABILITY_NOT_ROAMING,
285                 NET_CAPABILITY_NOT_SUSPENDED,
286                 NET_CAPABILITY_NOT_VPN,
287                 NET_CAPABILITY_PARTIAL_CONNECTIVITY,
288                 NET_CAPABILITY_TEMPORARILY_NOT_METERED,
289                 NET_CAPABILITY_TRUSTED,
290                 NET_CAPABILITY_VALIDATED,
291                 NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED);
292 
293         private final NetworkCapabilities mNetworkCapabilities;
294 
295         // A boolean that represents whether the NOT_VCN_MANAGED capability should be deduced when
296         // the NetworkRequest object is built.
297         private boolean mShouldDeduceNotVcnManaged = true;
298 
299         /**
300          * Default constructor for Builder.
301          */
Builder()302         public Builder() {
303             // By default, restrict this request to networks available to this app.
304             // Apps can rescind this restriction, but ConnectivityService will enforce
305             // it for apps that do not have the NETWORK_SETTINGS permission.
306             mNetworkCapabilities = new NetworkCapabilities();
307             mNetworkCapabilities.setSingleUid(Process.myUid());
308         }
309 
310         /**
311          * Creates a new Builder of NetworkRequest from an existing instance.
312          */
Builder(@onNull final NetworkRequest request)313         public Builder(@NonNull final NetworkRequest request) {
314             Objects.requireNonNull(request);
315             mNetworkCapabilities = request.networkCapabilities;
316             // If the caller constructed the builder from a request, it means the user
317             // might explicitly want the capabilities from the request. Thus, the NOT_VCN_MANAGED
318             // capabilities should not be touched later.
319             mShouldDeduceNotVcnManaged = false;
320         }
321 
322         /**
323          * Build {@link NetworkRequest} give the current set of capabilities.
324          */
build()325         public NetworkRequest build() {
326             // Make a copy of mNetworkCapabilities so we don't inadvertently remove NOT_RESTRICTED
327             // when later an unrestricted capability could be added to mNetworkCapabilities, in
328             // which case NOT_RESTRICTED should be returned to mNetworkCapabilities, which
329             // maybeMarkCapabilitiesRestricted() doesn't add back.
330             final NetworkCapabilities nc = new NetworkCapabilities(mNetworkCapabilities);
331             nc.maybeMarkCapabilitiesRestricted();
332             deduceNotVcnManagedCapability(nc);
333             return new NetworkRequest(nc, ConnectivityManager.TYPE_NONE,
334                     ConnectivityManager.REQUEST_ID_UNSET, Type.NONE);
335         }
336 
337         /**
338          * Add the given capability requirement to this builder.  These represent
339          * the requested network's required capabilities.  Note that when searching
340          * for a network to satisfy a request, all capabilities requested must be
341          * satisfied.
342          *
343          * @param capability The capability to add.
344          * @return The builder to facilitate chaining
345          *         {@code builder.addCapability(...).addCapability();}.
346          */
addCapability(@etworkCapabilities.NetCapability int capability)347         public Builder addCapability(@NetworkCapabilities.NetCapability int capability) {
348             mNetworkCapabilities.addCapability(capability);
349             if (capability == NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) {
350                 mShouldDeduceNotVcnManaged = false;
351             }
352             return this;
353         }
354 
355         /**
356          * Removes (if found) the given capability from this builder instance.
357          *
358          * @param capability The capability to remove.
359          * @return The builder to facilitate chaining.
360          */
removeCapability(@etworkCapabilities.NetCapability int capability)361         public Builder removeCapability(@NetworkCapabilities.NetCapability int capability) {
362             mNetworkCapabilities.removeCapability(capability);
363             if (capability == NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) {
364                 mShouldDeduceNotVcnManaged = false;
365             }
366             return this;
367         }
368 
369         /**
370          * Set the {@code NetworkCapabilities} for this builder instance,
371          * overriding any capabilities that had been previously set.
372          *
373          * @param nc The superseding {@code NetworkCapabilities} instance.
374          * @return The builder to facilitate chaining.
375          * @hide
376          */
setCapabilities(NetworkCapabilities nc)377         public Builder setCapabilities(NetworkCapabilities nc) {
378             mNetworkCapabilities.set(nc);
379             return this;
380         }
381 
382         /**
383          * Sets this request to match only networks that apply to the specified UIDs.
384          *
385          * By default, the set of UIDs is the UID of the calling app, and this request will match
386          * any network that applies to the app. Setting it to {@code null} will observe any
387          * network on the system, even if it does not apply to this app. In this case, any
388          * {@link NetworkSpecifier} set on this request will be redacted or removed to prevent the
389          * application deducing restricted information such as location.
390          *
391          * @param uids The UIDs as a set of {@code Range<Integer>}, or null for everything.
392          * @return The builder to facilitate chaining.
393          * @hide
394          */
395         @NonNull
396         @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
397         @SuppressLint("MissingGetterMatchingBuilder")
setUids(@ullable Set<Range<Integer>> uids)398         public Builder setUids(@Nullable Set<Range<Integer>> uids) {
399             mNetworkCapabilities.setUids(uids);
400             return this;
401         }
402 
403         /**
404          * Add a capability that must not exist in the requested network.
405          * <p>
406          * If the capability was previously added to the list of required capabilities (for
407          * example, it was there by default or added using {@link #addCapability(int)} method), then
408          * it will be removed from the list of required capabilities as well.
409          *
410          * @see #addCapability(int)
411          *
412          * @param capability The capability to add to forbidden capability list.
413          * @return The builder to facilitate chaining.
414          *
415          * @hide
416          */
417         @NonNull
418         @SuppressLint("MissingGetterMatchingBuilder")
419         @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
420         // TODO : @FlaggedApi(Flags.FLAG_FORBIDDEN_CAPABILITY) and public
addForbiddenCapability(@etworkCapabilities.NetCapability int capability)421         public Builder addForbiddenCapability(@NetworkCapabilities.NetCapability int capability) {
422             mNetworkCapabilities.addForbiddenCapability(capability);
423             return this;
424         }
425 
426         /**
427          * Removes (if found) the given forbidden capability from this builder instance.
428          *
429          * @param capability The forbidden capability to remove.
430          * @return The builder to facilitate chaining.
431          *
432          * @hide
433          */
434         @NonNull
435         @SuppressLint("BuilderSetStyle")
436         @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
437         // TODO : @FlaggedApi(Flags.FLAG_FORBIDDEN_CAPABILITY) and public
removeForbiddenCapability( @etworkCapabilities.NetCapability int capability)438         public Builder removeForbiddenCapability(
439                 @NetworkCapabilities.NetCapability int capability) {
440             mNetworkCapabilities.removeForbiddenCapability(capability);
441             return this;
442         }
443 
444         /**
445          * Completely clears all the {@code NetworkCapabilities} from this builder instance,
446          * removing even the capabilities that are set by default when the object is constructed.
447          * Also removes any set forbidden capabilities.
448          *
449          * @return The builder to facilitate chaining.
450          */
451         @NonNull
clearCapabilities()452         public Builder clearCapabilities() {
453             mNetworkCapabilities.clearAll();
454             // If the caller explicitly clear all capabilities, the NOT_VCN_MANAGED capabilities
455             // should not be add back later.
456             mShouldDeduceNotVcnManaged = false;
457             return this;
458         }
459 
460         /**
461          * Adds the given transport requirement to this builder.  These represent
462          * the set of allowed transports for the request.  Only networks using one
463          * of these transports will satisfy the request.  If no particular transports
464          * are required, none should be specified here.
465          *
466          * @param transportType The transport type to add.
467          * @return The builder to facilitate chaining.
468          */
addTransportType(@etworkCapabilities.Transport int transportType)469         public Builder addTransportType(@NetworkCapabilities.Transport int transportType) {
470             mNetworkCapabilities.addTransportType(transportType);
471             return this;
472         }
473 
474         /**
475          * Removes (if found) the given transport from this builder instance.
476          *
477          * @param transportType The transport type to remove.
478          * @return The builder to facilitate chaining.
479          */
removeTransportType(@etworkCapabilities.Transport int transportType)480         public Builder removeTransportType(@NetworkCapabilities.Transport int transportType) {
481             mNetworkCapabilities.removeTransportType(transportType);
482             return this;
483         }
484 
485         /**
486          * @hide
487          */
setLinkUpstreamBandwidthKbps(int upKbps)488         public Builder setLinkUpstreamBandwidthKbps(int upKbps) {
489             mNetworkCapabilities.setLinkUpstreamBandwidthKbps(upKbps);
490             return this;
491         }
492         /**
493          * @hide
494          */
setLinkDownstreamBandwidthKbps(int downKbps)495         public Builder setLinkDownstreamBandwidthKbps(int downKbps) {
496             mNetworkCapabilities.setLinkDownstreamBandwidthKbps(downKbps);
497             return this;
498         }
499 
500         /**
501          * Sets the optional bearer specific network specifier.
502          * This has no meaning if a single transport is also not specified, so calling
503          * this without a single transport set will generate an exception, as will
504          * subsequently adding or removing transports after this is set.
505          * </p>
506          * If the {@code networkSpecifier} is provided, it shall be interpreted as follows:
507          * <ul>
508          * <li>If the specifier can be parsed as an integer, it will be treated as a
509          * {@link android.net TelephonyNetworkSpecifier}, and the provided integer will be
510          * interpreted as a SubscriptionId.
511          * <li>If the value is an ethernet interface name, it will be treated as such.
512          * <li>For all other cases, the behavior is undefined.
513          * </ul>
514          *
515          * @param networkSpecifier A {@code String} of either a SubscriptionId in cellular
516          *                         network request or an ethernet interface name in ethernet
517          *                         network request.
518          *
519          * @deprecated Use {@link #setNetworkSpecifier(NetworkSpecifier)} instead.
520          */
521         @Deprecated
setNetworkSpecifier(String networkSpecifier)522         public Builder setNetworkSpecifier(String networkSpecifier) {
523             try {
524                 int subId = Integer.parseInt(networkSpecifier);
525                 return setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
526                         .setSubscriptionId(subId).build());
527             } catch (NumberFormatException nfe) {
528                 // An EthernetNetworkSpecifier or TestNetworkSpecifier does not accept null or empty
529                 // ("") strings. When network specifiers were strings a null string and an empty
530                 // string were considered equivalent. Hence no meaning is attached to a null or
531                 // empty ("") string.
532                 if (TextUtils.isEmpty(networkSpecifier)) {
533                     return setNetworkSpecifier((NetworkSpecifier) null);
534                 } else if (mNetworkCapabilities.hasTransport(TRANSPORT_TEST)) {
535                     return setNetworkSpecifier(new TestNetworkSpecifier(networkSpecifier));
536                 } else {
537                     return setNetworkSpecifier(new EthernetNetworkSpecifier(networkSpecifier));
538                 }
539             }
540         }
541 
542         /**
543          * Sets the optional bearer specific network specifier.
544          * This has no meaning if a single transport is also not specified, so calling
545          * this without a single transport set will generate an exception, as will
546          * subsequently adding or removing transports after this is set.
547          * </p>
548          *
549          * @param networkSpecifier A concrete, parcelable framework class that extends
550          *                         NetworkSpecifier.
551          */
setNetworkSpecifier(NetworkSpecifier networkSpecifier)552         public Builder setNetworkSpecifier(NetworkSpecifier networkSpecifier) {
553             if (networkSpecifier instanceof MatchAllNetworkSpecifier) {
554                 throw new IllegalArgumentException("A MatchAllNetworkSpecifier is not permitted");
555             }
556             mNetworkCapabilities.setNetworkSpecifier(networkSpecifier);
557             // Do not touch NOT_VCN_MANAGED if the caller needs to access to a very specific
558             // Network.
559             mShouldDeduceNotVcnManaged = false;
560             return this;
561         }
562 
563         /**
564          * Sets the signal strength. This is a signed integer, with higher values indicating a
565          * stronger signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same
566          * RSSI units reported by WifiManager.
567          * <p>
568          * Note that when used to register a network callback, this specifies the minimum acceptable
569          * signal strength. When received as the state of an existing network it specifies the
570          * current value. A value of {@code SIGNAL_STRENGTH_UNSPECIFIED} means no value when
571          * received and has no effect when requesting a callback.
572          *
573          * <p>This method requires the caller to hold the
574          * {@link android.Manifest.permission#NETWORK_SIGNAL_STRENGTH_WAKEUP} permission
575          *
576          * @param signalStrength the bearer-specific signal strength.
577          * @hide
578          */
579         @SystemApi
580         @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP)
setSignalStrength(int signalStrength)581         public @NonNull Builder setSignalStrength(int signalStrength) {
582             mNetworkCapabilities.setSignalStrength(signalStrength);
583             return this;
584         }
585 
586         /**
587          * Deduce the NET_CAPABILITY_NOT_VCN_MANAGED capability from other capabilities
588          * and user intention, which includes:
589          *   1. For the requests that don't have anything besides
590          *      {@link #VCN_SUPPORTED_CAPABILITIES}, add the NET_CAPABILITY_NOT_VCN_MANAGED to
591          *      allow the callers automatically utilize VCN networks if available.
592          *   2. For the requests that explicitly add or remove NET_CAPABILITY_NOT_VCN_MANAGED,
593          *      or has clear intention of tracking specific network,
594          *      do not alter them to allow user fire request that suits their need.
595          *
596          * @hide
597          */
deduceNotVcnManagedCapability(final NetworkCapabilities nc)598         private void deduceNotVcnManagedCapability(final NetworkCapabilities nc) {
599             if (!mShouldDeduceNotVcnManaged) return;
600             for (final int cap : nc.getCapabilities()) {
601                 if (!VCN_SUPPORTED_CAPABILITIES.contains(cap)) return;
602             }
603             nc.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
604         }
605 
606         /**
607          * Sets the optional subscription ID set.
608          * <p>
609          * This specify the subscription IDs requirement.
610          * A network will satisfy this request only if it matches one of the subIds in this set.
611          * An empty set matches all networks, including those without a subId.
612          *
613          * <p>Registering a NetworkRequest with a non-empty set of subIds requires the
614          * NETWORK_FACTORY permission.
615          *
616          * @param subIds A {@code Set} that represents subscription IDs.
617          */
618         @NonNull
619         @FlaggedApi(Flags.REQUEST_RESTRICTED_WIFI)
setSubscriptionIds(@onNull Set<Integer> subIds)620         public Builder setSubscriptionIds(@NonNull Set<Integer> subIds) {
621             mNetworkCapabilities.setSubscriptionIds(subIds);
622             return this;
623         }
624 
625         /**
626          * Specifies whether the built request should also match networks that do not apply to the
627          * calling UID.
628          *
629          * By default, the built request will only match networks that apply to the calling UID.
630          * If this method is called with {@code true}, the built request will match any network on
631          * the system that matches the other parameters of the request. In this case, any
632          * information in the built request that is subject to redaction for security or privacy
633          * purposes, such as a {@link NetworkSpecifier}, will be redacted or removed to prevent the
634          * application deducing sensitive information.
635          *
636          * @param include Whether to match networks that do not apply to the calling UID.
637          * @return The builder to facilitate chaining.
638          */
639         @NonNull
setIncludeOtherUidNetworks(boolean include)640         public Builder setIncludeOtherUidNetworks(boolean include) {
641             if (include) {
642                 mNetworkCapabilities.setUids(null);
643             } else {
644                 mNetworkCapabilities.setSingleUid(Process.myUid());
645             }
646             return this;
647         }
648     }
649 
650     // implement the Parcelable interface
describeContents()651     public int describeContents() {
652         return 0;
653     }
writeToParcel(Parcel dest, int flags)654     public void writeToParcel(Parcel dest, int flags) {
655         networkCapabilities.writeToParcel(dest, flags);
656         dest.writeInt(legacyType);
657         dest.writeInt(requestId);
658         dest.writeString(type.name());
659     }
660 
661     public static final @android.annotation.NonNull Creator<NetworkRequest> CREATOR =
662         new Creator<NetworkRequest>() {
663             public NetworkRequest createFromParcel(Parcel in) {
664                 NetworkCapabilities nc = NetworkCapabilities.CREATOR.createFromParcel(in);
665                 int legacyType = in.readInt();
666                 int requestId = in.readInt();
667                 Type type = Type.valueOf(in.readString());  // IllegalArgumentException if invalid.
668                 NetworkRequest result = new NetworkRequest(nc, legacyType, requestId, type);
669                 return result;
670             }
671             public NetworkRequest[] newArray(int size) {
672                 return new NetworkRequest[size];
673             }
674         };
675 
676     /**
677      * Returns true iff. this NetworkRequest is of type LISTEN.
678      *
679      * @hide
680      */
isListen()681     public boolean isListen() {
682         return type == Type.LISTEN;
683     }
684 
685     /**
686      * Returns true iff. this NetworkRequest is of type LISTEN_FOR_BEST.
687      *
688      * @hide
689      */
isListenForBest()690     public boolean isListenForBest() {
691         return type == Type.LISTEN_FOR_BEST;
692     }
693 
694     /**
695      * Returns true iff. the contained NetworkRequest is one that:
696      *
697      *     - should be associated with at most one satisfying network
698      *       at a time;
699      *
700      *     - should cause a network to be kept up, but not necessarily in
701      *       the foreground, if it is the best network which can satisfy the
702      *       NetworkRequest.
703      *
704      * For full detail of how isRequest() is used for pairing Networks with
705      * NetworkRequests read rematchNetworkAndRequests().
706      *
707      * @hide
708      */
isRequest()709     public boolean isRequest() {
710         return type == Type.REQUEST || type == Type.BACKGROUND_REQUEST;
711     }
712 
713     /**
714      * Returns true iff. this NetworkRequest is of type BACKGROUND_REQUEST.
715      *
716      * @hide
717      */
isBackgroundRequest()718     public boolean isBackgroundRequest() {
719         return type == Type.BACKGROUND_REQUEST;
720     }
721 
722     /**
723      * @see Builder#addCapability(int)
724      */
hasCapability(@etCapability int capability)725     public boolean hasCapability(@NetCapability int capability) {
726         return networkCapabilities.hasCapability(capability);
727     }
728 
729     /**
730      * @see Builder#addForbiddenCapability(int)
731      *
732      * @hide
733      */
734     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
735     // TODO : @FlaggedApi(Flags.FLAG_FORBIDDEN_CAPABILITY) and public instead of @SystemApi
hasForbiddenCapability(@etCapability int capability)736     public boolean hasForbiddenCapability(@NetCapability int capability) {
737         return networkCapabilities.hasForbiddenCapability(capability);
738     }
739 
740     /**
741      * Returns true if and only if the capabilities requested in this NetworkRequest are satisfied
742      * by the provided {@link NetworkCapabilities}.
743      *
744      * @param nc Capabilities that should satisfy this NetworkRequest. null capabilities do not
745      *           satisfy any request.
746      */
canBeSatisfiedBy(@ullable NetworkCapabilities nc)747     public boolean canBeSatisfiedBy(@Nullable NetworkCapabilities nc) {
748         return networkCapabilities.satisfiedByNetworkCapabilities(nc);
749     }
750 
751     /**
752      * @see Builder#addTransportType(int)
753      */
hasTransport(@ransport int transportType)754     public boolean hasTransport(@Transport int transportType) {
755         return networkCapabilities.hasTransport(transportType);
756     }
757 
758     /**
759      * @see Builder#setNetworkSpecifier(NetworkSpecifier)
760      */
761     @Nullable
getNetworkSpecifier()762     public NetworkSpecifier getNetworkSpecifier() {
763         return networkCapabilities.getNetworkSpecifier();
764     }
765 
766     /**
767      * @return the uid of the app making the request.
768      *
769      * Note: This could return {@link Process#INVALID_UID} if the {@link NetworkRequest} object was
770      * not obtained from {@link ConnectivityManager}.
771      * @hide
772      */
773     @SystemApi
getRequestorUid()774     public int getRequestorUid() {
775         return networkCapabilities.getRequestorUid();
776     }
777 
778     /**
779      * @return the package name of the app making the request.
780      *
781      * Note: This could return {@code null} if the {@link NetworkRequest} object was not obtained
782      * from {@link ConnectivityManager}.
783      * @hide
784      */
785     @SystemApi
786     @Nullable
getRequestorPackageName()787     public String getRequestorPackageName() {
788         return networkCapabilities.getRequestorPackageName();
789     }
790 
toString()791     public String toString() {
792         return "NetworkRequest [ " + type + " id=" + requestId +
793                 (legacyType != ConnectivityManager.TYPE_NONE ? ", legacyType=" + legacyType : "") +
794                 ", " + networkCapabilities.toString() + " ]";
795     }
796 
equals(@ullable Object obj)797     public boolean equals(@Nullable Object obj) {
798         if (obj instanceof NetworkRequest == false) return false;
799         NetworkRequest that = (NetworkRequest)obj;
800         return (that.legacyType == this.legacyType &&
801                 that.requestId == this.requestId &&
802                 that.type == this.type &&
803                 Objects.equals(that.networkCapabilities, this.networkCapabilities));
804     }
805 
hashCode()806     public int hashCode() {
807         return Objects.hash(requestId, legacyType, networkCapabilities, type);
808     }
809 
810     /**
811      * Gets all the capabilities set on this {@code NetworkRequest} instance.
812      *
813      * @return an array of capability values for this instance.
814      */
815     @NonNull
getCapabilities()816     public @NetCapability int[] getCapabilities() {
817         // No need to make a defensive copy here as NC#getCapabilities() already returns
818         // a new array.
819         return networkCapabilities.getCapabilities();
820     }
821 
822     /**
823      * Get the enteprise identifiers.
824      *
825      * Get all the enterprise identifiers set on this {@code NetworkCapability}
826      * @return array of all the enterprise identifiers.
827      * @hide
828      */
829     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
getEnterpriseIds()830     public @NonNull @NetworkCapabilities.EnterpriseId int[] getEnterpriseIds() {
831         // No need to make a defensive copy here as NC#getCapabilities() already returns
832         // a new array.
833         return networkCapabilities.getEnterpriseIds();
834     }
835 
836     /**
837      * Tests for the presence of an enterprise identifier on this instance.
838      *
839      * @param enterpriseId the enterprise capability identifier to be tested for.
840      * @return {@code true} if set on this instance.
841      * @hide
842      */
843     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
hasEnterpriseId( @etworkCapabilities.EnterpriseId int enterpriseId)844     public boolean hasEnterpriseId(
845             @NetworkCapabilities.EnterpriseId int enterpriseId) {
846         return networkCapabilities.hasEnterpriseId(enterpriseId);
847     }
848 
849     /**
850      * Gets all the forbidden capabilities set on this {@code NetworkRequest} instance.
851      *
852      * @return an array of forbidden capability values for this instance.
853      *
854      * @hide
855      */
856     @NonNull
857     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
858     // TODO : @FlaggedApi(Flags.FLAG_FORBIDDEN_CAPABILITY) and public instead of @SystemApi
getForbiddenCapabilities()859     public @NetCapability int[] getForbiddenCapabilities() {
860         // No need to make a defensive copy here as NC#getForbiddenCapabilities() already returns
861         // a new array.
862         return networkCapabilities.getForbiddenCapabilities();
863     }
864 
865     /**
866      * Gets all the transports set on this {@code NetworkRequest} instance.
867      *
868      * @return an array of transport type values for this instance.
869      */
870     @NonNull
getTransportTypes()871     public @Transport int[] getTransportTypes() {
872         // No need to make a defensive copy here as NC#getTransportTypes() already returns
873         // a new array.
874         return networkCapabilities.getTransportTypes();
875     }
876 
877     /**
878      * Gets all the subscription ids set on this {@code NetworkRequest} instance.
879      *
880      * @return Set of Integer values for this instance.
881      */
882     @NonNull
883     @FlaggedApi(Flags.REQUEST_RESTRICTED_WIFI)
getSubscriptionIds()884     public Set<Integer> getSubscriptionIds() {
885         // No need to make a defensive copy here as NC#getSubscriptionIds() already returns
886         // a new set.
887         return networkCapabilities.getSubscriptionIds();
888     }
889 }
890