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 
     23 import java.util.Objects;
     24 
     25 /**
     26  * Defines a request for a network, made through {@link NetworkRequest.Builder} and used
     27  * to request a network via {@link ConnectivityManager#requestNetwork} or listen for changes
     28  * via {@link ConnectivityManager#registerNetworkCallback}.
     29  */
     30 public class NetworkRequest implements Parcelable {
     31     /**
     32      * The {@link NetworkCapabilities} that define this request.
     33      * @hide
     34      */
     35     public final NetworkCapabilities networkCapabilities;
     36 
     37     /**
     38      * Identifies the request.  NetworkRequests should only be constructed by
     39      * the Framework and given out to applications as tokens to be used to identify
     40      * the request.
     41      * @hide
     42      */
     43     public final int requestId;
     44 
     45     /**
     46      * Set for legacy requests and the default.  Set to TYPE_NONE for none.
     47      * Causes CONNECTIVITY_ACTION broadcasts to be sent.
     48      * @hide
     49      */
     50     public final int legacyType;
     51 
     52     /**
     53      * A NetworkRequest as used by the system can be one of the following types:
     54      *
     55      *     - LISTEN, for which the framework will issue callbacks about any
     56      *       and all networks that match the specified NetworkCapabilities,
     57      *
     58      *     - REQUEST, capable of causing a specific network to be created
     59      *       first (e.g. a telephony DUN request), the framework will issue
     60      *       callbacks about the single, highest scoring current network
     61      *       (if any) that matches the specified NetworkCapabilities, or
     62      *
     63      *     - TRACK_DEFAULT, a hybrid of the two designed such that the
     64      *       framework will issue callbacks for the single, highest scoring
     65      *       current network (if any) that matches the capabilities of the
     66      *       default Internet request (mDefaultRequest), but which cannot cause
     67      *       the framework to either create or retain the existence of any
     68      *       specific network. Note that from the point of view of the request
     69      *       matching code, TRACK_DEFAULT is identical to REQUEST: its special
     70      *       behaviour is not due to different semantics, but to the fact that
     71      *       the system will only ever create a TRACK_DEFAULT with capabilities
     72      *       that are identical to the default request's capabilities, thus
     73      *       causing it to share fate in every way with the default request.
     74      *
     75      *     - BACKGROUND_REQUEST, like REQUEST but does not cause any networks
     76      *       to retain the NET_CAPABILITY_FOREGROUND capability. A network with
     77      *       no foreground requests is in the background. A network that has
     78      *       one or more background requests and loses its last foreground
     79      *       request to a higher-scoring network will not go into the
     80      *       background immediately, but will linger and go into the background
     81      *       after the linger timeout.
     82      *
     83      *     - The value NONE is used only by applications. When an application
     84      *       creates a NetworkRequest, it does not have a type; the type is set
     85      *       by the system depending on the method used to file the request
     86      *       (requestNetwork, registerNetworkCallback, etc.).
     87      *
     88      * @hide
     89      */
     90     public static enum Type {
     91         NONE,
     92         LISTEN,
     93         TRACK_DEFAULT,
     94         REQUEST,
     95         BACKGROUND_REQUEST,
     96     };
     97 
     98     /**
     99      * The type of the request. This is only used by the system and is always NONE elsewhere.
    100      *
    101      * @hide
    102      */
    103     public final Type type;
    104 
    105     /**
    106      * @hide
    107      */
    108     public NetworkRequest(NetworkCapabilities nc, int legacyType, int rId, Type type) {
    109         if (nc == null) {
    110             throw new NullPointerException();
    111         }
    112         requestId = rId;
    113         networkCapabilities = nc;
    114         this.legacyType = legacyType;
    115         this.type = type;
    116     }
    117 
    118     /**
    119      * @hide
    120      */
    121     public NetworkRequest(NetworkRequest that) {
    122         networkCapabilities = new NetworkCapabilities(that.networkCapabilities);
    123         requestId = that.requestId;
    124         this.legacyType = that.legacyType;
    125         this.type = that.type;
    126     }
    127 
    128     /**
    129      * Builder used to create {@link NetworkRequest} objects.  Specify the Network features
    130      * needed in terms of {@link NetworkCapabilities} features
    131      */
    132     public static class Builder {
    133         private final NetworkCapabilities mNetworkCapabilities = new NetworkCapabilities();
    134 
    135         /**
    136          * Default constructor for Builder.
    137          */
    138         public Builder() {}
    139 
    140         /**
    141          * Build {@link NetworkRequest} give the current set of capabilities.
    142          */
    143         public NetworkRequest build() {
    144             // Make a copy of mNetworkCapabilities so we don't inadvertently remove NOT_RESTRICTED
    145             // when later an unrestricted capability could be added to mNetworkCapabilities, in
    146             // which case NOT_RESTRICTED should be returned to mNetworkCapabilities, which
    147             // maybeMarkCapabilitiesRestricted() doesn't add back.
    148             final NetworkCapabilities nc = new NetworkCapabilities(mNetworkCapabilities);
    149             nc.maybeMarkCapabilitiesRestricted();
    150             return new NetworkRequest(nc, ConnectivityManager.TYPE_NONE,
    151                     ConnectivityManager.REQUEST_ID_UNSET, Type.NONE);
    152         }
    153 
    154         /**
    155          * Add the given capability requirement to this builder.  These represent
    156          * the requested network's required capabilities.  Note that when searching
    157          * for a network to satisfy a request, all capabilities requested must be
    158          * satisfied.  See {@link NetworkCapabilities} for {@code NET_CAPABILITY_*}
    159          * definitions.
    160          *
    161          * @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to add.
    162          * @return The builder to facilitate chaining
    163          *         {@code builder.addCapability(...).addCapability();}.
    164          */
    165         public Builder addCapability(int capability) {
    166             mNetworkCapabilities.addCapability(capability);
    167             return this;
    168         }
    169 
    170         /**
    171          * Removes (if found) the given capability from this builder instance.
    172          *
    173          * @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to remove.
    174          * @return The builder to facilitate chaining.
    175          */
    176         public Builder removeCapability(int capability) {
    177             mNetworkCapabilities.removeCapability(capability);
    178             return this;
    179         }
    180 
    181         /**
    182          * Set the {@code NetworkCapabilities} for this builder instance,
    183          * overriding any capabilities that had been previously set.
    184          *
    185          * @param nc The superseding {@code NetworkCapabilities} instance.
    186          * @return The builder to facilitate chaining.
    187          * @hide
    188          */
    189         public Builder setCapabilities(NetworkCapabilities nc) {
    190             mNetworkCapabilities.clearAll();
    191             mNetworkCapabilities.combineCapabilities(nc);
    192             return this;
    193         }
    194 
    195         /**
    196          * Completely clears all the {@code NetworkCapabilities} from this builder instance,
    197          * removing even the capabilities that are set by default when the object is constructed.
    198          *
    199          * @return The builder to facilitate chaining.
    200          * @hide
    201          */
    202         public Builder clearCapabilities() {
    203             mNetworkCapabilities.clearAll();
    204             return this;
    205         }
    206 
    207         /**
    208          * Adds the given transport requirement to this builder.  These represent
    209          * the set of allowed transports for the request.  Only networks using one
    210          * of these transports will satisfy the request.  If no particular transports
    211          * are required, none should be specified here.  See {@link NetworkCapabilities}
    212          * for {@code TRANSPORT_*} definitions.
    213          *
    214          * @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to add.
    215          * @return The builder to facilitate chaining.
    216          */
    217         public Builder addTransportType(int transportType) {
    218             mNetworkCapabilities.addTransportType(transportType);
    219             return this;
    220         }
    221 
    222         /**
    223          * Removes (if found) the given transport from this builder instance.
    224          *
    225          * @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to remove.
    226          * @return The builder to facilitate chaining.
    227          */
    228         public Builder removeTransportType(int transportType) {
    229             mNetworkCapabilities.removeTransportType(transportType);
    230             return this;
    231         }
    232 
    233         /**
    234          * @hide
    235          */
    236         public Builder setLinkUpstreamBandwidthKbps(int upKbps) {
    237             mNetworkCapabilities.setLinkUpstreamBandwidthKbps(upKbps);
    238             return this;
    239         }
    240         /**
    241          * @hide
    242          */
    243         public Builder setLinkDownstreamBandwidthKbps(int downKbps) {
    244             mNetworkCapabilities.setLinkDownstreamBandwidthKbps(downKbps);
    245             return this;
    246         }
    247 
    248         /**
    249          * Sets the optional bearer specific network specifier.
    250          * This has no meaning if a single transport is also not specified, so calling
    251          * this without a single transport set will generate an exception, as will
    252          * subsequently adding or removing transports after this is set.
    253          * </p>
    254          * The interpretation of this {@code String} is bearer specific and bearers that use
    255          * it should document their particulars.  For example, Bluetooth may use some sort of
    256          * device id while WiFi could used ssid and/or bssid.  Cellular may use carrier spn.
    257          *
    258          * @param networkSpecifier An {@code String} of opaque format used to specify the bearer
    259          *                         specific network specifier where the bearer has a choice of
    260          *                         networks.
    261          */
    262         public Builder setNetworkSpecifier(String networkSpecifier) {
    263             /*
    264              * A StringNetworkSpecifier does not accept null or empty ("") strings. When network
    265              * specifiers were strings a null string and an empty string were considered equivalent.
    266              * Hence no meaning is attached to a null or empty ("") string.
    267              */
    268             return setNetworkSpecifier(TextUtils.isEmpty(networkSpecifier) ? null
    269                     : new StringNetworkSpecifier(networkSpecifier));
    270         }
    271 
    272         /**
    273          * Sets the optional bearer specific network specifier.
    274          * This has no meaning if a single transport is also not specified, so calling
    275          * this without a single transport set will generate an exception, as will
    276          * subsequently adding or removing transports after this is set.
    277          * </p>
    278          *
    279          * @param networkSpecifier A concrete, parcelable framework class that extends
    280          *                         NetworkSpecifier.
    281          */
    282         public Builder setNetworkSpecifier(NetworkSpecifier networkSpecifier) {
    283             MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(networkSpecifier);
    284             mNetworkCapabilities.setNetworkSpecifier(networkSpecifier);
    285             return this;
    286         }
    287 
    288         /**
    289          * Sets the signal strength. This is a signed integer, with higher values indicating a
    290          * stronger signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same
    291          * RSSI units reported by WifiManager.
    292          * <p>
    293          * Note that when used to register a network callback, this specifies the minimum acceptable
    294          * signal strength. When received as the state of an existing network it specifies the
    295          * current value. A value of {@code SIGNAL_STRENGTH_UNSPECIFIED} means no value when
    296          * received and has no effect when requesting a callback.
    297          *
    298          * @param signalStrength the bearer-specific signal strength.
    299          * @hide
    300          */
    301         public Builder setSignalStrength(int signalStrength) {
    302             mNetworkCapabilities.setSignalStrength(signalStrength);
    303             return this;
    304         }
    305     }
    306 
    307     // implement the Parcelable interface
    308     public int describeContents() {
    309         return 0;
    310     }
    311     public void writeToParcel(Parcel dest, int flags) {
    312         dest.writeParcelable(networkCapabilities, flags);
    313         dest.writeInt(legacyType);
    314         dest.writeInt(requestId);
    315         dest.writeString(type.name());
    316     }
    317     public static final Creator<NetworkRequest> CREATOR =
    318         new Creator<NetworkRequest>() {
    319             public NetworkRequest createFromParcel(Parcel in) {
    320                 NetworkCapabilities nc = (NetworkCapabilities)in.readParcelable(null);
    321                 int legacyType = in.readInt();
    322                 int requestId = in.readInt();
    323                 Type type = Type.valueOf(in.readString());  // IllegalArgumentException if invalid.
    324                 NetworkRequest result = new NetworkRequest(nc, legacyType, requestId, type);
    325                 return result;
    326             }
    327             public NetworkRequest[] newArray(int size) {
    328                 return new NetworkRequest[size];
    329             }
    330         };
    331 
    332     /**
    333      * Returns true iff. this NetworkRequest is of type LISTEN.
    334      *
    335      * @hide
    336      */
    337     public boolean isListen() {
    338         return type == Type.LISTEN;
    339     }
    340 
    341     /**
    342      * Returns true iff. the contained NetworkRequest is one that:
    343      *
    344      *     - should be associated with at most one satisfying network
    345      *       at a time;
    346      *
    347      *     - should cause a network to be kept up, but not necessarily in
    348      *       the foreground, if it is the best network which can satisfy the
    349      *       NetworkRequest.
    350      *
    351      * For full detail of how isRequest() is used for pairing Networks with
    352      * NetworkRequests read rematchNetworkAndRequests().
    353      *
    354      * @hide
    355      */
    356     public boolean isRequest() {
    357         return isForegroundRequest() || isBackgroundRequest();
    358     }
    359 
    360     /**
    361      * Returns true iff. the contained NetworkRequest is one that:
    362      *
    363      *     - should be associated with at most one satisfying network
    364      *       at a time;
    365      *
    366      *     - should cause a network to be kept up and in the foreground if
    367      *       it is the best network which can satisfy the NetworkRequest.
    368      *
    369      * For full detail of how isRequest() is used for pairing Networks with
    370      * NetworkRequests read rematchNetworkAndRequests().
    371      *
    372      * @hide
    373      */
    374     public boolean isForegroundRequest() {
    375         return type == Type.TRACK_DEFAULT || type == Type.REQUEST;
    376     }
    377 
    378     /**
    379      * Returns true iff. this NetworkRequest is of type BACKGROUND_REQUEST.
    380      *
    381      * @hide
    382      */
    383     public boolean isBackgroundRequest() {
    384         return type == Type.BACKGROUND_REQUEST;
    385     }
    386 
    387     public String toString() {
    388         return "NetworkRequest [ " + type + " id=" + requestId +
    389                 (legacyType != ConnectivityManager.TYPE_NONE ? ", legacyType=" + legacyType : "") +
    390                 ", " + networkCapabilities.toString() + " ]";
    391     }
    392 
    393     public boolean equals(Object obj) {
    394         if (obj instanceof NetworkRequest == false) return false;
    395         NetworkRequest that = (NetworkRequest)obj;
    396         return (that.legacyType == this.legacyType &&
    397                 that.requestId == this.requestId &&
    398                 that.type == this.type &&
    399                 Objects.equals(that.networkCapabilities, this.networkCapabilities));
    400     }
    401 
    402     public int hashCode() {
    403         return Objects.hash(requestId, legacyType, networkCapabilities, type);
    404     }
    405 }
    406