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