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