Home | History | Annotate | Download | only in net
      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      */
     59     public NetworkCapabilities() {
     60         clearAll();
     61         mNetworkCapabilities = DEFAULT_CAPABILITIES;
     62     }
     63 
     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      */
     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      */
     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      */
    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      */
    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      */
    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      */
    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
    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      */
    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      */
    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
    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      */
    482     public boolean hasCapability(@NetCapability int capability) {
    483         return isValidCapability(capability)
    484                 && ((mNetworkCapabilities & (1 << capability)) != 0);
    485     }
    486 
    487     /** @hide */
    488     public boolean hasUnwantedCapability(@NetCapability int capability) {
    489         return isValidCapability(capability)
    490                 && ((mUnwantedNetworkCapabilities & (1 << capability)) != 0);
    491     }
    492 
    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      */
    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 
    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 */
    531     public boolean equalsNetCapabilities(NetworkCapabilities nc) {
    532         return (nc.mNetworkCapabilities == this.mNetworkCapabilities)
    533                 && (nc.mUnwantedNetworkCapabilities == this.mUnwantedNetworkCapabilities);
    534     }
    535 
    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      */
    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 */
    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      */
    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      */
    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      */
    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
    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      */
    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      */
    724     public boolean hasTransport(@Transport int transportType) {
    725         return isValidTransport(transportType) && ((mTransportTypes & (1 << transportType)) != 0);
    726     }
    727 
    728     private void combineTransportTypes(NetworkCapabilities nc) {
    729         this.mTransportTypes |= nc.mTransportTypes;
    730     }
    731 
    732     private boolean satisfiedByTransportTypes(NetworkCapabilities nc) {
    733         return ((this.mTransportTypes == 0) ||
    734                 ((this.mTransportTypes & nc.mTransportTypes) != 0));
    735     }
    736 
    737     /** @hide */
    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      */
    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      */
    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      */
    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      */
    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      */
    835     public int getLinkDownstreamBandwidthKbps() {
    836         return mLinkDownBandwidthKbps;
    837     }
    838 
    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     }
    845     private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) {
    846         return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps ||
    847                 this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps);
    848     }
    849     private boolean equalsLinkBandwidths(NetworkCapabilities nc) {
    850         return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps &&
    851                 this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
    852     }
    853     /** @hide */
    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 */
    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      */
    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      */
    900     public NetworkSpecifier getNetworkSpecifier() {
    901         return mNetworkSpecifier;
    902     }
    903 
    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 
    911     private boolean satisfiedBySpecifier(NetworkCapabilities nc) {
    912         return mNetworkSpecifier == null || mNetworkSpecifier.satisfiedBy(nc.mNetworkSpecifier)
    913                 || nc.mNetworkSpecifier instanceof MatchAllNetworkSpecifier;
    914     }
    915 
    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      */
    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      */
    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      */
    967     public int getSignalStrength() {
    968         return mSignalStrength;
    969     }
    970 
    971     private void combineSignalStrength(NetworkCapabilities nc) {
    972         this.mSignalStrength = Math.max(this.mSignalStrength, nc.mSignalStrength);
    973     }
    974 
    975     private boolean satisfiedBySignalStrength(NetworkCapabilities nc) {
    976         return this.mSignalStrength <= nc.mSignalStrength;
    977     }
    978 
    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      */
   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      */
   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      */
   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      */
   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
   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      */
   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
   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      */
   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      */
   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      */
   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      */
   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      */
   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      */
   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      */
   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      */
   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      */
   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      */
   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      */
   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      */
   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
   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
   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
   1354     public int describeContents() {
   1355         return 0;
   1356     }
   1357     @Override
   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
   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 {
   1446         String nameOf(int value);
   1447     }
   1448     /**
   1449      * @hide
   1450      */
   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 */
   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      */
   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      */
   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      */
   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      */
   1555     public static String transportNameOf(@Transport int transport) {
   1556         if (!isValidTransport(transport)) {
   1557             return "UNKNOWN";
   1558         }
   1559         return TRANSPORT_NAMES[transport];
   1560     }
   1561 
   1562     private static void checkValidTransportType(@Transport int transport) {
   1563         Preconditions.checkArgument(
   1564                 isValidTransport(transport), "Invalid TransportType " + transport);
   1565     }
   1566 
   1567     private static boolean isValidCapability(@NetworkCapabilities.NetCapability int capability) {
   1568         return capability >= MIN_NET_CAPABILITY && capability <= MAX_NET_CAPABILITY;
   1569     }
   1570 
   1571     private static void checkValidCapability(@NetworkCapabilities.NetCapability int capability) {
   1572         Preconditions.checkArgument(isValidCapability(capability),
   1573                 "NetworkCapability " + capability + "out of range");
   1574     }
   1575 }
   1576