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.os.Parcel;
     20 import android.os.Parcelable;
     21 
     22 import com.android.internal.annotations.VisibleForTesting;
     23 import com.android.internal.util.BitUtils;
     24 
     25 import java.util.Objects;
     26 
     27 /**
     28  * This class represents the capabilities of a network.  This is used both to specify
     29  * needs to {@link ConnectivityManager} and when inspecting a network.
     30  *
     31  * Note that this replaces the old {@link ConnectivityManager#TYPE_MOBILE} method
     32  * of network selection.  Rather than indicate a need for Wi-Fi because an application
     33  * needs high bandwidth and risk obsolescence when a new, fast network appears (like LTE),
     34  * the application should specify it needs high bandwidth.  Similarly if an application
     35  * needs an unmetered network for a bulk transfer it can specify that rather than assuming
     36  * all cellular based connections are metered and all Wi-Fi based connections are not.
     37  */
     38 public final class NetworkCapabilities implements Parcelable {
     39     private static final String TAG = "NetworkCapabilities";
     40 
     41     /**
     42      * @hide
     43      */
     44     public NetworkCapabilities() {
     45         clearAll();
     46         mNetworkCapabilities = DEFAULT_CAPABILITIES;
     47     }
     48 
     49     public NetworkCapabilities(NetworkCapabilities nc) {
     50         if (nc != null) {
     51             mNetworkCapabilities = nc.mNetworkCapabilities;
     52             mTransportTypes = nc.mTransportTypes;
     53             mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps;
     54             mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
     55             mNetworkSpecifier = nc.mNetworkSpecifier;
     56             mSignalStrength = nc.mSignalStrength;
     57         }
     58     }
     59 
     60     /**
     61      * Completely clears the contents of this object, removing even the capabilities that are set
     62      * by default when the object is constructed.
     63      * @hide
     64      */
     65     public void clearAll() {
     66         mNetworkCapabilities = mTransportTypes = 0;
     67         mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = 0;
     68         mNetworkSpecifier = null;
     69         mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
     70     }
     71 
     72     /**
     73      * Represents the network's capabilities.  If any are specified they will be satisfied
     74      * by any Network that matches all of them.
     75      */
     76     private long mNetworkCapabilities;
     77 
     78     /**
     79      * Indicates this is a network that has the ability to reach the
     80      * carrier's MMSC for sending and receiving MMS messages.
     81      */
     82     public static final int NET_CAPABILITY_MMS            = 0;
     83 
     84     /**
     85      * Indicates this is a network that has the ability to reach the carrier's
     86      * SUPL server, used to retrieve GPS information.
     87      */
     88     public static final int NET_CAPABILITY_SUPL           = 1;
     89 
     90     /**
     91      * Indicates this is a network that has the ability to reach the carrier's
     92      * DUN or tethering gateway.
     93      */
     94     public static final int NET_CAPABILITY_DUN            = 2;
     95 
     96     /**
     97      * Indicates this is a network that has the ability to reach the carrier's
     98      * FOTA portal, used for over the air updates.
     99      */
    100     public static final int NET_CAPABILITY_FOTA           = 3;
    101 
    102     /**
    103      * Indicates this is a network that has the ability to reach the carrier's
    104      * IMS servers, used for network registration and signaling.
    105      */
    106     public static final int NET_CAPABILITY_IMS            = 4;
    107 
    108     /**
    109      * Indicates this is a network that has the ability to reach the carrier's
    110      * CBS servers, used for carrier specific services.
    111      */
    112     public static final int NET_CAPABILITY_CBS            = 5;
    113 
    114     /**
    115      * Indicates this is a network that has the ability to reach a Wi-Fi direct
    116      * peer.
    117      */
    118     public static final int NET_CAPABILITY_WIFI_P2P       = 6;
    119 
    120     /**
    121      * Indicates this is a network that has the ability to reach a carrier's
    122      * Initial Attach servers.
    123      */
    124     public static final int NET_CAPABILITY_IA             = 7;
    125 
    126     /**
    127      * Indicates this is a network that has the ability to reach a carrier's
    128      * RCS servers, used for Rich Communication Services.
    129      */
    130     public static final int NET_CAPABILITY_RCS            = 8;
    131 
    132     /**
    133      * Indicates this is a network that has the ability to reach a carrier's
    134      * XCAP servers, used for configuration and control.
    135      */
    136     public static final int NET_CAPABILITY_XCAP           = 9;
    137 
    138     /**
    139      * Indicates this is a network that has the ability to reach a carrier's
    140      * Emergency IMS servers or other services, used for network signaling
    141      * during emergency calls.
    142      */
    143     public static final int NET_CAPABILITY_EIMS           = 10;
    144 
    145     /**
    146      * Indicates that this network is unmetered.
    147      */
    148     public static final int NET_CAPABILITY_NOT_METERED    = 11;
    149 
    150     /**
    151      * Indicates that this network should be able to reach the internet.
    152      */
    153     public static final int NET_CAPABILITY_INTERNET       = 12;
    154 
    155     /**
    156      * Indicates that this network is available for general use.  If this is not set
    157      * applications should not attempt to communicate on this network.  Note that this
    158      * is simply informative and not enforcement - enforcement is handled via other means.
    159      * Set by default.
    160      */
    161     public static final int NET_CAPABILITY_NOT_RESTRICTED = 13;
    162 
    163     /**
    164      * Indicates that the user has indicated implicit trust of this network.  This
    165      * generally means it's a sim-selected carrier, a plugged in ethernet, a paired
    166      * BT device or a wifi the user asked to connect to.  Untrusted networks
    167      * are probably limited to unknown wifi AP.  Set by default.
    168      */
    169     public static final int NET_CAPABILITY_TRUSTED        = 14;
    170 
    171     /**
    172      * Indicates that this network is not a VPN.  This capability is set by default and should be
    173      * explicitly cleared for VPN networks.
    174      */
    175     public static final int NET_CAPABILITY_NOT_VPN        = 15;
    176 
    177     /**
    178      * Indicates that connectivity on this network was successfully validated. For example, for a
    179      * network with NET_CAPABILITY_INTERNET, it means that Internet connectivity was successfully
    180      * detected.
    181      */
    182     public static final int NET_CAPABILITY_VALIDATED      = 16;
    183 
    184     /**
    185      * Indicates that this network was found to have a captive portal in place last time it was
    186      * probed.
    187      */
    188     public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17;
    189 
    190     /**
    191      * Indicates that this network is available for use by apps, and not a network that is being
    192      * kept up in the background to facilitate fast network switching.
    193      * @hide
    194      */
    195     public static final int NET_CAPABILITY_FOREGROUND = 18;
    196 
    197     private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
    198     private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_FOREGROUND;
    199 
    200     /**
    201      * Network capabilities that are expected to be mutable, i.e., can change while a particular
    202      * network is connected.
    203      */
    204     private static final long MUTABLE_CAPABILITIES =
    205             // TRUSTED can change when user explicitly connects to an untrusted network in Settings.
    206             // http://b/18206275
    207             (1 << NET_CAPABILITY_TRUSTED) |
    208             (1 << NET_CAPABILITY_VALIDATED) |
    209             (1 << NET_CAPABILITY_CAPTIVE_PORTAL) |
    210             (1 << NET_CAPABILITY_FOREGROUND);
    211 
    212     /**
    213      * Network capabilities that are not allowed in NetworkRequests. This exists because the
    214      * NetworkFactory / NetworkAgent model does not deal well with the situation where a
    215      * capability's presence cannot be known in advance. If such a capability is requested, then we
    216      * can get into a cycle where the NetworkFactory endlessly churns out NetworkAgents that then
    217      * get immediately torn down because they do not have the requested capability.
    218      */
    219     private static final long NON_REQUESTABLE_CAPABILITIES =
    220             MUTABLE_CAPABILITIES & ~(1 << NET_CAPABILITY_TRUSTED);
    221 
    222     /**
    223      * Capabilities that are set by default when the object is constructed.
    224      */
    225     private static final long DEFAULT_CAPABILITIES =
    226             (1 << NET_CAPABILITY_NOT_RESTRICTED) |
    227             (1 << NET_CAPABILITY_TRUSTED) |
    228             (1 << NET_CAPABILITY_NOT_VPN);
    229 
    230     /**
    231      * Capabilities that suggest that a network is restricted.
    232      * {@see #maybeMarkCapabilitiesRestricted}.
    233      */
    234     @VisibleForTesting
    235     /* package */ static final long RESTRICTED_CAPABILITIES =
    236             (1 << NET_CAPABILITY_CBS) |
    237             (1 << NET_CAPABILITY_DUN) |
    238             (1 << NET_CAPABILITY_EIMS) |
    239             (1 << NET_CAPABILITY_FOTA) |
    240             (1 << NET_CAPABILITY_IA) |
    241             (1 << NET_CAPABILITY_IMS) |
    242             (1 << NET_CAPABILITY_RCS) |
    243             (1 << NET_CAPABILITY_XCAP);
    244 
    245     /**
    246      * Capabilities that suggest that a network is unrestricted.
    247      * {@see #maybeMarkCapabilitiesRestricted}.
    248      */
    249     @VisibleForTesting
    250     /* package */ static final long UNRESTRICTED_CAPABILITIES =
    251             (1 << NET_CAPABILITY_INTERNET) |
    252             (1 << NET_CAPABILITY_MMS) |
    253             (1 << NET_CAPABILITY_SUPL) |
    254             (1 << NET_CAPABILITY_WIFI_P2P);
    255 
    256     /**
    257      * Adds the given capability to this {@code NetworkCapability} instance.
    258      * Multiple capabilities may be applied sequentially.  Note that when searching
    259      * for a network to satisfy a request, all capabilities requested must be satisfied.
    260      *
    261      * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be added.
    262      * @return This NetworkCapabilities instance, to facilitate chaining.
    263      * @hide
    264      */
    265     public NetworkCapabilities addCapability(int capability) {
    266         if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
    267             throw new IllegalArgumentException("NetworkCapability out of range");
    268         }
    269         mNetworkCapabilities |= 1 << capability;
    270         return this;
    271     }
    272 
    273     /**
    274      * Removes (if found) the given capability from this {@code NetworkCapability} instance.
    275      *
    276      * @param capability the {@code NetworkCapabilities.NET_CAPABILTIY_*} to be removed.
    277      * @return This NetworkCapabilities instance, to facilitate chaining.
    278      * @hide
    279      */
    280     public NetworkCapabilities removeCapability(int capability) {
    281         if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
    282             throw new IllegalArgumentException("NetworkCapability out of range");
    283         }
    284         mNetworkCapabilities &= ~(1 << capability);
    285         return this;
    286     }
    287 
    288     /**
    289      * Gets all the capabilities set on this {@code NetworkCapability} instance.
    290      *
    291      * @return an array of {@code NetworkCapabilities.NET_CAPABILITY_*} values
    292      *         for this instance.
    293      * @hide
    294      */
    295     public int[] getCapabilities() {
    296         return BitUtils.unpackBits(mNetworkCapabilities);
    297     }
    298 
    299     /**
    300      * Tests for the presence of a capabilitity on this instance.
    301      *
    302      * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be tested for.
    303      * @return {@code true} if set on this instance.
    304      */
    305     public boolean hasCapability(int capability) {
    306         if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
    307             return false;
    308         }
    309         return ((mNetworkCapabilities & (1 << capability)) != 0);
    310     }
    311 
    312     private void combineNetCapabilities(NetworkCapabilities nc) {
    313         this.mNetworkCapabilities |= nc.mNetworkCapabilities;
    314     }
    315 
    316     /**
    317      * Convenience function that returns a human-readable description of the first mutable
    318      * capability we find. Used to present an error message to apps that request mutable
    319      * capabilities.
    320      *
    321      * @hide
    322      */
    323     public String describeFirstNonRequestableCapability() {
    324         if (hasCapability(NET_CAPABILITY_VALIDATED)) return "NET_CAPABILITY_VALIDATED";
    325         if (hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return "NET_CAPABILITY_CAPTIVE_PORTAL";
    326         if (hasCapability(NET_CAPABILITY_FOREGROUND)) return "NET_CAPABILITY_FOREGROUND";
    327         // This cannot happen unless the preceding checks are incomplete.
    328         if ((mNetworkCapabilities & NON_REQUESTABLE_CAPABILITIES) != 0) {
    329             return "unknown non-requestable capabilities " + Long.toHexString(mNetworkCapabilities);
    330         }
    331         if (mLinkUpBandwidthKbps != 0 || mLinkDownBandwidthKbps != 0) return "link bandwidth";
    332         if (hasSignalStrength()) return "signalStrength";
    333         return null;
    334     }
    335 
    336     private boolean satisfiedByNetCapabilities(NetworkCapabilities nc, boolean onlyImmutable) {
    337         long networkCapabilities = this.mNetworkCapabilities;
    338         if (onlyImmutable) {
    339             networkCapabilities = networkCapabilities & ~MUTABLE_CAPABILITIES;
    340         }
    341         return ((nc.mNetworkCapabilities & networkCapabilities) == networkCapabilities);
    342     }
    343 
    344     /** @hide */
    345     public boolean equalsNetCapabilities(NetworkCapabilities nc) {
    346         return (nc.mNetworkCapabilities == this.mNetworkCapabilities);
    347     }
    348 
    349     private boolean equalsNetCapabilitiesImmutable(NetworkCapabilities that) {
    350         return ((this.mNetworkCapabilities & ~MUTABLE_CAPABILITIES) ==
    351                 (that.mNetworkCapabilities & ~MUTABLE_CAPABILITIES));
    352     }
    353 
    354     private boolean equalsNetCapabilitiesRequestable(NetworkCapabilities that) {
    355         return ((this.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) ==
    356                 (that.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES));
    357     }
    358 
    359     /**
    360      * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if all the capabilities it provides are
    361      * typically provided by restricted networks.
    362      *
    363      * TODO: consider:
    364      * - Renaming it to guessRestrictedCapability and make it set the
    365      *   restricted capability bit in addition to clearing it.
    366      * @hide
    367      */
    368     public void maybeMarkCapabilitiesRestricted() {
    369         // Verify there aren't any unrestricted capabilities.  If there are we say
    370         // the whole thing is unrestricted.
    371         final boolean hasUnrestrictedCapabilities =
    372                 ((mNetworkCapabilities & UNRESTRICTED_CAPABILITIES) != 0);
    373 
    374         // Must have at least some restricted capabilities.
    375         final boolean hasRestrictedCapabilities =
    376                 ((mNetworkCapabilities & RESTRICTED_CAPABILITIES) != 0);
    377 
    378         if (hasRestrictedCapabilities && !hasUnrestrictedCapabilities) {
    379             removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
    380         }
    381     }
    382 
    383     /**
    384      * Representing the transport type.  Apps should generally not care about transport.  A
    385      * request for a fast internet connection could be satisfied by a number of different
    386      * transports.  If any are specified here it will be satisfied a Network that matches
    387      * any of them.  If a caller doesn't care about the transport it should not specify any.
    388      */
    389     private long mTransportTypes;
    390 
    391     /**
    392      * Indicates this network uses a Cellular transport.
    393      */
    394     public static final int TRANSPORT_CELLULAR = 0;
    395 
    396     /**
    397      * Indicates this network uses a Wi-Fi transport.
    398      */
    399     public static final int TRANSPORT_WIFI = 1;
    400 
    401     /**
    402      * Indicates this network uses a Bluetooth transport.
    403      */
    404     public static final int TRANSPORT_BLUETOOTH = 2;
    405 
    406     /**
    407      * Indicates this network uses an Ethernet transport.
    408      */
    409     public static final int TRANSPORT_ETHERNET = 3;
    410 
    411     /**
    412      * Indicates this network uses a VPN transport.
    413      */
    414     public static final int TRANSPORT_VPN = 4;
    415 
    416     /**
    417      * Indicates this network uses a Wi-Fi Aware transport.
    418      */
    419     public static final int TRANSPORT_WIFI_AWARE = 5;
    420 
    421     /** @hide */
    422     public static final int MIN_TRANSPORT = TRANSPORT_CELLULAR;
    423     /** @hide */
    424     public static final int MAX_TRANSPORT = TRANSPORT_WIFI_AWARE;
    425 
    426     private static final String[] TRANSPORT_NAMES = {
    427         "CELLULAR",
    428         "WIFI",
    429         "BLUETOOTH",
    430         "ETHERNET",
    431         "VPN",
    432         "WIFI_AWARE"
    433     };
    434 
    435     /**
    436      * Adds the given transport type to this {@code NetworkCapability} instance.
    437      * Multiple transports may be applied sequentially.  Note that when searching
    438      * for a network to satisfy a request, any listed in the request will satisfy the request.
    439      * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a
    440      * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network
    441      * to be selected.  This is logically different than
    442      * {@code NetworkCapabilities.NET_CAPABILITY_*} listed above.
    443      *
    444      * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be added.
    445      * @return This NetworkCapabilities instance, to facilitate chaining.
    446      * @hide
    447      */
    448     public NetworkCapabilities addTransportType(int transportType) {
    449         if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
    450             throw new IllegalArgumentException("TransportType out of range");
    451         }
    452         mTransportTypes |= 1 << transportType;
    453         setNetworkSpecifier(mNetworkSpecifier); // used for exception checking
    454         return this;
    455     }
    456 
    457     /**
    458      * Removes (if found) the given transport from this {@code NetworkCapability} instance.
    459      *
    460      * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be removed.
    461      * @return This NetworkCapabilities instance, to facilitate chaining.
    462      * @hide
    463      */
    464     public NetworkCapabilities removeTransportType(int transportType) {
    465         if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
    466             throw new IllegalArgumentException("TransportType out of range");
    467         }
    468         mTransportTypes &= ~(1 << transportType);
    469         setNetworkSpecifier(mNetworkSpecifier); // used for exception checking
    470         return this;
    471     }
    472 
    473     /**
    474      * Gets all the transports set on this {@code NetworkCapability} instance.
    475      *
    476      * @return an array of {@code NetworkCapabilities.TRANSPORT_*} values
    477      *         for this instance.
    478      * @hide
    479      */
    480     public int[] getTransportTypes() {
    481         return BitUtils.unpackBits(mTransportTypes);
    482     }
    483 
    484     /**
    485      * Tests for the presence of a transport on this instance.
    486      *
    487      * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be tested for.
    488      * @return {@code true} if set on this instance.
    489      */
    490     public boolean hasTransport(int transportType) {
    491         if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
    492             return false;
    493         }
    494         return ((mTransportTypes & (1 << transportType)) != 0);
    495     }
    496 
    497     private void combineTransportTypes(NetworkCapabilities nc) {
    498         this.mTransportTypes |= nc.mTransportTypes;
    499     }
    500     private boolean satisfiedByTransportTypes(NetworkCapabilities nc) {
    501         return ((this.mTransportTypes == 0) ||
    502                 ((this.mTransportTypes & nc.mTransportTypes) != 0));
    503     }
    504     /** @hide */
    505     public boolean equalsTransportTypes(NetworkCapabilities nc) {
    506         return (nc.mTransportTypes == this.mTransportTypes);
    507     }
    508 
    509     /**
    510      * Passive link bandwidth.  This is a rough guide of the expected peak bandwidth
    511      * for the first hop on the given transport.  It is not measured, but may take into account
    512      * link parameters (Radio technology, allocated channels, etc).
    513      */
    514     private int mLinkUpBandwidthKbps;
    515     private int mLinkDownBandwidthKbps;
    516 
    517     /**
    518      * Sets the upstream bandwidth for this network in Kbps.  This always only refers to
    519      * the estimated first hop transport bandwidth.
    520      * <p>
    521      * Note that when used to request a network, this specifies the minimum acceptable.
    522      * When received as the state of an existing network this specifies the typical
    523      * first hop bandwidth expected.  This is never measured, but rather is inferred
    524      * from technology type and other link parameters.  It could be used to differentiate
    525      * between very slow 1xRTT cellular links and other faster networks or even between
    526      * 802.11b vs 802.11AC wifi technologies.  It should not be used to differentiate between
    527      * fast backhauls and slow backhauls.
    528      *
    529      * @param upKbps the estimated first hop upstream (device to network) bandwidth.
    530      * @hide
    531      */
    532     public void setLinkUpstreamBandwidthKbps(int upKbps) {
    533         mLinkUpBandwidthKbps = upKbps;
    534     }
    535 
    536     /**
    537      * Retrieves the upstream bandwidth for this network in Kbps.  This always only refers to
    538      * the estimated first hop transport bandwidth.
    539      *
    540      * @return The estimated first hop upstream (device to network) bandwidth.
    541      */
    542     public int getLinkUpstreamBandwidthKbps() {
    543         return mLinkUpBandwidthKbps;
    544     }
    545 
    546     /**
    547      * Sets the downstream bandwidth for this network in Kbps.  This always only refers to
    548      * the estimated first hop transport bandwidth.
    549      * <p>
    550      * Note that when used to request a network, this specifies the minimum acceptable.
    551      * When received as the state of an existing network this specifies the typical
    552      * first hop bandwidth expected.  This is never measured, but rather is inferred
    553      * from technology type and other link parameters.  It could be used to differentiate
    554      * between very slow 1xRTT cellular links and other faster networks or even between
    555      * 802.11b vs 802.11AC wifi technologies.  It should not be used to differentiate between
    556      * fast backhauls and slow backhauls.
    557      *
    558      * @param downKbps the estimated first hop downstream (network to device) bandwidth.
    559      * @hide
    560      */
    561     public void setLinkDownstreamBandwidthKbps(int downKbps) {
    562         mLinkDownBandwidthKbps = downKbps;
    563     }
    564 
    565     /**
    566      * Retrieves the downstream bandwidth for this network in Kbps.  This always only refers to
    567      * the estimated first hop transport bandwidth.
    568      *
    569      * @return The estimated first hop downstream (network to device) bandwidth.
    570      */
    571     public int getLinkDownstreamBandwidthKbps() {
    572         return mLinkDownBandwidthKbps;
    573     }
    574 
    575     private void combineLinkBandwidths(NetworkCapabilities nc) {
    576         this.mLinkUpBandwidthKbps =
    577                 Math.max(this.mLinkUpBandwidthKbps, nc.mLinkUpBandwidthKbps);
    578         this.mLinkDownBandwidthKbps =
    579                 Math.max(this.mLinkDownBandwidthKbps, nc.mLinkDownBandwidthKbps);
    580     }
    581     private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) {
    582         return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps ||
    583                 this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps);
    584     }
    585     private boolean equalsLinkBandwidths(NetworkCapabilities nc) {
    586         return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps &&
    587                 this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
    588     }
    589 
    590     private NetworkSpecifier mNetworkSpecifier = null;
    591 
    592     /**
    593      * Sets the optional bearer specific network specifier.
    594      * This has no meaning if a single transport is also not specified, so calling
    595      * this without a single transport set will generate an exception, as will
    596      * subsequently adding or removing transports after this is set.
    597      * </p>
    598      *
    599      * @param networkSpecifier A concrete, parcelable framework class that extends
    600      *                         NetworkSpecifier.
    601      * @return This NetworkCapabilities instance, to facilitate chaining.
    602      * @hide
    603      */
    604     public NetworkCapabilities setNetworkSpecifier(NetworkSpecifier networkSpecifier) {
    605         if (networkSpecifier != null && Long.bitCount(mTransportTypes) != 1) {
    606             throw new IllegalStateException("Must have a single transport specified to use " +
    607                     "setNetworkSpecifier");
    608         }
    609 
    610         mNetworkSpecifier = networkSpecifier;
    611 
    612         return this;
    613     }
    614 
    615     /**
    616      * Gets the optional bearer specific network specifier.
    617      *
    618      * @return The optional {@link NetworkSpecifier} specifying the bearer specific network
    619      *         specifier. See {@link #setNetworkSpecifier}.
    620      * @hide
    621      */
    622     public NetworkSpecifier getNetworkSpecifier() {
    623         return mNetworkSpecifier;
    624     }
    625 
    626     private void combineSpecifiers(NetworkCapabilities nc) {
    627         if (mNetworkSpecifier != null && !mNetworkSpecifier.equals(nc.mNetworkSpecifier)) {
    628             throw new IllegalStateException("Can't combine two networkSpecifiers");
    629         }
    630         setNetworkSpecifier(nc.mNetworkSpecifier);
    631     }
    632 
    633     private boolean satisfiedBySpecifier(NetworkCapabilities nc) {
    634         return mNetworkSpecifier == null || mNetworkSpecifier.satisfiedBy(nc.mNetworkSpecifier)
    635                 || nc.mNetworkSpecifier instanceof MatchAllNetworkSpecifier;
    636     }
    637 
    638     private boolean equalsSpecifier(NetworkCapabilities nc) {
    639         return Objects.equals(mNetworkSpecifier, nc.mNetworkSpecifier);
    640     }
    641 
    642     /**
    643      * Magic value that indicates no signal strength provided. A request specifying this value is
    644      * always satisfied.
    645      *
    646      * @hide
    647      */
    648     public static final int SIGNAL_STRENGTH_UNSPECIFIED = Integer.MIN_VALUE;
    649 
    650     /**
    651      * Signal strength. This is a signed integer, and higher values indicate better signal.
    652      * The exact units are bearer-dependent. For example, Wi-Fi uses RSSI.
    653      */
    654     private int mSignalStrength;
    655 
    656     /**
    657      * Sets the signal strength. This is a signed integer, with higher values indicating a stronger
    658      * signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same RSSI units
    659      * reported by WifiManager.
    660      * <p>
    661      * Note that when used to register a network callback, this specifies the minimum acceptable
    662      * signal strength. When received as the state of an existing network it specifies the current
    663      * value. A value of code SIGNAL_STRENGTH_UNSPECIFIED} means no value when received and has no
    664      * effect when requesting a callback.
    665      *
    666      * @param signalStrength the bearer-specific signal strength.
    667      * @hide
    668      */
    669     public void setSignalStrength(int signalStrength) {
    670         mSignalStrength = signalStrength;
    671     }
    672 
    673     /**
    674      * Returns {@code true} if this object specifies a signal strength.
    675      *
    676      * @hide
    677      */
    678     public boolean hasSignalStrength() {
    679         return mSignalStrength > SIGNAL_STRENGTH_UNSPECIFIED;
    680     }
    681 
    682     /**
    683      * Retrieves the signal strength.
    684      *
    685      * @return The bearer-specific signal strength.
    686      * @hide
    687      */
    688     public int getSignalStrength() {
    689         return mSignalStrength;
    690     }
    691 
    692     private void combineSignalStrength(NetworkCapabilities nc) {
    693         this.mSignalStrength = Math.max(this.mSignalStrength, nc.mSignalStrength);
    694     }
    695 
    696     private boolean satisfiedBySignalStrength(NetworkCapabilities nc) {
    697         return this.mSignalStrength <= nc.mSignalStrength;
    698     }
    699 
    700     private boolean equalsSignalStrength(NetworkCapabilities nc) {
    701         return this.mSignalStrength == nc.mSignalStrength;
    702     }
    703 
    704     /**
    705      * Combine a set of Capabilities to this one.  Useful for coming up with the complete set
    706      * @hide
    707      */
    708     public void combineCapabilities(NetworkCapabilities nc) {
    709         combineNetCapabilities(nc);
    710         combineTransportTypes(nc);
    711         combineLinkBandwidths(nc);
    712         combineSpecifiers(nc);
    713         combineSignalStrength(nc);
    714     }
    715 
    716     /**
    717      * Check if our requirements are satisfied by the given {@code NetworkCapabilities}.
    718      *
    719      * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
    720      * @param onlyImmutable if {@code true}, do not consider mutable requirements such as link
    721      *         bandwidth, signal strength, or validation / captive portal status.
    722      *
    723      * @hide
    724      */
    725     private boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc, boolean onlyImmutable) {
    726         return (nc != null &&
    727                 satisfiedByNetCapabilities(nc, onlyImmutable) &&
    728                 satisfiedByTransportTypes(nc) &&
    729                 (onlyImmutable || satisfiedByLinkBandwidths(nc)) &&
    730                 satisfiedBySpecifier(nc) &&
    731                 (onlyImmutable || satisfiedBySignalStrength(nc)));
    732     }
    733 
    734     /**
    735      * Check if our requirements are satisfied by the given {@code NetworkCapabilities}.
    736      *
    737      * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
    738      *
    739      * @hide
    740      */
    741     public boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc) {
    742         return satisfiedByNetworkCapabilities(nc, false);
    743     }
    744 
    745     /**
    746      * Check if our immutable requirements are satisfied by the given {@code NetworkCapabilities}.
    747      *
    748      * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
    749      *
    750      * @hide
    751      */
    752     public boolean satisfiedByImmutableNetworkCapabilities(NetworkCapabilities nc) {
    753         return satisfiedByNetworkCapabilities(nc, true);
    754     }
    755 
    756     /**
    757      * Checks that our immutable capabilities are the same as those of the given
    758      * {@code NetworkCapabilities}.
    759      *
    760      * @hide
    761      */
    762     public boolean equalImmutableCapabilities(NetworkCapabilities nc) {
    763         if (nc == null) return false;
    764         return (equalsNetCapabilitiesImmutable(nc) &&
    765                 equalsTransportTypes(nc) &&
    766                 equalsSpecifier(nc));
    767     }
    768 
    769     /**
    770      * Checks that our requestable capabilities are the same as those of the given
    771      * {@code NetworkCapabilities}.
    772      *
    773      * @hide
    774      */
    775     public boolean equalRequestableCapabilities(NetworkCapabilities nc) {
    776         if (nc == null) return false;
    777         return (equalsNetCapabilitiesRequestable(nc) &&
    778                 equalsTransportTypes(nc) &&
    779                 equalsSpecifier(nc));
    780     }
    781 
    782     @Override
    783     public boolean equals(Object obj) {
    784         if (obj == null || (obj instanceof NetworkCapabilities == false)) return false;
    785         NetworkCapabilities that = (NetworkCapabilities)obj;
    786         return (equalsNetCapabilities(that) &&
    787                 equalsTransportTypes(that) &&
    788                 equalsLinkBandwidths(that) &&
    789                 equalsSignalStrength(that) &&
    790                 equalsSpecifier(that));
    791     }
    792 
    793     @Override
    794     public int hashCode() {
    795         return ((int)(mNetworkCapabilities & 0xFFFFFFFF) +
    796                 ((int)(mNetworkCapabilities >> 32) * 3) +
    797                 ((int)(mTransportTypes & 0xFFFFFFFF) * 5) +
    798                 ((int)(mTransportTypes >> 32) * 7) +
    799                 (mLinkUpBandwidthKbps * 11) +
    800                 (mLinkDownBandwidthKbps * 13) +
    801                 Objects.hashCode(mNetworkSpecifier) * 17 +
    802                 (mSignalStrength * 19));
    803     }
    804 
    805     @Override
    806     public int describeContents() {
    807         return 0;
    808     }
    809     @Override
    810     public void writeToParcel(Parcel dest, int flags) {
    811         dest.writeLong(mNetworkCapabilities);
    812         dest.writeLong(mTransportTypes);
    813         dest.writeInt(mLinkUpBandwidthKbps);
    814         dest.writeInt(mLinkDownBandwidthKbps);
    815         dest.writeParcelable((Parcelable) mNetworkSpecifier, flags);
    816         dest.writeInt(mSignalStrength);
    817     }
    818 
    819     public static final Creator<NetworkCapabilities> CREATOR =
    820         new Creator<NetworkCapabilities>() {
    821             @Override
    822             public NetworkCapabilities createFromParcel(Parcel in) {
    823                 NetworkCapabilities netCap = new NetworkCapabilities();
    824 
    825                 netCap.mNetworkCapabilities = in.readLong();
    826                 netCap.mTransportTypes = in.readLong();
    827                 netCap.mLinkUpBandwidthKbps = in.readInt();
    828                 netCap.mLinkDownBandwidthKbps = in.readInt();
    829                 netCap.mNetworkSpecifier = in.readParcelable(null);
    830                 netCap.mSignalStrength = in.readInt();
    831                 return netCap;
    832             }
    833             @Override
    834             public NetworkCapabilities[] newArray(int size) {
    835                 return new NetworkCapabilities[size];
    836             }
    837         };
    838 
    839     @Override
    840     public String toString() {
    841         int[] types = getTransportTypes();
    842         String transports = (types.length > 0) ? " Transports: " + transportNamesOf(types) : "";
    843 
    844         types = getCapabilities();
    845         String capabilities = (types.length > 0 ? " Capabilities: " : "");
    846         for (int i = 0; i < types.length; ) {
    847             switch (types[i]) {
    848                 case NET_CAPABILITY_MMS:            capabilities += "MMS"; break;
    849                 case NET_CAPABILITY_SUPL:           capabilities += "SUPL"; break;
    850                 case NET_CAPABILITY_DUN:            capabilities += "DUN"; break;
    851                 case NET_CAPABILITY_FOTA:           capabilities += "FOTA"; break;
    852                 case NET_CAPABILITY_IMS:            capabilities += "IMS"; break;
    853                 case NET_CAPABILITY_CBS:            capabilities += "CBS"; break;
    854                 case NET_CAPABILITY_WIFI_P2P:       capabilities += "WIFI_P2P"; break;
    855                 case NET_CAPABILITY_IA:             capabilities += "IA"; break;
    856                 case NET_CAPABILITY_RCS:            capabilities += "RCS"; break;
    857                 case NET_CAPABILITY_XCAP:           capabilities += "XCAP"; break;
    858                 case NET_CAPABILITY_EIMS:           capabilities += "EIMS"; break;
    859                 case NET_CAPABILITY_NOT_METERED:    capabilities += "NOT_METERED"; break;
    860                 case NET_CAPABILITY_INTERNET:       capabilities += "INTERNET"; break;
    861                 case NET_CAPABILITY_NOT_RESTRICTED: capabilities += "NOT_RESTRICTED"; break;
    862                 case NET_CAPABILITY_TRUSTED:        capabilities += "TRUSTED"; break;
    863                 case NET_CAPABILITY_NOT_VPN:        capabilities += "NOT_VPN"; break;
    864                 case NET_CAPABILITY_VALIDATED:      capabilities += "VALIDATED"; break;
    865                 case NET_CAPABILITY_CAPTIVE_PORTAL: capabilities += "CAPTIVE_PORTAL"; break;
    866                 case NET_CAPABILITY_FOREGROUND:     capabilities += "FOREGROUND"; break;
    867             }
    868             if (++i < types.length) capabilities += "&";
    869         }
    870 
    871         String upBand = ((mLinkUpBandwidthKbps > 0) ? " LinkUpBandwidth>=" +
    872                 mLinkUpBandwidthKbps + "Kbps" : "");
    873         String dnBand = ((mLinkDownBandwidthKbps > 0) ? " LinkDnBandwidth>=" +
    874                 mLinkDownBandwidthKbps + "Kbps" : "");
    875 
    876         String specifier = (mNetworkSpecifier == null ?
    877                 "" : " Specifier: <" + mNetworkSpecifier + ">");
    878 
    879         String signalStrength = (hasSignalStrength() ? " SignalStrength: " + mSignalStrength : "");
    880 
    881         return "[" + transports + capabilities + upBand + dnBand + specifier + signalStrength + "]";
    882     }
    883 
    884     /**
    885      * @hide
    886      */
    887     public static String transportNamesOf(int[] types) {
    888         if (types == null || types.length == 0) {
    889             return "";
    890         }
    891         StringBuilder transports = new StringBuilder();
    892         for (int t : types) {
    893             transports.append("|").append(transportNameOf(t));
    894         }
    895         return transports.substring(1);
    896     }
    897 
    898     /**
    899      * @hide
    900      */
    901     public static String transportNameOf(int transport) {
    902         if (transport < 0 || TRANSPORT_NAMES.length <= transport) {
    903             return "UNKNOWN";
    904         }
    905         return TRANSPORT_NAMES[transport];
    906     }
    907 }
    908