Home | History | Annotate | Download | only in net
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.net;
     18 
     19 import android.annotation.NonNull;
     20 import android.net.NetworkCapabilities.NetCapability;
     21 import android.net.NetworkCapabilities.Transport;
     22 import android.os.Parcel;
     23 import android.os.Parcelable;
     24 import android.os.Process;
     25 import android.text.TextUtils;
     26 import android.util.proto.ProtoOutputStream;
     27 
     28 import java.util.Objects;
     29 import java.util.Set;
     30 
     31 /**
     32  * Defines a request for a network, made through {@link NetworkRequest.Builder} and used
     33  * to request a network via {@link ConnectivityManager#requestNetwork} or listen for changes
     34  * via {@link ConnectivityManager#registerNetworkCallback}.
     35  */
     36 public class NetworkRequest implements Parcelable {
     37     /**
     38      * The {@link NetworkCapabilities} that define this request.
     39      * @hide
     40      */
     41     public final @NonNull NetworkCapabilities networkCapabilities;
     42 
     43     /**
     44      * Identifies the request.  NetworkRequests should only be constructed by
     45      * the Framework and given out to applications as tokens to be used to identify
     46      * the request.
     47      * @hide
     48      */
     49     public final int requestId;
     50 
     51     /**
     52      * Set for legacy requests and the default.  Set to TYPE_NONE for none.
     53      * Causes CONNECTIVITY_ACTION broadcasts to be sent.
     54      * @hide
     55      */
     56     public final int legacyType;
     57 
     58     /**
     59      * A NetworkRequest as used by the system can be one of the following types:
     60      *
     61      *     - LISTEN, for which the framework will issue callbacks about any
     62      *       and all networks that match the specified NetworkCapabilities,
     63      *
     64      *     - REQUEST, capable of causing a specific network to be created
     65      *       first (e.g. a telephony DUN request), the framework will issue
     66      *       callbacks about the single, highest scoring current network
     67      *       (if any) that matches the specified NetworkCapabilities, or
     68      *
     69      *     - TRACK_DEFAULT, a hybrid of the two designed such that the
     70      *       framework will issue callbacks for the single, highest scoring
     71      *       current network (if any) that matches the capabilities of the
     72      *       default Internet request (mDefaultRequest), but which cannot cause
     73      *       the framework to either create or retain the existence of any
     74      *       specific network. Note that from the point of view of the request
     75      *       matching code, TRACK_DEFAULT is identical to REQUEST: its special
     76      *       behaviour is not due to different semantics, but to the fact that
     77      *       the system will only ever create a TRACK_DEFAULT with capabilities
     78      *       that are identical to the default request's capabilities, thus
     79      *       causing it to share fate in every way with the default request.
     80      *
     81      *     - BACKGROUND_REQUEST, like REQUEST but does not cause any networks
     82      *       to retain the NET_CAPABILITY_FOREGROUND capability. A network with
     83      *       no foreground requests is in the background. A network that has
     84      *       one or more background requests and loses its last foreground
     85      *       request to a higher-scoring network will not go into the
     86      *       background immediately, but will linger and go into the background
     87      *       after the linger timeout.
     88      *
     89      *     - The value NONE is used only by applications. When an application
     90      *       creates a NetworkRequest, it does not have a type; the type is set
     91      *       by the system depending on the method used to file the request
     92      *       (requestNetwork, registerNetworkCallback, etc.).
     93      *
     94      * @hide
     95      */
     96     public static enum Type {
     97         NONE,
     98         LISTEN,
     99         TRACK_DEFAULT,
    100         REQUEST,
    101         BACKGROUND_REQUEST,
    102     };
    103 
    104     /**
    105      * The type of the request. This is only used by the system and is always NONE elsewhere.
    106      *
    107      * @hide
    108      */
    109     public final Type type;
    110 
    111     /**
    112      * @hide
    113      */
    114     public NetworkRequest(NetworkCapabilities nc, int legacyType, int rId, Type type) {
    115         if (nc == null) {
    116             throw new NullPointerException();
    117         }
    118         requestId = rId;
    119         networkCapabilities = nc;
    120         this.legacyType = legacyType;
    121         this.type = type;
    122     }
    123 
    124     /**
    125      * @hide
    126      */
    127     public NetworkRequest(NetworkRequest that) {
    128         networkCapabilities = new NetworkCapabilities(that.networkCapabilities);
    129         requestId = that.requestId;
    130         this.legacyType = that.legacyType;
    131         this.type = that.type;
    132     }
    133 
    134     /**
    135      * Builder used to create {@link NetworkRequest} objects.  Specify the Network features
    136      * needed in terms of {@link NetworkCapabilities} features
    137      */
    138     public static class Builder {
    139         private final NetworkCapabilities mNetworkCapabilities;
    140 
    141         /**
    142          * Default constructor for Builder.
    143          */
    144         public Builder() {
    145             // By default, restrict this request to networks available to this app.
    146             // Apps can rescind this restriction, but ConnectivityService will enforce
    147             // it for apps that do not have the NETWORK_SETTINGS permission.
    148             mNetworkCapabilities = new NetworkCapabilities();
    149             mNetworkCapabilities.setSingleUid(Process.myUid());
    150         }
    151 
    152         /**
    153          * Build {@link NetworkRequest} give the current set of capabilities.
    154          */
    155         public NetworkRequest build() {
    156             // Make a copy of mNetworkCapabilities so we don't inadvertently remove NOT_RESTRICTED
    157             // when later an unrestricted capability could be added to mNetworkCapabilities, in
    158             // which case NOT_RESTRICTED should be returned to mNetworkCapabilities, which
    159             // maybeMarkCapabilitiesRestricted() doesn't add back.
    160             final NetworkCapabilities nc = new NetworkCapabilities(mNetworkCapabilities);
    161             nc.maybeMarkCapabilitiesRestricted();
    162             return new NetworkRequest(nc, ConnectivityManager.TYPE_NONE,
    163                     ConnectivityManager.REQUEST_ID_UNSET, Type.NONE);
    164         }
    165 
    166         /**
    167          * Add the given capability requirement to this builder.  These represent
    168          * the requested network's required capabilities.  Note that when searching
    169          * for a network to satisfy a request, all capabilities requested must be
    170          * satisfied.
    171          *
    172          * @param capability The capability to add.
    173          * @return The builder to facilitate chaining
    174          *         {@code builder.addCapability(...).addCapability();}.
    175          */
    176         public Builder addCapability(@NetworkCapabilities.NetCapability int capability) {
    177             mNetworkCapabilities.addCapability(capability);
    178             return this;
    179         }
    180 
    181         /**
    182          * Removes (if found) the given capability from this builder instance.
    183          *
    184          * @param capability The capability to remove.
    185          * @return The builder to facilitate chaining.
    186          */
    187         public Builder removeCapability(@NetworkCapabilities.NetCapability int capability) {
    188             mNetworkCapabilities.removeCapability(capability);
    189             return this;
    190         }
    191 
    192         /**
    193          * Set the {@code NetworkCapabilities} for this builder instance,
    194          * overriding any capabilities that had been previously set.
    195          *
    196          * @param nc The superseding {@code NetworkCapabilities} instance.
    197          * @return The builder to facilitate chaining.
    198          * @hide
    199          */
    200         public Builder setCapabilities(NetworkCapabilities nc) {
    201             mNetworkCapabilities.set(nc);
    202             return this;
    203         }
    204 
    205         /**
    206          * Set the watched UIDs for this request. This will be reset and wiped out unless
    207          * the calling app holds the CHANGE_NETWORK_STATE permission.
    208          *
    209          * @param uids The watched UIDs as a set of UidRanges, or null for everything.
    210          * @return The builder to facilitate chaining.
    211          * @hide
    212          */
    213         public Builder setUids(Set<UidRange> uids) {
    214             mNetworkCapabilities.setUids(uids);
    215             return this;
    216         }
    217 
    218         /**
    219          * Add a capability that must not exist in the requested network.
    220          * <p>
    221          * If the capability was previously added to the list of required capabilities (for
    222          * example, it was there by default or added using {@link #addCapability(int)} method), then
    223          * it will be removed from the list of required capabilities as well.
    224          *
    225          * @see #addCapability(int)
    226          *
    227          * @param capability The capability to add to unwanted capability list.
    228          * @return The builder to facilitate chaining.
    229          *
    230          * @hide
    231          */
    232         public Builder addUnwantedCapability(@NetworkCapabilities.NetCapability int capability) {
    233             mNetworkCapabilities.addUnwantedCapability(capability);
    234             return this;
    235         }
    236 
    237         /**
    238          * Completely clears all the {@code NetworkCapabilities} from this builder instance,
    239          * removing even the capabilities that are set by default when the object is constructed.
    240          *
    241          * @return The builder to facilitate chaining.
    242          * @hide
    243          */
    244         public Builder clearCapabilities() {
    245             mNetworkCapabilities.clearAll();
    246             return this;
    247         }
    248 
    249         /**
    250          * Adds the given transport requirement to this builder.  These represent
    251          * the set of allowed transports for the request.  Only networks using one
    252          * of these transports will satisfy the request.  If no particular transports
    253          * are required, none should be specified here.
    254          *
    255          * @param transportType The transport type to add.
    256          * @return The builder to facilitate chaining.
    257          */
    258         public Builder addTransportType(@NetworkCapabilities.Transport int transportType) {
    259             mNetworkCapabilities.addTransportType(transportType);
    260             return this;
    261         }
    262 
    263         /**
    264          * Removes (if found) the given transport from this builder instance.
    265          *
    266          * @param transportType The transport type to remove.
    267          * @return The builder to facilitate chaining.
    268          */
    269         public Builder removeTransportType(@NetworkCapabilities.Transport int transportType) {
    270             mNetworkCapabilities.removeTransportType(transportType);
    271             return this;
    272         }
    273 
    274         /**
    275          * @hide
    276          */
    277         public Builder setLinkUpstreamBandwidthKbps(int upKbps) {
    278             mNetworkCapabilities.setLinkUpstreamBandwidthKbps(upKbps);
    279             return this;
    280         }
    281         /**
    282          * @hide
    283          */
    284         public Builder setLinkDownstreamBandwidthKbps(int downKbps) {
    285             mNetworkCapabilities.setLinkDownstreamBandwidthKbps(downKbps);
    286             return this;
    287         }
    288 
    289         /**
    290          * Sets the optional bearer specific network specifier.
    291          * This has no meaning if a single transport is also not specified, so calling
    292          * this without a single transport set will generate an exception, as will
    293          * subsequently adding or removing transports after this is set.
    294          * </p>
    295          * The interpretation of this {@code String} is bearer specific and bearers that use
    296          * it should document their particulars.  For example, Bluetooth may use some sort of
    297          * device id while WiFi could used ssid and/or bssid.  Cellular may use carrier spn.
    298          *
    299          * @param networkSpecifier An {@code String} of opaque format used to specify the bearer
    300          *                         specific network specifier where the bearer has a choice of
    301          *                         networks.
    302          */
    303         public Builder setNetworkSpecifier(String networkSpecifier) {
    304             /*
    305              * A StringNetworkSpecifier does not accept null or empty ("") strings. When network
    306              * specifiers were strings a null string and an empty string were considered equivalent.
    307              * Hence no meaning is attached to a null or empty ("") string.
    308              */
    309             return setNetworkSpecifier(TextUtils.isEmpty(networkSpecifier) ? null
    310                     : new StringNetworkSpecifier(networkSpecifier));
    311         }
    312 
    313         /**
    314          * Sets the optional bearer specific network specifier.
    315          * This has no meaning if a single transport is also not specified, so calling
    316          * this without a single transport set will generate an exception, as will
    317          * subsequently adding or removing transports after this is set.
    318          * </p>
    319          *
    320          * @param networkSpecifier A concrete, parcelable framework class that extends
    321          *                         NetworkSpecifier.
    322          */
    323         public Builder setNetworkSpecifier(NetworkSpecifier networkSpecifier) {
    324             MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(networkSpecifier);
    325             mNetworkCapabilities.setNetworkSpecifier(networkSpecifier);
    326             return this;
    327         }
    328 
    329         /**
    330          * Sets the signal strength. This is a signed integer, with higher values indicating a
    331          * stronger signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same
    332          * RSSI units reported by WifiManager.
    333          * <p>
    334          * Note that when used to register a network callback, this specifies the minimum acceptable
    335          * signal strength. When received as the state of an existing network it specifies the
    336          * current value. A value of {@code SIGNAL_STRENGTH_UNSPECIFIED} means no value when
    337          * received and has no effect when requesting a callback.
    338          *
    339          * @param signalStrength the bearer-specific signal strength.
    340          * @hide
    341          */
    342         public Builder setSignalStrength(int signalStrength) {
    343             mNetworkCapabilities.setSignalStrength(signalStrength);
    344             return this;
    345         }
    346     }
    347 
    348     // implement the Parcelable interface
    349     public int describeContents() {
    350         return 0;
    351     }
    352     public void writeToParcel(Parcel dest, int flags) {
    353         networkCapabilities.writeToParcel(dest, flags);
    354         dest.writeInt(legacyType);
    355         dest.writeInt(requestId);
    356         dest.writeString(type.name());
    357     }
    358     public static final Creator<NetworkRequest> CREATOR =
    359         new Creator<NetworkRequest>() {
    360             public NetworkRequest createFromParcel(Parcel in) {
    361                 NetworkCapabilities nc = NetworkCapabilities.CREATOR.createFromParcel(in);
    362                 int legacyType = in.readInt();
    363                 int requestId = in.readInt();
    364                 Type type = Type.valueOf(in.readString());  // IllegalArgumentException if invalid.
    365                 NetworkRequest result = new NetworkRequest(nc, legacyType, requestId, type);
    366                 return result;
    367             }
    368             public NetworkRequest[] newArray(int size) {
    369                 return new NetworkRequest[size];
    370             }
    371         };
    372 
    373     /**
    374      * Returns true iff. this NetworkRequest is of type LISTEN.
    375      *
    376      * @hide
    377      */
    378     public boolean isListen() {
    379         return type == Type.LISTEN;
    380     }
    381 
    382     /**
    383      * Returns true iff. the contained NetworkRequest is one that:
    384      *
    385      *     - should be associated with at most one satisfying network
    386      *       at a time;
    387      *
    388      *     - should cause a network to be kept up, but not necessarily in
    389      *       the foreground, if it is the best network which can satisfy the
    390      *       NetworkRequest.
    391      *
    392      * For full detail of how isRequest() is used for pairing Networks with
    393      * NetworkRequests read rematchNetworkAndRequests().
    394      *
    395      * @hide
    396      */
    397     public boolean isRequest() {
    398         return isForegroundRequest() || isBackgroundRequest();
    399     }
    400 
    401     /**
    402      * Returns true iff. the contained NetworkRequest is one that:
    403      *
    404      *     - should be associated with at most one satisfying network
    405      *       at a time;
    406      *
    407      *     - should cause a network to be kept up and in the foreground if
    408      *       it is the best network which can satisfy the NetworkRequest.
    409      *
    410      * For full detail of how isRequest() is used for pairing Networks with
    411      * NetworkRequests read rematchNetworkAndRequests().
    412      *
    413      * @hide
    414      */
    415     public boolean isForegroundRequest() {
    416         return type == Type.TRACK_DEFAULT || type == Type.REQUEST;
    417     }
    418 
    419     /**
    420      * Returns true iff. this NetworkRequest is of type BACKGROUND_REQUEST.
    421      *
    422      * @hide
    423      */
    424     public boolean isBackgroundRequest() {
    425         return type == Type.BACKGROUND_REQUEST;
    426     }
    427 
    428     /**
    429      * @see Builder#addCapability(int)
    430      */
    431     public boolean hasCapability(@NetCapability int capability) {
    432         return networkCapabilities.hasCapability(capability);
    433     }
    434 
    435     /**
    436      * @see Builder#addUnwantedCapability(int)
    437      *
    438      * @hide
    439      */
    440     public boolean hasUnwantedCapability(@NetCapability int capability) {
    441         return networkCapabilities.hasUnwantedCapability(capability);
    442     }
    443 
    444     /**
    445      * @see Builder#addTransportType(int)
    446      */
    447     public boolean hasTransport(@Transport int transportType) {
    448         return networkCapabilities.hasTransport(transportType);
    449     }
    450 
    451     public String toString() {
    452         return "NetworkRequest [ " + type + " id=" + requestId +
    453                 (legacyType != ConnectivityManager.TYPE_NONE ? ", legacyType=" + legacyType : "") +
    454                 ", " + networkCapabilities.toString() + " ]";
    455     }
    456 
    457     private int typeToProtoEnum(Type t) {
    458         switch (t) {
    459             case NONE:
    460                 return NetworkRequestProto.TYPE_NONE;
    461             case LISTEN:
    462                 return NetworkRequestProto.TYPE_LISTEN;
    463             case TRACK_DEFAULT:
    464                 return NetworkRequestProto.TYPE_TRACK_DEFAULT;
    465             case REQUEST:
    466                 return NetworkRequestProto.TYPE_REQUEST;
    467             case BACKGROUND_REQUEST:
    468                 return NetworkRequestProto.TYPE_BACKGROUND_REQUEST;
    469             default:
    470                 return NetworkRequestProto.TYPE_UNKNOWN;
    471         }
    472     }
    473 
    474     /** @hide */
    475     public void writeToProto(ProtoOutputStream proto, long fieldId) {
    476         final long token = proto.start(fieldId);
    477 
    478         proto.write(NetworkRequestProto.TYPE, typeToProtoEnum(type));
    479         proto.write(NetworkRequestProto.REQUEST_ID, requestId);
    480         proto.write(NetworkRequestProto.LEGACY_TYPE, legacyType);
    481         networkCapabilities.writeToProto(proto, NetworkRequestProto.NETWORK_CAPABILITIES);
    482 
    483         proto.end(token);
    484     }
    485 
    486     public boolean equals(Object obj) {
    487         if (obj instanceof NetworkRequest == false) return false;
    488         NetworkRequest that = (NetworkRequest)obj;
    489         return (that.legacyType == this.legacyType &&
    490                 that.requestId == this.requestId &&
    491                 that.type == this.type &&
    492                 Objects.equals(that.networkCapabilities, this.networkCapabilities));
    493     }
    494 
    495     public int hashCode() {
    496         return Objects.hash(requestId, legacyType, networkCapabilities, type);
    497     }
    498 }
    499