• 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.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.SystemApi;
23 import android.annotation.TestApi;
24 import android.annotation.UnsupportedAppUsage;
25 import android.net.ConnectivityManager.NetworkCallback;
26 import android.os.Build;
27 import android.os.Parcel;
28 import android.os.Parcelable;
29 import android.util.ArraySet;
30 import android.util.proto.ProtoOutputStream;
31 
32 import com.android.internal.annotations.VisibleForTesting;
33 import com.android.internal.util.BitUtils;
34 import com.android.internal.util.Preconditions;
35 
36 import java.lang.annotation.Retention;
37 import java.lang.annotation.RetentionPolicy;
38 import java.util.Objects;
39 import java.util.Set;
40 import java.util.StringJoiner;
41 
42 /**
43  * Representation of the capabilities of an active network. Instances are
44  * typically obtained through
45  * {@link NetworkCallback#onCapabilitiesChanged(Network, NetworkCapabilities)}
46  * or {@link ConnectivityManager#getNetworkCapabilities(Network)}.
47  * <p>
48  * This replaces the old {@link ConnectivityManager#TYPE_MOBILE} method of
49  * network selection. Rather than indicate a need for Wi-Fi because an
50  * application needs high bandwidth and risk obsolescence when a new, fast
51  * network appears (like LTE), the application should specify it needs high
52  * bandwidth. Similarly if an application needs an unmetered network for a bulk
53  * transfer it can specify that rather than assuming all cellular based
54  * connections are metered and all Wi-Fi based connections are not.
55  */
56 public final class NetworkCapabilities implements Parcelable {
57     private static final String TAG = "NetworkCapabilities";
58     private static final int INVALID_UID = -1;
59 
60     /**
61      * @hide
62      */
63     @UnsupportedAppUsage
NetworkCapabilities()64     public NetworkCapabilities() {
65         clearAll();
66         mNetworkCapabilities = DEFAULT_CAPABILITIES;
67     }
68 
NetworkCapabilities(NetworkCapabilities nc)69     public NetworkCapabilities(NetworkCapabilities nc) {
70         if (nc != null) {
71             set(nc);
72         }
73     }
74 
75     /**
76      * Completely clears the contents of this object, removing even the capabilities that are set
77      * by default when the object is constructed.
78      * @hide
79      */
clearAll()80     public void clearAll() {
81         mNetworkCapabilities = mTransportTypes = mUnwantedNetworkCapabilities = 0;
82         mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
83         mNetworkSpecifier = null;
84         mTransportInfo = null;
85         mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
86         mUids = null;
87         mEstablishingVpnAppUid = INVALID_UID;
88         mSSID = null;
89     }
90 
91     /**
92      * Set all contents of this object to the contents of a NetworkCapabilities.
93      * @hide
94      */
set(@onNull NetworkCapabilities nc)95     public void set(@NonNull NetworkCapabilities nc) {
96         mNetworkCapabilities = nc.mNetworkCapabilities;
97         mTransportTypes = nc.mTransportTypes;
98         mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps;
99         mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
100         mNetworkSpecifier = nc.mNetworkSpecifier;
101         mTransportInfo = nc.mTransportInfo;
102         mSignalStrength = nc.mSignalStrength;
103         setUids(nc.mUids); // Will make the defensive copy
104         mEstablishingVpnAppUid = nc.mEstablishingVpnAppUid;
105         mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities;
106         mSSID = nc.mSSID;
107     }
108 
109     /**
110      * Represents the network's capabilities.  If any are specified they will be satisfied
111      * by any Network that matches all of them.
112      */
113     @UnsupportedAppUsage
114     private long mNetworkCapabilities;
115 
116     /**
117      * If any capabilities specified here they must not exist in the matching Network.
118      */
119     private long mUnwantedNetworkCapabilities;
120 
121     /** @hide */
122     @Retention(RetentionPolicy.SOURCE)
123     @IntDef(prefix = { "NET_CAPABILITY_" }, value = {
124             NET_CAPABILITY_MMS,
125             NET_CAPABILITY_SUPL,
126             NET_CAPABILITY_DUN,
127             NET_CAPABILITY_FOTA,
128             NET_CAPABILITY_IMS,
129             NET_CAPABILITY_CBS,
130             NET_CAPABILITY_WIFI_P2P,
131             NET_CAPABILITY_IA,
132             NET_CAPABILITY_RCS,
133             NET_CAPABILITY_XCAP,
134             NET_CAPABILITY_EIMS,
135             NET_CAPABILITY_NOT_METERED,
136             NET_CAPABILITY_INTERNET,
137             NET_CAPABILITY_NOT_RESTRICTED,
138             NET_CAPABILITY_TRUSTED,
139             NET_CAPABILITY_NOT_VPN,
140             NET_CAPABILITY_VALIDATED,
141             NET_CAPABILITY_CAPTIVE_PORTAL,
142             NET_CAPABILITY_NOT_ROAMING,
143             NET_CAPABILITY_FOREGROUND,
144             NET_CAPABILITY_NOT_CONGESTED,
145             NET_CAPABILITY_NOT_SUSPENDED,
146             NET_CAPABILITY_OEM_PAID,
147             NET_CAPABILITY_MCX,
148             NET_CAPABILITY_PARTIAL_CONNECTIVITY,
149     })
150     public @interface NetCapability { }
151 
152     /**
153      * Indicates this is a network that has the ability to reach the
154      * carrier's MMSC for sending and receiving MMS messages.
155      */
156     public static final int NET_CAPABILITY_MMS            = 0;
157 
158     /**
159      * Indicates this is a network that has the ability to reach the carrier's
160      * SUPL server, used to retrieve GPS information.
161      */
162     public static final int NET_CAPABILITY_SUPL           = 1;
163 
164     /**
165      * Indicates this is a network that has the ability to reach the carrier's
166      * DUN or tethering gateway.
167      */
168     public static final int NET_CAPABILITY_DUN            = 2;
169 
170     /**
171      * Indicates this is a network that has the ability to reach the carrier's
172      * FOTA portal, used for over the air updates.
173      */
174     public static final int NET_CAPABILITY_FOTA           = 3;
175 
176     /**
177      * Indicates this is a network that has the ability to reach the carrier's
178      * IMS servers, used for network registration and signaling.
179      */
180     public static final int NET_CAPABILITY_IMS            = 4;
181 
182     /**
183      * Indicates this is a network that has the ability to reach the carrier's
184      * CBS servers, used for carrier specific services.
185      */
186     public static final int NET_CAPABILITY_CBS            = 5;
187 
188     /**
189      * Indicates this is a network that has the ability to reach a Wi-Fi direct
190      * peer.
191      */
192     public static final int NET_CAPABILITY_WIFI_P2P       = 6;
193 
194     /**
195      * Indicates this is a network that has the ability to reach a carrier's
196      * Initial Attach servers.
197      */
198     public static final int NET_CAPABILITY_IA             = 7;
199 
200     /**
201      * Indicates this is a network that has the ability to reach a carrier's
202      * RCS servers, used for Rich Communication Services.
203      */
204     public static final int NET_CAPABILITY_RCS            = 8;
205 
206     /**
207      * Indicates this is a network that has the ability to reach a carrier's
208      * XCAP servers, used for configuration and control.
209      */
210     public static final int NET_CAPABILITY_XCAP           = 9;
211 
212     /**
213      * Indicates this is a network that has the ability to reach a carrier's
214      * Emergency IMS servers or other services, used for network signaling
215      * during emergency calls.
216      */
217     public static final int NET_CAPABILITY_EIMS           = 10;
218 
219     /**
220      * Indicates that this network is unmetered.
221      */
222     public static final int NET_CAPABILITY_NOT_METERED    = 11;
223 
224     /**
225      * Indicates that this network should be able to reach the internet.
226      */
227     public static final int NET_CAPABILITY_INTERNET       = 12;
228 
229     /**
230      * Indicates that this network is available for general use.  If this is not set
231      * applications should not attempt to communicate on this network.  Note that this
232      * is simply informative and not enforcement - enforcement is handled via other means.
233      * Set by default.
234      */
235     public static final int NET_CAPABILITY_NOT_RESTRICTED = 13;
236 
237     /**
238      * Indicates that the user has indicated implicit trust of this network.  This
239      * generally means it's a sim-selected carrier, a plugged in ethernet, a paired
240      * BT device or a wifi the user asked to connect to.  Untrusted networks
241      * are probably limited to unknown wifi AP.  Set by default.
242      */
243     public static final int NET_CAPABILITY_TRUSTED        = 14;
244 
245     /**
246      * Indicates that this network is not a VPN.  This capability is set by default and should be
247      * explicitly cleared for VPN networks.
248      */
249     public static final int NET_CAPABILITY_NOT_VPN        = 15;
250 
251     /**
252      * Indicates that connectivity on this network was successfully validated. For example, for a
253      * network with NET_CAPABILITY_INTERNET, it means that Internet connectivity was successfully
254      * detected.
255      */
256     public static final int NET_CAPABILITY_VALIDATED      = 16;
257 
258     /**
259      * Indicates that this network was found to have a captive portal in place last time it was
260      * probed.
261      */
262     public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17;
263 
264     /**
265      * Indicates that this network is not roaming.
266      */
267     public static final int NET_CAPABILITY_NOT_ROAMING = 18;
268 
269     /**
270      * Indicates that this network is available for use by apps, and not a network that is being
271      * kept up in the background to facilitate fast network switching.
272      */
273     public static final int NET_CAPABILITY_FOREGROUND = 19;
274 
275     /**
276      * Indicates that this network is not congested.
277      * <p>
278      * When a network is congested, applications should defer network traffic
279      * that can be done at a later time, such as uploading analytics.
280      */
281     public static final int NET_CAPABILITY_NOT_CONGESTED = 20;
282 
283     /**
284      * Indicates that this network is not currently suspended.
285      * <p>
286      * When a network is suspended, the network's IP addresses and any connections
287      * established on the network remain valid, but the network is temporarily unable
288      * to transfer data. This can happen, for example, if a cellular network experiences
289      * a temporary loss of signal, such as when driving through a tunnel, etc.
290      * A network with this capability is not suspended, so is expected to be able to
291      * transfer data.
292      */
293     public static final int NET_CAPABILITY_NOT_SUSPENDED = 21;
294 
295     /**
296      * Indicates that traffic that goes through this network is paid by oem. For example,
297      * this network can be used by system apps to upload telemetry data.
298      * @hide
299      */
300     @SystemApi
301     public static final int NET_CAPABILITY_OEM_PAID = 22;
302 
303     /**
304      * Indicates this is a network that has the ability to reach a carrier's Mission Critical
305      * servers.
306      */
307     public static final int NET_CAPABILITY_MCX = 23;
308 
309     /**
310      * Indicates that this network was tested to only provide partial connectivity.
311      * @hide
312      */
313     @SystemApi
314     public static final int NET_CAPABILITY_PARTIAL_CONNECTIVITY = 24;
315 
316     private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
317     private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_PARTIAL_CONNECTIVITY;
318 
319     /**
320      * Network capabilities that are expected to be mutable, i.e., can change while a particular
321      * network is connected.
322      */
323     private static final long MUTABLE_CAPABILITIES =
324             // TRUSTED can change when user explicitly connects to an untrusted network in Settings.
325             // http://b/18206275
326             (1 << NET_CAPABILITY_TRUSTED)
327             | (1 << NET_CAPABILITY_VALIDATED)
328             | (1 << NET_CAPABILITY_CAPTIVE_PORTAL)
329             | (1 << NET_CAPABILITY_NOT_ROAMING)
330             | (1 << NET_CAPABILITY_FOREGROUND)
331             | (1 << NET_CAPABILITY_NOT_CONGESTED)
332             | (1 << NET_CAPABILITY_NOT_SUSPENDED)
333             | (1 << NET_CAPABILITY_PARTIAL_CONNECTIVITY);
334 
335     /**
336      * Network capabilities that are not allowed in NetworkRequests. This exists because the
337      * NetworkFactory / NetworkAgent model does not deal well with the situation where a
338      * capability's presence cannot be known in advance. If such a capability is requested, then we
339      * can get into a cycle where the NetworkFactory endlessly churns out NetworkAgents that then
340      * get immediately torn down because they do not have the requested capability.
341      */
342     private static final long NON_REQUESTABLE_CAPABILITIES =
343             MUTABLE_CAPABILITIES & ~(1 << NET_CAPABILITY_TRUSTED);
344 
345     /**
346      * Capabilities that are set by default when the object is constructed.
347      */
348     private static final long DEFAULT_CAPABILITIES =
349             (1 << NET_CAPABILITY_NOT_RESTRICTED) |
350             (1 << NET_CAPABILITY_TRUSTED) |
351             (1 << NET_CAPABILITY_NOT_VPN);
352 
353     /**
354      * Capabilities that suggest that a network is restricted.
355      * {@see #maybeMarkCapabilitiesRestricted}, {@see #FORCE_RESTRICTED_CAPABILITIES}
356      */
357     @VisibleForTesting
358     /* package */ static final long RESTRICTED_CAPABILITIES =
359             (1 << NET_CAPABILITY_CBS) |
360             (1 << NET_CAPABILITY_DUN) |
361             (1 << NET_CAPABILITY_EIMS) |
362             (1 << NET_CAPABILITY_FOTA) |
363             (1 << NET_CAPABILITY_IA) |
364             (1 << NET_CAPABILITY_IMS) |
365             (1 << NET_CAPABILITY_RCS) |
366             (1 << NET_CAPABILITY_XCAP) |
367             (1 << NET_CAPABILITY_MCX);
368 
369     /**
370      * Capabilities that force network to be restricted.
371      * {@see #maybeMarkCapabilitiesRestricted}.
372      */
373     private static final long FORCE_RESTRICTED_CAPABILITIES =
374             (1 << NET_CAPABILITY_OEM_PAID);
375 
376     /**
377      * Capabilities that suggest that a network is unrestricted.
378      * {@see #maybeMarkCapabilitiesRestricted}.
379      */
380     @VisibleForTesting
381     /* package */ static final long UNRESTRICTED_CAPABILITIES =
382             (1 << NET_CAPABILITY_INTERNET) |
383             (1 << NET_CAPABILITY_MMS) |
384             (1 << NET_CAPABILITY_SUPL) |
385             (1 << NET_CAPABILITY_WIFI_P2P);
386 
387     /**
388      * Capabilities that are managed by ConnectivityService.
389      */
390     private static final long CONNECTIVITY_MANAGED_CAPABILITIES =
391             (1 << NET_CAPABILITY_VALIDATED)
392             | (1 << NET_CAPABILITY_CAPTIVE_PORTAL)
393             | (1 << NET_CAPABILITY_FOREGROUND)
394             | (1 << NET_CAPABILITY_PARTIAL_CONNECTIVITY);
395 
396     /**
397      * Adds the given capability to this {@code NetworkCapability} instance.
398      * Multiple capabilities may be applied sequentially.  Note that when searching
399      * for a network to satisfy a request, all capabilities requested must be satisfied.
400      * <p>
401      * If the given capability was previously added to the list of unwanted capabilities
402      * then the capability will also be removed from the list of unwanted capabilities.
403      *
404      * @param capability the capability to be added.
405      * @return This NetworkCapabilities instance, to facilitate chaining.
406      * @hide
407      */
408     @UnsupportedAppUsage
addCapability(@etCapability int capability)409     public @NonNull NetworkCapabilities addCapability(@NetCapability int capability) {
410         checkValidCapability(capability);
411         mNetworkCapabilities |= 1 << capability;
412         mUnwantedNetworkCapabilities &= ~(1 << capability);  // remove from unwanted capability list
413         return this;
414     }
415 
416     /**
417      * Adds the given capability to the list of unwanted capabilities of this
418      * {@code NetworkCapability} instance.  Multiple unwanted capabilities may be applied
419      * sequentially.  Note that when searching for a network to satisfy a request, the network
420      * must not contain any capability from unwanted capability list.
421      * <p>
422      * If the capability was previously added to the list of required capabilities (for
423      * example, it was there by default or added using {@link #addCapability(int)} method), then
424      * it will be removed from the list of required capabilities as well.
425      *
426      * @see #addCapability(int)
427      * @hide
428      */
addUnwantedCapability(@etCapability int capability)429     public void addUnwantedCapability(@NetCapability int capability) {
430         checkValidCapability(capability);
431         mUnwantedNetworkCapabilities |= 1 << capability;
432         mNetworkCapabilities &= ~(1 << capability);  // remove from requested capabilities
433     }
434 
435     /**
436      * Removes (if found) the given capability from this {@code NetworkCapability} instance.
437      * <p>
438      * Note that this method removes capabilities that were added via {@link #addCapability(int)},
439      * {@link #addUnwantedCapability(int)} or {@link #setCapabilities(int[], int[])} .
440      *
441      * @param capability the capability to be removed.
442      * @return This NetworkCapabilities instance, to facilitate chaining.
443      * @hide
444      */
445     @UnsupportedAppUsage
removeCapability(@etCapability int capability)446     public @NonNull NetworkCapabilities removeCapability(@NetCapability int capability) {
447         checkValidCapability(capability);
448         final long mask = ~(1 << capability);
449         mNetworkCapabilities &= mask;
450         mUnwantedNetworkCapabilities &= mask;
451         return this;
452     }
453 
454     /**
455      * Sets (or clears) the given capability on this {@link NetworkCapabilities}
456      * instance.
457      *
458      * @hide
459      */
setCapability(@etCapability int capability, boolean value)460     public @NonNull NetworkCapabilities setCapability(@NetCapability int capability,
461             boolean value) {
462         if (value) {
463             addCapability(capability);
464         } else {
465             removeCapability(capability);
466         }
467         return this;
468     }
469 
470     /**
471      * Gets all the capabilities set on this {@code NetworkCapability} instance.
472      *
473      * @return an array of capability values for this instance.
474      * @hide
475      */
476     @TestApi
getCapabilities()477     public @NetCapability int[] getCapabilities() {
478         return BitUtils.unpackBits(mNetworkCapabilities);
479     }
480 
481     /**
482      * Gets all the unwanted capabilities set on this {@code NetworkCapability} instance.
483      *
484      * @return an array of unwanted capability values for this instance.
485      * @hide
486      */
getUnwantedCapabilities()487     public @NetCapability int[] getUnwantedCapabilities() {
488         return BitUtils.unpackBits(mUnwantedNetworkCapabilities);
489     }
490 
491 
492     /**
493      * Sets all the capabilities set on this {@code NetworkCapability} instance.
494      * This overwrites any existing capabilities.
495      *
496      * @hide
497      */
setCapabilities(@etCapability int[] capabilities, @NetCapability int[] unwantedCapabilities)498     public void setCapabilities(@NetCapability int[] capabilities,
499             @NetCapability int[] unwantedCapabilities) {
500         mNetworkCapabilities = BitUtils.packBits(capabilities);
501         mUnwantedNetworkCapabilities = BitUtils.packBits(unwantedCapabilities);
502     }
503 
504     /**
505      * @deprecated use {@link #setCapabilities(int[], int[])}
506      * @hide
507      */
508     @Deprecated
setCapabilities(@etCapability int[] capabilities)509     public void setCapabilities(@NetCapability int[] capabilities) {
510         setCapabilities(capabilities, new int[] {});
511     }
512 
513     /**
514      * Tests for the presence of a capability on this instance.
515      *
516      * @param capability the capabilities to be tested for.
517      * @return {@code true} if set on this instance.
518      */
hasCapability(@etCapability int capability)519     public boolean hasCapability(@NetCapability int capability) {
520         return isValidCapability(capability)
521                 && ((mNetworkCapabilities & (1 << capability)) != 0);
522     }
523 
524     /** @hide */
hasUnwantedCapability(@etCapability int capability)525     public boolean hasUnwantedCapability(@NetCapability int capability) {
526         return isValidCapability(capability)
527                 && ((mUnwantedNetworkCapabilities & (1 << capability)) != 0);
528     }
529 
530     /**
531      * Check if this NetworkCapabilities has system managed capabilities or not.
532      * @hide
533      */
hasConnectivityManagedCapability()534     public boolean hasConnectivityManagedCapability() {
535         return ((mNetworkCapabilities & CONNECTIVITY_MANAGED_CAPABILITIES) != 0);
536     }
537 
538     /** Note this method may result in having the same capability in wanted and unwanted lists. */
combineNetCapabilities(@onNull NetworkCapabilities nc)539     private void combineNetCapabilities(@NonNull NetworkCapabilities nc) {
540         this.mNetworkCapabilities |= nc.mNetworkCapabilities;
541         this.mUnwantedNetworkCapabilities |= nc.mUnwantedNetworkCapabilities;
542     }
543 
544     /**
545      * Convenience function that returns a human-readable description of the first mutable
546      * capability we find. Used to present an error message to apps that request mutable
547      * capabilities.
548      *
549      * @hide
550      */
describeFirstNonRequestableCapability()551     public @Nullable String describeFirstNonRequestableCapability() {
552         final long nonRequestable = (mNetworkCapabilities | mUnwantedNetworkCapabilities)
553                 & NON_REQUESTABLE_CAPABILITIES;
554 
555         if (nonRequestable != 0) {
556             return capabilityNameOf(BitUtils.unpackBits(nonRequestable)[0]);
557         }
558         if (mLinkUpBandwidthKbps != 0 || mLinkDownBandwidthKbps != 0) return "link bandwidth";
559         if (hasSignalStrength()) return "signalStrength";
560         return null;
561     }
562 
satisfiedByNetCapabilities(@onNull NetworkCapabilities nc, boolean onlyImmutable)563     private boolean satisfiedByNetCapabilities(@NonNull NetworkCapabilities nc,
564             boolean onlyImmutable) {
565         long requestedCapabilities = mNetworkCapabilities;
566         long requestedUnwantedCapabilities = mUnwantedNetworkCapabilities;
567         long providedCapabilities = nc.mNetworkCapabilities;
568 
569         if (onlyImmutable) {
570             requestedCapabilities &= ~MUTABLE_CAPABILITIES;
571             requestedUnwantedCapabilities &= ~MUTABLE_CAPABILITIES;
572         }
573         return ((providedCapabilities & requestedCapabilities) == requestedCapabilities)
574                 && ((requestedUnwantedCapabilities & providedCapabilities) == 0);
575     }
576 
577     /** @hide */
equalsNetCapabilities(@onNull NetworkCapabilities nc)578     public boolean equalsNetCapabilities(@NonNull NetworkCapabilities nc) {
579         return (nc.mNetworkCapabilities == this.mNetworkCapabilities)
580                 && (nc.mUnwantedNetworkCapabilities == this.mUnwantedNetworkCapabilities);
581     }
582 
equalsNetCapabilitiesRequestable(@onNull NetworkCapabilities that)583     private boolean equalsNetCapabilitiesRequestable(@NonNull NetworkCapabilities that) {
584         return ((this.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) ==
585                 (that.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES))
586                 && ((this.mUnwantedNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) ==
587                 (that.mUnwantedNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES));
588     }
589 
590     /**
591      * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if all the capabilities it provides are
592      * typically provided by restricted networks.
593      *
594      * TODO: consider:
595      * - Renaming it to guessRestrictedCapability and make it set the
596      *   restricted capability bit in addition to clearing it.
597      * @hide
598      */
maybeMarkCapabilitiesRestricted()599     public void maybeMarkCapabilitiesRestricted() {
600         // Check if we have any capability that forces the network to be restricted.
601         final boolean forceRestrictedCapability =
602                 (mNetworkCapabilities & FORCE_RESTRICTED_CAPABILITIES) != 0;
603 
604         // Verify there aren't any unrestricted capabilities.  If there are we say
605         // the whole thing is unrestricted unless it is forced to be restricted.
606         final boolean hasUnrestrictedCapabilities =
607                 (mNetworkCapabilities & UNRESTRICTED_CAPABILITIES) != 0;
608 
609         // Must have at least some restricted capabilities.
610         final boolean hasRestrictedCapabilities =
611                 (mNetworkCapabilities & RESTRICTED_CAPABILITIES) != 0;
612 
613         if (forceRestrictedCapability
614                 || (hasRestrictedCapabilities && !hasUnrestrictedCapabilities)) {
615             removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
616         }
617     }
618 
619     /**
620      * Representing the transport type.  Apps should generally not care about transport.  A
621      * request for a fast internet connection could be satisfied by a number of different
622      * transports.  If any are specified here it will be satisfied a Network that matches
623      * any of them.  If a caller doesn't care about the transport it should not specify any.
624      */
625     private long mTransportTypes;
626 
627     /** @hide */
628     @Retention(RetentionPolicy.SOURCE)
629     @IntDef(prefix = { "TRANSPORT_" }, value = {
630             TRANSPORT_CELLULAR,
631             TRANSPORT_WIFI,
632             TRANSPORT_BLUETOOTH,
633             TRANSPORT_ETHERNET,
634             TRANSPORT_VPN,
635             TRANSPORT_WIFI_AWARE,
636             TRANSPORT_LOWPAN,
637             TRANSPORT_TEST,
638     })
639     public @interface Transport { }
640 
641     /**
642      * Indicates this network uses a Cellular transport.
643      */
644     public static final int TRANSPORT_CELLULAR = 0;
645 
646     /**
647      * Indicates this network uses a Wi-Fi transport.
648      */
649     public static final int TRANSPORT_WIFI = 1;
650 
651     /**
652      * Indicates this network uses a Bluetooth transport.
653      */
654     public static final int TRANSPORT_BLUETOOTH = 2;
655 
656     /**
657      * Indicates this network uses an Ethernet transport.
658      */
659     public static final int TRANSPORT_ETHERNET = 3;
660 
661     /**
662      * Indicates this network uses a VPN transport.
663      */
664     public static final int TRANSPORT_VPN = 4;
665 
666     /**
667      * Indicates this network uses a Wi-Fi Aware transport.
668      */
669     public static final int TRANSPORT_WIFI_AWARE = 5;
670 
671     /**
672      * Indicates this network uses a LoWPAN transport.
673      */
674     public static final int TRANSPORT_LOWPAN = 6;
675 
676     /**
677      * Indicates this network uses a Test-only virtual interface as a transport.
678      *
679      * @hide
680      */
681     @TestApi
682     public static final int TRANSPORT_TEST = 7;
683 
684     /** @hide */
685     public static final int MIN_TRANSPORT = TRANSPORT_CELLULAR;
686     /** @hide */
687     public static final int MAX_TRANSPORT = TRANSPORT_TEST;
688 
689     /** @hide */
isValidTransport(@ransport int transportType)690     public static boolean isValidTransport(@Transport int transportType) {
691         return (MIN_TRANSPORT <= transportType) && (transportType <= MAX_TRANSPORT);
692     }
693 
694     private static final String[] TRANSPORT_NAMES = {
695         "CELLULAR",
696         "WIFI",
697         "BLUETOOTH",
698         "ETHERNET",
699         "VPN",
700         "WIFI_AWARE",
701         "LOWPAN",
702         "TEST"
703     };
704 
705     /**
706      * Adds the given transport type to this {@code NetworkCapability} instance.
707      * Multiple transports may be applied sequentially.  Note that when searching
708      * for a network to satisfy a request, any listed in the request will satisfy the request.
709      * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a
710      * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network
711      * to be selected.  This is logically different than
712      * {@code NetworkCapabilities.NET_CAPABILITY_*} listed above.
713      *
714      * @param transportType the transport type to be added.
715      * @return This NetworkCapabilities instance, to facilitate chaining.
716      * @hide
717      */
718     @UnsupportedAppUsage
addTransportType(@ransport int transportType)719     public @NonNull NetworkCapabilities addTransportType(@Transport int transportType) {
720         checkValidTransportType(transportType);
721         mTransportTypes |= 1 << transportType;
722         setNetworkSpecifier(mNetworkSpecifier); // used for exception checking
723         return this;
724     }
725 
726     /**
727      * Removes (if found) the given transport from this {@code NetworkCapability} instance.
728      *
729      * @param transportType the transport type to be removed.
730      * @return This NetworkCapabilities instance, to facilitate chaining.
731      * @hide
732      */
removeTransportType(@ransport int transportType)733     public @NonNull NetworkCapabilities removeTransportType(@Transport int transportType) {
734         checkValidTransportType(transportType);
735         mTransportTypes &= ~(1 << transportType);
736         setNetworkSpecifier(mNetworkSpecifier); // used for exception checking
737         return this;
738     }
739 
740     /**
741      * Sets (or clears) the given transport on this {@link NetworkCapabilities}
742      * instance.
743      *
744      * @hide
745      */
setTransportType(@ransport int transportType, boolean value)746     public @NonNull NetworkCapabilities setTransportType(@Transport int transportType,
747             boolean value) {
748         if (value) {
749             addTransportType(transportType);
750         } else {
751             removeTransportType(transportType);
752         }
753         return this;
754     }
755 
756     /**
757      * Gets all the transports set on this {@code NetworkCapability} instance.
758      *
759      * @return an array of transport type values for this instance.
760      * @hide
761      */
762     @TestApi
763     @SystemApi
getTransportTypes()764     @NonNull public @Transport int[] getTransportTypes() {
765         return BitUtils.unpackBits(mTransportTypes);
766     }
767 
768     /**
769      * Sets all the transports set on this {@code NetworkCapability} instance.
770      * This overwrites any existing transports.
771      *
772      * @hide
773      */
setTransportTypes(@ransport int[] transportTypes)774     public void setTransportTypes(@Transport int[] transportTypes) {
775         mTransportTypes = BitUtils.packBits(transportTypes);
776     }
777 
778     /**
779      * Tests for the presence of a transport on this instance.
780      *
781      * @param transportType the transport type to be tested for.
782      * @return {@code true} if set on this instance.
783      */
hasTransport(@ransport int transportType)784     public boolean hasTransport(@Transport int transportType) {
785         return isValidTransport(transportType) && ((mTransportTypes & (1 << transportType)) != 0);
786     }
787 
combineTransportTypes(NetworkCapabilities nc)788     private void combineTransportTypes(NetworkCapabilities nc) {
789         this.mTransportTypes |= nc.mTransportTypes;
790     }
791 
satisfiedByTransportTypes(NetworkCapabilities nc)792     private boolean satisfiedByTransportTypes(NetworkCapabilities nc) {
793         return ((this.mTransportTypes == 0) ||
794                 ((this.mTransportTypes & nc.mTransportTypes) != 0));
795     }
796 
797     /** @hide */
equalsTransportTypes(NetworkCapabilities nc)798     public boolean equalsTransportTypes(NetworkCapabilities nc) {
799         return (nc.mTransportTypes == this.mTransportTypes);
800     }
801 
802     /**
803      * UID of the app that manages this network, or INVALID_UID if none/unknown.
804      *
805      * This field keeps track of the UID of the app that created this network and is in charge
806      * of managing it. In the practice, it is used to store the UID of VPN apps so it is named
807      * accordingly, but it may be renamed if other mechanisms are offered for third party apps
808      * to create networks.
809      *
810      * Because this field is only used in the services side (and to avoid apps being able to
811      * set this to whatever they want), this field is not parcelled and will not be conserved
812      * across the IPC boundary.
813      * @hide
814      */
815     private int mEstablishingVpnAppUid = INVALID_UID;
816 
817     /**
818      * Set the UID of the managing app.
819      * @hide
820      */
setEstablishingVpnAppUid(final int uid)821     public void setEstablishingVpnAppUid(final int uid) {
822         mEstablishingVpnAppUid = uid;
823     }
824 
825     /** @hide */
getEstablishingVpnAppUid()826     public int getEstablishingVpnAppUid() {
827         return mEstablishingVpnAppUid;
828     }
829 
830     /**
831      * Value indicating that link bandwidth is unspecified.
832      * @hide
833      */
834     public static final int LINK_BANDWIDTH_UNSPECIFIED = 0;
835 
836     /**
837      * Passive link bandwidth.  This is a rough guide of the expected peak bandwidth
838      * for the first hop on the given transport.  It is not measured, but may take into account
839      * link parameters (Radio technology, allocated channels, etc).
840      */
841     private int mLinkUpBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
842     private int mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
843 
844     /**
845      * Sets the upstream bandwidth for this network in Kbps.  This always only refers to
846      * the estimated first hop transport bandwidth.
847      * <p>
848      * Note that when used to request a network, this specifies the minimum acceptable.
849      * When received as the state of an existing network this specifies the typical
850      * first hop bandwidth expected.  This is never measured, but rather is inferred
851      * from technology type and other link parameters.  It could be used to differentiate
852      * between very slow 1xRTT cellular links and other faster networks or even between
853      * 802.11b vs 802.11AC wifi technologies.  It should not be used to differentiate between
854      * fast backhauls and slow backhauls.
855      *
856      * @param upKbps the estimated first hop upstream (device to network) bandwidth.
857      * @hide
858      */
setLinkUpstreamBandwidthKbps(int upKbps)859     public @NonNull NetworkCapabilities setLinkUpstreamBandwidthKbps(int upKbps) {
860         mLinkUpBandwidthKbps = upKbps;
861         return this;
862     }
863 
864     /**
865      * Retrieves the upstream bandwidth for this network in Kbps.  This always only refers to
866      * the estimated first hop transport bandwidth.
867      *
868      * @return The estimated first hop upstream (device to network) bandwidth.
869      */
getLinkUpstreamBandwidthKbps()870     public int getLinkUpstreamBandwidthKbps() {
871         return mLinkUpBandwidthKbps;
872     }
873 
874     /**
875      * Sets the downstream bandwidth for this network in Kbps.  This always only refers to
876      * the estimated first hop transport bandwidth.
877      * <p>
878      * Note that when used to request a network, this specifies the minimum acceptable.
879      * When received as the state of an existing network this specifies the typical
880      * first hop bandwidth expected.  This is never measured, but rather is inferred
881      * from technology type and other link parameters.  It could be used to differentiate
882      * between very slow 1xRTT cellular links and other faster networks or even between
883      * 802.11b vs 802.11AC wifi technologies.  It should not be used to differentiate between
884      * fast backhauls and slow backhauls.
885      *
886      * @param downKbps the estimated first hop downstream (network to device) bandwidth.
887      * @hide
888      */
setLinkDownstreamBandwidthKbps(int downKbps)889     public @NonNull NetworkCapabilities setLinkDownstreamBandwidthKbps(int downKbps) {
890         mLinkDownBandwidthKbps = downKbps;
891         return this;
892     }
893 
894     /**
895      * Retrieves the downstream bandwidth for this network in Kbps.  This always only refers to
896      * the estimated first hop transport bandwidth.
897      *
898      * @return The estimated first hop downstream (network to device) bandwidth.
899      */
getLinkDownstreamBandwidthKbps()900     public int getLinkDownstreamBandwidthKbps() {
901         return mLinkDownBandwidthKbps;
902     }
903 
combineLinkBandwidths(NetworkCapabilities nc)904     private void combineLinkBandwidths(NetworkCapabilities nc) {
905         this.mLinkUpBandwidthKbps =
906                 Math.max(this.mLinkUpBandwidthKbps, nc.mLinkUpBandwidthKbps);
907         this.mLinkDownBandwidthKbps =
908                 Math.max(this.mLinkDownBandwidthKbps, nc.mLinkDownBandwidthKbps);
909     }
satisfiedByLinkBandwidths(NetworkCapabilities nc)910     private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) {
911         return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps ||
912                 this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps);
913     }
equalsLinkBandwidths(NetworkCapabilities nc)914     private boolean equalsLinkBandwidths(NetworkCapabilities nc) {
915         return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps &&
916                 this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
917     }
918     /** @hide */
minBandwidth(int a, int b)919     public static int minBandwidth(int a, int b) {
920         if (a == LINK_BANDWIDTH_UNSPECIFIED)  {
921             return b;
922         } else if (b == LINK_BANDWIDTH_UNSPECIFIED) {
923             return a;
924         } else {
925             return Math.min(a, b);
926         }
927     }
928     /** @hide */
maxBandwidth(int a, int b)929     public static int maxBandwidth(int a, int b) {
930         return Math.max(a, b);
931     }
932 
933     private NetworkSpecifier mNetworkSpecifier = null;
934     private TransportInfo mTransportInfo = null;
935 
936     /**
937      * Sets the optional bearer specific network specifier.
938      * This has no meaning if a single transport is also not specified, so calling
939      * this without a single transport set will generate an exception, as will
940      * subsequently adding or removing transports after this is set.
941      * </p>
942      *
943      * @param networkSpecifier A concrete, parcelable framework class that extends
944      *                         NetworkSpecifier.
945      * @return This NetworkCapabilities instance, to facilitate chaining.
946      * @hide
947      */
setNetworkSpecifier(NetworkSpecifier networkSpecifier)948     public @NonNull NetworkCapabilities setNetworkSpecifier(NetworkSpecifier networkSpecifier) {
949         if (networkSpecifier != null && Long.bitCount(mTransportTypes) != 1) {
950             throw new IllegalStateException("Must have a single transport specified to use " +
951                     "setNetworkSpecifier");
952         }
953 
954         mNetworkSpecifier = networkSpecifier;
955 
956         return this;
957     }
958 
959     /**
960      * Sets the optional transport specific information.
961      *
962      * @param transportInfo A concrete, parcelable framework class that extends
963      * {@link TransportInfo}.
964      * @return This NetworkCapabilities instance, to facilitate chaining.
965      * @hide
966      */
setTransportInfo(TransportInfo transportInfo)967     public @NonNull NetworkCapabilities setTransportInfo(TransportInfo transportInfo) {
968         mTransportInfo = transportInfo;
969         return this;
970     }
971 
972     /**
973      * Gets the optional bearer specific network specifier. May be {@code null} if not set.
974      *
975      * @return The optional {@link NetworkSpecifier} specifying the bearer specific network
976      *         specifier or {@code null}. See {@link #setNetworkSpecifier}.
977      * @hide
978      */
979     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
getNetworkSpecifier()980     public @Nullable NetworkSpecifier getNetworkSpecifier() {
981         return mNetworkSpecifier;
982     }
983 
984     /**
985      * Returns a transport-specific information container. The application may cast this
986      * container to a concrete sub-class based on its knowledge of the network request. The
987      * application should be able to deal with a {@code null} return value or an invalid case,
988      * e.g. use {@code instanceof} operator to verify expected type.
989      *
990      * @return A concrete implementation of the {@link TransportInfo} class or null if not
991      * available for the network.
992      */
getTransportInfo()993     @Nullable public TransportInfo getTransportInfo() {
994         return mTransportInfo;
995     }
996 
combineSpecifiers(NetworkCapabilities nc)997     private void combineSpecifiers(NetworkCapabilities nc) {
998         if (mNetworkSpecifier != null && !mNetworkSpecifier.equals(nc.mNetworkSpecifier)) {
999             throw new IllegalStateException("Can't combine two networkSpecifiers");
1000         }
1001         setNetworkSpecifier(nc.mNetworkSpecifier);
1002     }
1003 
satisfiedBySpecifier(NetworkCapabilities nc)1004     private boolean satisfiedBySpecifier(NetworkCapabilities nc) {
1005         return mNetworkSpecifier == null || mNetworkSpecifier.satisfiedBy(nc.mNetworkSpecifier)
1006                 || nc.mNetworkSpecifier instanceof MatchAllNetworkSpecifier;
1007     }
1008 
equalsSpecifier(NetworkCapabilities nc)1009     private boolean equalsSpecifier(NetworkCapabilities nc) {
1010         return Objects.equals(mNetworkSpecifier, nc.mNetworkSpecifier);
1011     }
1012 
combineTransportInfos(NetworkCapabilities nc)1013     private void combineTransportInfos(NetworkCapabilities nc) {
1014         if (mTransportInfo != null && !mTransportInfo.equals(nc.mTransportInfo)) {
1015             throw new IllegalStateException("Can't combine two TransportInfos");
1016         }
1017         setTransportInfo(nc.mTransportInfo);
1018     }
1019 
equalsTransportInfo(NetworkCapabilities nc)1020     private boolean equalsTransportInfo(NetworkCapabilities nc) {
1021         return Objects.equals(mTransportInfo, nc.mTransportInfo);
1022     }
1023 
1024     /**
1025      * Magic value that indicates no signal strength provided. A request specifying this value is
1026      * always satisfied.
1027      */
1028     public static final int SIGNAL_STRENGTH_UNSPECIFIED = Integer.MIN_VALUE;
1029 
1030     /**
1031      * Signal strength. This is a signed integer, and higher values indicate better signal.
1032      * The exact units are bearer-dependent. For example, Wi-Fi uses RSSI.
1033      */
1034     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
1035     private int mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
1036 
1037     /**
1038      * Sets the signal strength. This is a signed integer, with higher values indicating a stronger
1039      * signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same RSSI units
1040      * reported by wifi code.
1041      * <p>
1042      * Note that when used to register a network callback, this specifies the minimum acceptable
1043      * signal strength. When received as the state of an existing network it specifies the current
1044      * value. A value of code SIGNAL_STRENGTH_UNSPECIFIED} means no value when received and has no
1045      * effect when requesting a callback.
1046      *
1047      * @param signalStrength the bearer-specific signal strength.
1048      * @hide
1049      */
1050     @UnsupportedAppUsage
setSignalStrength(int signalStrength)1051     public @NonNull NetworkCapabilities setSignalStrength(int signalStrength) {
1052         mSignalStrength = signalStrength;
1053         return this;
1054     }
1055 
1056     /**
1057      * Returns {@code true} if this object specifies a signal strength.
1058      *
1059      * @hide
1060      */
1061     @UnsupportedAppUsage
hasSignalStrength()1062     public boolean hasSignalStrength() {
1063         return mSignalStrength > SIGNAL_STRENGTH_UNSPECIFIED;
1064     }
1065 
1066     /**
1067      * Retrieves the signal strength.
1068      *
1069      * @return The bearer-specific signal strength.
1070      */
getSignalStrength()1071     public int getSignalStrength() {
1072         return mSignalStrength;
1073     }
1074 
combineSignalStrength(NetworkCapabilities nc)1075     private void combineSignalStrength(NetworkCapabilities nc) {
1076         this.mSignalStrength = Math.max(this.mSignalStrength, nc.mSignalStrength);
1077     }
1078 
satisfiedBySignalStrength(NetworkCapabilities nc)1079     private boolean satisfiedBySignalStrength(NetworkCapabilities nc) {
1080         return this.mSignalStrength <= nc.mSignalStrength;
1081     }
1082 
equalsSignalStrength(NetworkCapabilities nc)1083     private boolean equalsSignalStrength(NetworkCapabilities nc) {
1084         return this.mSignalStrength == nc.mSignalStrength;
1085     }
1086 
1087     /**
1088      * List of UIDs this network applies to. No restriction if null.
1089      * <p>
1090      * For networks, mUids represent the list of network this applies to, and null means this
1091      * network applies to all UIDs.
1092      * For requests, mUids is the list of UIDs this network MUST apply to to match ; ALL UIDs
1093      * must be included in a network so that they match. As an exception to the general rule,
1094      * a null mUids field for requests mean "no requirements" rather than what the general rule
1095      * would suggest ("must apply to all UIDs") : this is because this has shown to be what users
1096      * of this API expect in practice. A network that must match all UIDs can still be
1097      * expressed with a set ranging the entire set of possible UIDs.
1098      * <p>
1099      * mUids is typically (and at this time, only) used by VPN. This network is only available to
1100      * the UIDs in this list, and it is their default network. Apps in this list that wish to
1101      * bypass the VPN can do so iff the VPN app allows them to or if they are privileged. If this
1102      * member is null, then the network is not restricted by app UID. If it's an empty list, then
1103      * it means nobody can use it.
1104      * As a special exception, the app managing this network (as identified by its UID stored in
1105      * mEstablishingVpnAppUid) can always see this network. This is embodied by a special check in
1106      * satisfiedByUids. That still does not mean the network necessarily <strong>applies</strong>
1107      * to the app that manages it as determined by #appliesToUid.
1108      * <p>
1109      * Please note that in principle a single app can be associated with multiple UIDs because
1110      * each app will have a different UID when it's run as a different (macro-)user. A single
1111      * macro user can only have a single active VPN app at any given time however.
1112      * <p>
1113      * Also please be aware this class does not try to enforce any normalization on this. Callers
1114      * can only alter the UIDs by setting them wholesale : this class does not provide any utility
1115      * to add or remove individual UIDs or ranges. If callers have any normalization needs on
1116      * their own (like requiring sortedness or no overlap) they need to enforce it
1117      * themselves. Some of the internal methods also assume this is normalized as in no adjacent
1118      * or overlapping ranges are present.
1119      *
1120      * @hide
1121      */
1122     private ArraySet<UidRange> mUids = null;
1123 
1124     /**
1125      * Convenience method to set the UIDs this network applies to to a single UID.
1126      * @hide
1127      */
setSingleUid(int uid)1128     public @NonNull NetworkCapabilities setSingleUid(int uid) {
1129         final ArraySet<UidRange> identity = new ArraySet<>(1);
1130         identity.add(new UidRange(uid, uid));
1131         setUids(identity);
1132         return this;
1133     }
1134 
1135     /**
1136      * Set the list of UIDs this network applies to.
1137      * This makes a copy of the set so that callers can't modify it after the call.
1138      * @hide
1139      */
setUids(Set<UidRange> uids)1140     public @NonNull NetworkCapabilities setUids(Set<UidRange> uids) {
1141         if (null == uids) {
1142             mUids = null;
1143         } else {
1144             mUids = new ArraySet<>(uids);
1145         }
1146         return this;
1147     }
1148 
1149     /**
1150      * Get the list of UIDs this network applies to.
1151      * This returns a copy of the set so that callers can't modify the original object.
1152      * @hide
1153      */
getUids()1154     public @Nullable Set<UidRange> getUids() {
1155         return null == mUids ? null : new ArraySet<>(mUids);
1156     }
1157 
1158     /**
1159      * Test whether this network applies to this UID.
1160      * @hide
1161      */
appliesToUid(int uid)1162     public boolean appliesToUid(int uid) {
1163         if (null == mUids) return true;
1164         for (UidRange range : mUids) {
1165             if (range.contains(uid)) {
1166                 return true;
1167             }
1168         }
1169         return false;
1170     }
1171 
1172     /**
1173      * Tests if the set of UIDs that this network applies to is the same as the passed network.
1174      * <p>
1175      * This test only checks whether equal range objects are in both sets. It will
1176      * return false if the ranges are not exactly the same, even if the covered UIDs
1177      * are for an equivalent result.
1178      * <p>
1179      * Note that this method is not very optimized, which is fine as long as it's not used very
1180      * often.
1181      * <p>
1182      * nc is assumed nonnull.
1183      *
1184      * @hide
1185      */
1186     @VisibleForTesting
equalsUids(@onNull NetworkCapabilities nc)1187     public boolean equalsUids(@NonNull NetworkCapabilities nc) {
1188         Set<UidRange> comparedUids = nc.mUids;
1189         if (null == comparedUids) return null == mUids;
1190         if (null == mUids) return false;
1191         // Make a copy so it can be mutated to check that all ranges in mUids
1192         // also are in uids.
1193         final Set<UidRange> uids = new ArraySet<>(mUids);
1194         for (UidRange range : comparedUids) {
1195             if (!uids.contains(range)) {
1196                 return false;
1197             }
1198             uids.remove(range);
1199         }
1200         return uids.isEmpty();
1201     }
1202 
1203     /**
1204      * Test whether the passed NetworkCapabilities satisfies the UIDs this capabilities require.
1205      *
1206      * This method is called on the NetworkCapabilities embedded in a request with the
1207      * capabilities of an available network. It checks whether all the UIDs from this listen
1208      * (representing the UIDs that must have access to the network) are satisfied by the UIDs
1209      * in the passed nc (representing the UIDs that this network is available to).
1210      * <p>
1211      * As a special exception, the UID that created the passed network (as represented by its
1212      * mEstablishingVpnAppUid field) always satisfies a NetworkRequest requiring it (of LISTEN
1213      * or REQUEST types alike), even if the network does not apply to it. That is so a VPN app
1214      * can see its own network when it listens for it.
1215      * <p>
1216      * nc is assumed nonnull. Else, NPE.
1217      * @see #appliesToUid
1218      * @hide
1219      */
satisfiedByUids(@onNull NetworkCapabilities nc)1220     public boolean satisfiedByUids(@NonNull NetworkCapabilities nc) {
1221         if (null == nc.mUids || null == mUids) return true; // The network satisfies everything.
1222         for (UidRange requiredRange : mUids) {
1223             if (requiredRange.contains(nc.mEstablishingVpnAppUid)) return true;
1224             if (!nc.appliesToUidRange(requiredRange)) {
1225                 return false;
1226             }
1227         }
1228         return true;
1229     }
1230 
1231     /**
1232      * Returns whether this network applies to the passed ranges.
1233      * This assumes that to apply, the passed range has to be entirely contained
1234      * within one of the ranges this network applies to. If the ranges are not normalized,
1235      * this method may return false even though all required UIDs are covered because no
1236      * single range contained them all.
1237      * @hide
1238      */
1239     @VisibleForTesting
appliesToUidRange(@ullable UidRange requiredRange)1240     public boolean appliesToUidRange(@Nullable UidRange requiredRange) {
1241         if (null == mUids) return true;
1242         for (UidRange uidRange : mUids) {
1243             if (uidRange.containsRange(requiredRange)) {
1244                 return true;
1245             }
1246         }
1247         return false;
1248     }
1249 
1250     /**
1251      * Combine the UIDs this network currently applies to with the UIDs the passed
1252      * NetworkCapabilities apply to.
1253      * nc is assumed nonnull.
1254      */
combineUids(@onNull NetworkCapabilities nc)1255     private void combineUids(@NonNull NetworkCapabilities nc) {
1256         if (null == nc.mUids || null == mUids) {
1257             mUids = null;
1258             return;
1259         }
1260         mUids.addAll(nc.mUids);
1261     }
1262 
1263 
1264     /**
1265      * The SSID of the network, or null if not applicable or unknown.
1266      * <p>
1267      * This is filled in by wifi code.
1268      * @hide
1269      */
1270     private String mSSID;
1271 
1272     /**
1273      * Sets the SSID of this network.
1274      * @hide
1275      */
setSSID(@ullable String ssid)1276     public @NonNull NetworkCapabilities setSSID(@Nullable String ssid) {
1277         mSSID = ssid;
1278         return this;
1279     }
1280 
1281     /**
1282      * Gets the SSID of this network, or null if none or unknown.
1283      * @hide
1284      */
getSSID()1285     public @Nullable String getSSID() {
1286         return mSSID;
1287     }
1288 
1289     /**
1290      * Tests if the SSID of this network is the same as the SSID of the passed network.
1291      * @hide
1292      */
equalsSSID(@onNull NetworkCapabilities nc)1293     public boolean equalsSSID(@NonNull NetworkCapabilities nc) {
1294         return Objects.equals(mSSID, nc.mSSID);
1295     }
1296 
1297     /**
1298      * Check if the SSID requirements of this object are matched by the passed object.
1299      * @hide
1300      */
satisfiedBySSID(@onNull NetworkCapabilities nc)1301     public boolean satisfiedBySSID(@NonNull NetworkCapabilities nc) {
1302         return mSSID == null || mSSID.equals(nc.mSSID);
1303     }
1304 
1305     /**
1306      * Combine SSIDs of the capabilities.
1307      * <p>
1308      * This is only legal if either the SSID of this object is null, or both SSIDs are
1309      * equal.
1310      * @hide
1311      */
combineSSIDs(@onNull NetworkCapabilities nc)1312     private void combineSSIDs(@NonNull NetworkCapabilities nc) {
1313         if (mSSID != null && !mSSID.equals(nc.mSSID)) {
1314             throw new IllegalStateException("Can't combine two SSIDs");
1315         }
1316         setSSID(nc.mSSID);
1317     }
1318 
1319     /**
1320      * Combine a set of Capabilities to this one.  Useful for coming up with the complete set.
1321      * <p>
1322      * Note that this method may break an invariant of having a particular capability in either
1323      * wanted or unwanted lists but never in both.  Requests that have the same capability in
1324      * both lists will never be satisfied.
1325      * @hide
1326      */
combineCapabilities(@onNull NetworkCapabilities nc)1327     public void combineCapabilities(@NonNull NetworkCapabilities nc) {
1328         combineNetCapabilities(nc);
1329         combineTransportTypes(nc);
1330         combineLinkBandwidths(nc);
1331         combineSpecifiers(nc);
1332         combineTransportInfos(nc);
1333         combineSignalStrength(nc);
1334         combineUids(nc);
1335         combineSSIDs(nc);
1336     }
1337 
1338     /**
1339      * Check if our requirements are satisfied by the given {@code NetworkCapabilities}.
1340      *
1341      * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
1342      * @param onlyImmutable if {@code true}, do not consider mutable requirements such as link
1343      *         bandwidth, signal strength, or validation / captive portal status.
1344      *
1345      * @hide
1346      */
satisfiedByNetworkCapabilities(NetworkCapabilities nc, boolean onlyImmutable)1347     private boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc, boolean onlyImmutable) {
1348         return (nc != null
1349                 && satisfiedByNetCapabilities(nc, onlyImmutable)
1350                 && satisfiedByTransportTypes(nc)
1351                 && (onlyImmutable || satisfiedByLinkBandwidths(nc))
1352                 && satisfiedBySpecifier(nc)
1353                 && (onlyImmutable || satisfiedBySignalStrength(nc))
1354                 && (onlyImmutable || satisfiedByUids(nc))
1355                 && (onlyImmutable || satisfiedBySSID(nc)));
1356     }
1357 
1358     /**
1359      * Check if our requirements are satisfied by the given {@code NetworkCapabilities}.
1360      *
1361      * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
1362      *
1363      * @hide
1364      */
1365     @TestApi
1366     @SystemApi
satisfiedByNetworkCapabilities(@ullable NetworkCapabilities nc)1367     public boolean satisfiedByNetworkCapabilities(@Nullable NetworkCapabilities nc) {
1368         return satisfiedByNetworkCapabilities(nc, false);
1369     }
1370 
1371     /**
1372      * Check if our immutable requirements are satisfied by the given {@code NetworkCapabilities}.
1373      *
1374      * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
1375      *
1376      * @hide
1377      */
satisfiedByImmutableNetworkCapabilities(@ullable NetworkCapabilities nc)1378     public boolean satisfiedByImmutableNetworkCapabilities(@Nullable NetworkCapabilities nc) {
1379         return satisfiedByNetworkCapabilities(nc, true);
1380     }
1381 
1382     /**
1383      * Checks that our immutable capabilities are the same as those of the given
1384      * {@code NetworkCapabilities} and return a String describing any difference.
1385      * The returned String is empty if there is no difference.
1386      *
1387      * @hide
1388      */
describeImmutableDifferences(@ullable NetworkCapabilities that)1389     public String describeImmutableDifferences(@Nullable NetworkCapabilities that) {
1390         if (that == null) {
1391             return "other NetworkCapabilities was null";
1392         }
1393 
1394         StringJoiner joiner = new StringJoiner(", ");
1395 
1396         // Ignore NOT_METERED being added or removed as it is effectively dynamic. http://b/63326103
1397         // TODO: properly support NOT_METERED as a mutable and requestable capability.
1398         final long mask = ~MUTABLE_CAPABILITIES & ~(1 << NET_CAPABILITY_NOT_METERED);
1399         long oldImmutableCapabilities = this.mNetworkCapabilities & mask;
1400         long newImmutableCapabilities = that.mNetworkCapabilities & mask;
1401         if (oldImmutableCapabilities != newImmutableCapabilities) {
1402             String before = capabilityNamesOf(BitUtils.unpackBits(oldImmutableCapabilities));
1403             String after = capabilityNamesOf(BitUtils.unpackBits(newImmutableCapabilities));
1404             joiner.add(String.format("immutable capabilities changed: %s -> %s", before, after));
1405         }
1406 
1407         if (!equalsSpecifier(that)) {
1408             NetworkSpecifier before = this.getNetworkSpecifier();
1409             NetworkSpecifier after = that.getNetworkSpecifier();
1410             joiner.add(String.format("specifier changed: %s -> %s", before, after));
1411         }
1412 
1413         if (!equalsTransportTypes(that)) {
1414             String before = transportNamesOf(this.getTransportTypes());
1415             String after = transportNamesOf(that.getTransportTypes());
1416             joiner.add(String.format("transports changed: %s -> %s", before, after));
1417         }
1418 
1419         return joiner.toString();
1420     }
1421 
1422     /**
1423      * Checks that our requestable capabilities are the same as those of the given
1424      * {@code NetworkCapabilities}.
1425      *
1426      * @hide
1427      */
equalRequestableCapabilities(@ullable NetworkCapabilities nc)1428     public boolean equalRequestableCapabilities(@Nullable NetworkCapabilities nc) {
1429         if (nc == null) return false;
1430         return (equalsNetCapabilitiesRequestable(nc) &&
1431                 equalsTransportTypes(nc) &&
1432                 equalsSpecifier(nc));
1433     }
1434 
1435     @Override
equals(@ullable Object obj)1436     public boolean equals(@Nullable Object obj) {
1437         if (obj == null || (obj instanceof NetworkCapabilities == false)) return false;
1438         NetworkCapabilities that = (NetworkCapabilities) obj;
1439         return (equalsNetCapabilities(that)
1440                 && equalsTransportTypes(that)
1441                 && equalsLinkBandwidths(that)
1442                 && equalsSignalStrength(that)
1443                 && equalsSpecifier(that)
1444                 && equalsTransportInfo(that)
1445                 && equalsUids(that)
1446                 && equalsSSID(that));
1447     }
1448 
1449     @Override
hashCode()1450     public int hashCode() {
1451         return (int) (mNetworkCapabilities & 0xFFFFFFFF)
1452                 + ((int) (mNetworkCapabilities >> 32) * 3)
1453                 + ((int) (mUnwantedNetworkCapabilities & 0xFFFFFFFF) * 5)
1454                 + ((int) (mUnwantedNetworkCapabilities >> 32) * 7)
1455                 + ((int) (mTransportTypes & 0xFFFFFFFF) * 11)
1456                 + ((int) (mTransportTypes >> 32) * 13)
1457                 + (mLinkUpBandwidthKbps * 17)
1458                 + (mLinkDownBandwidthKbps * 19)
1459                 + Objects.hashCode(mNetworkSpecifier) * 23
1460                 + (mSignalStrength * 29)
1461                 + Objects.hashCode(mUids) * 31
1462                 + Objects.hashCode(mSSID) * 37
1463                 + Objects.hashCode(mTransportInfo) * 41;
1464     }
1465 
1466     @Override
describeContents()1467     public int describeContents() {
1468         return 0;
1469     }
1470     @Override
writeToParcel(Parcel dest, int flags)1471     public void writeToParcel(Parcel dest, int flags) {
1472         dest.writeLong(mNetworkCapabilities);
1473         dest.writeLong(mUnwantedNetworkCapabilities);
1474         dest.writeLong(mTransportTypes);
1475         dest.writeInt(mLinkUpBandwidthKbps);
1476         dest.writeInt(mLinkDownBandwidthKbps);
1477         dest.writeParcelable((Parcelable) mNetworkSpecifier, flags);
1478         dest.writeParcelable((Parcelable) mTransportInfo, flags);
1479         dest.writeInt(mSignalStrength);
1480         dest.writeArraySet(mUids);
1481         dest.writeString(mSSID);
1482     }
1483 
1484     public static final @android.annotation.NonNull Creator<NetworkCapabilities> CREATOR =
1485         new Creator<NetworkCapabilities>() {
1486             @Override
1487             public NetworkCapabilities createFromParcel(Parcel in) {
1488                 NetworkCapabilities netCap = new NetworkCapabilities();
1489 
1490                 netCap.mNetworkCapabilities = in.readLong();
1491                 netCap.mUnwantedNetworkCapabilities = in.readLong();
1492                 netCap.mTransportTypes = in.readLong();
1493                 netCap.mLinkUpBandwidthKbps = in.readInt();
1494                 netCap.mLinkDownBandwidthKbps = in.readInt();
1495                 netCap.mNetworkSpecifier = in.readParcelable(null);
1496                 netCap.mTransportInfo = in.readParcelable(null);
1497                 netCap.mSignalStrength = in.readInt();
1498                 netCap.mUids = (ArraySet<UidRange>) in.readArraySet(
1499                         null /* ClassLoader, null for default */);
1500                 netCap.mSSID = in.readString();
1501                 return netCap;
1502             }
1503             @Override
1504             public NetworkCapabilities[] newArray(int size) {
1505                 return new NetworkCapabilities[size];
1506             }
1507         };
1508 
1509     @Override
toString()1510     public @NonNull String toString() {
1511         final StringBuilder sb = new StringBuilder("[");
1512         if (0 != mTransportTypes) {
1513             sb.append(" Transports: ");
1514             appendStringRepresentationOfBitMaskToStringBuilder(sb, mTransportTypes,
1515                     NetworkCapabilities::transportNameOf, "|");
1516         }
1517         if (0 != mNetworkCapabilities) {
1518             sb.append(" Capabilities: ");
1519             appendStringRepresentationOfBitMaskToStringBuilder(sb, mNetworkCapabilities,
1520                     NetworkCapabilities::capabilityNameOf, "&");
1521         }
1522         if (0 != mUnwantedNetworkCapabilities) {
1523             sb.append(" Unwanted: ");
1524             appendStringRepresentationOfBitMaskToStringBuilder(sb, mUnwantedNetworkCapabilities,
1525                     NetworkCapabilities::capabilityNameOf, "&");
1526         }
1527         if (mLinkUpBandwidthKbps > 0) {
1528             sb.append(" LinkUpBandwidth>=").append(mLinkUpBandwidthKbps).append("Kbps");
1529         }
1530         if (mLinkDownBandwidthKbps > 0) {
1531             sb.append(" LinkDnBandwidth>=").append(mLinkDownBandwidthKbps).append("Kbps");
1532         }
1533         if (mNetworkSpecifier != null) {
1534             sb.append(" Specifier: <").append(mNetworkSpecifier).append(">");
1535         }
1536         if (mTransportInfo != null) {
1537             sb.append(" TransportInfo: <").append(mTransportInfo).append(">");
1538         }
1539         if (hasSignalStrength()) {
1540             sb.append(" SignalStrength: ").append(mSignalStrength);
1541         }
1542 
1543         if (null != mUids) {
1544             if ((1 == mUids.size()) && (mUids.valueAt(0).count() == 1)) {
1545                 sb.append(" Uid: ").append(mUids.valueAt(0).start);
1546             } else {
1547                 sb.append(" Uids: <").append(mUids).append(">");
1548             }
1549         }
1550         if (mEstablishingVpnAppUid != INVALID_UID) {
1551             sb.append(" EstablishingAppUid: ").append(mEstablishingVpnAppUid);
1552         }
1553 
1554         if (null != mSSID) {
1555             sb.append(" SSID: ").append(mSSID);
1556         }
1557 
1558         sb.append("]");
1559         return sb.toString();
1560     }
1561 
1562 
1563     private interface NameOf {
nameOf(int value)1564         String nameOf(int value);
1565     }
1566     /**
1567      * @hide
1568      */
appendStringRepresentationOfBitMaskToStringBuilder(@onNull StringBuilder sb, long bitMask, @NonNull NameOf nameFetcher, @NonNull String separator)1569     public static void appendStringRepresentationOfBitMaskToStringBuilder(@NonNull StringBuilder sb,
1570             long bitMask, @NonNull NameOf nameFetcher, @NonNull String separator) {
1571         int bitPos = 0;
1572         boolean firstElementAdded = false;
1573         while (bitMask != 0) {
1574             if ((bitMask & 1) != 0) {
1575                 if (firstElementAdded) {
1576                     sb.append(separator);
1577                 } else {
1578                     firstElementAdded = true;
1579                 }
1580                 sb.append(nameFetcher.nameOf(bitPos));
1581             }
1582             bitMask >>= 1;
1583             ++bitPos;
1584         }
1585     }
1586 
1587     /** @hide */
writeToProto(@onNull ProtoOutputStream proto, long fieldId)1588     public void writeToProto(@NonNull ProtoOutputStream proto, long fieldId) {
1589         final long token = proto.start(fieldId);
1590 
1591         for (int transport : getTransportTypes()) {
1592             proto.write(NetworkCapabilitiesProto.TRANSPORTS, transport);
1593         }
1594 
1595         for (int capability : getCapabilities()) {
1596             proto.write(NetworkCapabilitiesProto.CAPABILITIES, capability);
1597         }
1598 
1599         proto.write(NetworkCapabilitiesProto.LINK_UP_BANDWIDTH_KBPS, mLinkUpBandwidthKbps);
1600         proto.write(NetworkCapabilitiesProto.LINK_DOWN_BANDWIDTH_KBPS, mLinkDownBandwidthKbps);
1601 
1602         if (mNetworkSpecifier != null) {
1603             proto.write(NetworkCapabilitiesProto.NETWORK_SPECIFIER, mNetworkSpecifier.toString());
1604         }
1605         if (mTransportInfo != null) {
1606             // TODO b/120653863: write transport-specific info to proto?
1607         }
1608 
1609         proto.write(NetworkCapabilitiesProto.CAN_REPORT_SIGNAL_STRENGTH, hasSignalStrength());
1610         proto.write(NetworkCapabilitiesProto.SIGNAL_STRENGTH, mSignalStrength);
1611 
1612         proto.end(token);
1613     }
1614 
1615     /**
1616      * @hide
1617      */
capabilityNamesOf(@ullable @etCapability int[] capabilities)1618     public static @NonNull String capabilityNamesOf(@Nullable @NetCapability int[] capabilities) {
1619         StringJoiner joiner = new StringJoiner("|");
1620         if (capabilities != null) {
1621             for (int c : capabilities) {
1622                 joiner.add(capabilityNameOf(c));
1623             }
1624         }
1625         return joiner.toString();
1626     }
1627 
1628     /**
1629      * @hide
1630      */
capabilityNameOf(@etCapability int capability)1631     public static @NonNull String capabilityNameOf(@NetCapability int capability) {
1632         switch (capability) {
1633             case NET_CAPABILITY_MMS:                  return "MMS";
1634             case NET_CAPABILITY_SUPL:                 return "SUPL";
1635             case NET_CAPABILITY_DUN:                  return "DUN";
1636             case NET_CAPABILITY_FOTA:                 return "FOTA";
1637             case NET_CAPABILITY_IMS:                  return "IMS";
1638             case NET_CAPABILITY_CBS:                  return "CBS";
1639             case NET_CAPABILITY_WIFI_P2P:             return "WIFI_P2P";
1640             case NET_CAPABILITY_IA:                   return "IA";
1641             case NET_CAPABILITY_RCS:                  return "RCS";
1642             case NET_CAPABILITY_XCAP:                 return "XCAP";
1643             case NET_CAPABILITY_EIMS:                 return "EIMS";
1644             case NET_CAPABILITY_NOT_METERED:          return "NOT_METERED";
1645             case NET_CAPABILITY_INTERNET:             return "INTERNET";
1646             case NET_CAPABILITY_NOT_RESTRICTED:       return "NOT_RESTRICTED";
1647             case NET_CAPABILITY_TRUSTED:              return "TRUSTED";
1648             case NET_CAPABILITY_NOT_VPN:              return "NOT_VPN";
1649             case NET_CAPABILITY_VALIDATED:            return "VALIDATED";
1650             case NET_CAPABILITY_CAPTIVE_PORTAL:       return "CAPTIVE_PORTAL";
1651             case NET_CAPABILITY_NOT_ROAMING:          return "NOT_ROAMING";
1652             case NET_CAPABILITY_FOREGROUND:           return "FOREGROUND";
1653             case NET_CAPABILITY_NOT_CONGESTED:        return "NOT_CONGESTED";
1654             case NET_CAPABILITY_NOT_SUSPENDED:        return "NOT_SUSPENDED";
1655             case NET_CAPABILITY_OEM_PAID:             return "OEM_PAID";
1656             case NET_CAPABILITY_MCX:                  return "MCX";
1657             case NET_CAPABILITY_PARTIAL_CONNECTIVITY: return "PARTIAL_CONNECTIVITY";
1658             default:                                  return Integer.toString(capability);
1659         }
1660     }
1661 
1662     /**
1663      * @hide
1664      */
1665     @UnsupportedAppUsage
transportNamesOf(@ullable @ransport int[] types)1666     public static @NonNull String transportNamesOf(@Nullable @Transport int[] types) {
1667         StringJoiner joiner = new StringJoiner("|");
1668         if (types != null) {
1669             for (int t : types) {
1670                 joiner.add(transportNameOf(t));
1671             }
1672         }
1673         return joiner.toString();
1674     }
1675 
1676     /**
1677      * @hide
1678      */
transportNameOf(@ransport int transport)1679     public static @NonNull String transportNameOf(@Transport int transport) {
1680         if (!isValidTransport(transport)) {
1681             return "UNKNOWN";
1682         }
1683         return TRANSPORT_NAMES[transport];
1684     }
1685 
checkValidTransportType(@ransport int transport)1686     private static void checkValidTransportType(@Transport int transport) {
1687         Preconditions.checkArgument(
1688                 isValidTransport(transport), "Invalid TransportType " + transport);
1689     }
1690 
isValidCapability(@etworkCapabilities.NetCapability int capability)1691     private static boolean isValidCapability(@NetworkCapabilities.NetCapability int capability) {
1692         return capability >= MIN_NET_CAPABILITY && capability <= MAX_NET_CAPABILITY;
1693     }
1694 
checkValidCapability(@etworkCapabilities.NetCapability int capability)1695     private static void checkValidCapability(@NetworkCapabilities.NetCapability int capability) {
1696         Preconditions.checkArgument(isValidCapability(capability),
1697                 "NetworkCapability " + capability + "out of range");
1698     }
1699 
1700     /**
1701      * Check if this {@code NetworkCapability} instance is metered.
1702      *
1703      * @return {@code true} if {@code NET_CAPABILITY_NOT_METERED} is not set on this instance.
1704      * @hide
1705      */
isMetered()1706     public boolean isMetered() {
1707         return !hasCapability(NET_CAPABILITY_NOT_METERED);
1708     }
1709 }
1710