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