• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 three 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.
68      *
69      *     - The value NONE is used only by applications. When an application
70      *       creates a NetworkRequest, it does not have a type; the type is set
71      *       by the system depending on the method used to file the request
72      *       (requestNetwork, registerNetworkCallback, etc.).
73      *
74      * @hide
75      */
76     public static enum Type {
77         NONE,
78         LISTEN,
79         TRACK_DEFAULT,
80         REQUEST
81     };
82 
83     /**
84      * The type of the request. This is only used by the system and is always NONE elsewhere.
85      *
86      * @hide
87      */
88     public final Type type;
89 
90     /**
91      * @hide
92      */
NetworkRequest(NetworkCapabilities nc, int legacyType, int rId, Type type)93     public NetworkRequest(NetworkCapabilities nc, int legacyType, int rId, Type type) {
94         if (nc == null) {
95             throw new NullPointerException();
96         }
97         requestId = rId;
98         networkCapabilities = nc;
99         this.legacyType = legacyType;
100         this.type = type;
101     }
102 
103     /**
104      * @hide
105      */
NetworkRequest(NetworkRequest that)106     public NetworkRequest(NetworkRequest that) {
107         networkCapabilities = new NetworkCapabilities(that.networkCapabilities);
108         requestId = that.requestId;
109         this.legacyType = that.legacyType;
110         this.type = that.type;
111     }
112 
113     /**
114      * Builder used to create {@link NetworkRequest} objects.  Specify the Network features
115      * needed in terms of {@link NetworkCapabilities} features
116      */
117     public static class Builder {
118         private final NetworkCapabilities mNetworkCapabilities = new NetworkCapabilities();
119 
120         /**
121          * Default constructor for Builder.
122          */
Builder()123         public Builder() {}
124 
125         /**
126          * Build {@link NetworkRequest} give the current set of capabilities.
127          */
build()128         public NetworkRequest build() {
129             // Make a copy of mNetworkCapabilities so we don't inadvertently remove NOT_RESTRICTED
130             // when later an unrestricted capability could be added to mNetworkCapabilities, in
131             // which case NOT_RESTRICTED should be returned to mNetworkCapabilities, which
132             // maybeMarkCapabilitiesRestricted() doesn't add back.
133             final NetworkCapabilities nc = new NetworkCapabilities(mNetworkCapabilities);
134             nc.maybeMarkCapabilitiesRestricted();
135             return new NetworkRequest(nc, ConnectivityManager.TYPE_NONE,
136                     ConnectivityManager.REQUEST_ID_UNSET, Type.NONE);
137         }
138 
139         /**
140          * Add the given capability requirement to this builder.  These represent
141          * the requested network's required capabilities.  Note that when searching
142          * for a network to satisfy a request, all capabilities requested must be
143          * satisfied.  See {@link NetworkCapabilities} for {@code NET_CAPABILITIY_*}
144          * definitions.
145          *
146          * @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to add.
147          * @return The builder to facilitate chaining
148          *         {@code builder.addCapability(...).addCapability();}.
149          */
addCapability(int capability)150         public Builder addCapability(int capability) {
151             mNetworkCapabilities.addCapability(capability);
152             return this;
153         }
154 
155         /**
156          * Removes (if found) the given capability from this builder instance.
157          *
158          * @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to remove.
159          * @return The builder to facilitate chaining.
160          */
removeCapability(int capability)161         public Builder removeCapability(int capability) {
162             mNetworkCapabilities.removeCapability(capability);
163             return this;
164         }
165 
166         /**
167          * Completely clears all the {@code NetworkCapabilities} from this builder instance,
168          * removing even the capabilities that are set by default when the object is constructed.
169          *
170          * @return The builder to facilitate chaining.
171          * @hide
172          */
clearCapabilities()173         public Builder clearCapabilities() {
174             mNetworkCapabilities.clearAll();
175             return this;
176         }
177 
178         /**
179          * Adds the given transport requirement to this builder.  These represent
180          * the set of allowed transports for the request.  Only networks using one
181          * of these transports will satisfy the request.  If no particular transports
182          * are required, none should be specified here.  See {@link NetworkCapabilities}
183          * for {@code TRANSPORT_*} definitions.
184          *
185          * @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to add.
186          * @return The builder to facilitate chaining.
187          */
addTransportType(int transportType)188         public Builder addTransportType(int transportType) {
189             mNetworkCapabilities.addTransportType(transportType);
190             return this;
191         }
192 
193         /**
194          * Removes (if found) the given transport from this builder instance.
195          *
196          * @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to remove.
197          * @return The builder to facilitate chaining.
198          */
removeTransportType(int transportType)199         public Builder removeTransportType(int transportType) {
200             mNetworkCapabilities.removeTransportType(transportType);
201             return this;
202         }
203 
204         /**
205          * @hide
206          */
setLinkUpstreamBandwidthKbps(int upKbps)207         public Builder setLinkUpstreamBandwidthKbps(int upKbps) {
208             mNetworkCapabilities.setLinkUpstreamBandwidthKbps(upKbps);
209             return this;
210         }
211         /**
212          * @hide
213          */
setLinkDownstreamBandwidthKbps(int downKbps)214         public Builder setLinkDownstreamBandwidthKbps(int downKbps) {
215             mNetworkCapabilities.setLinkDownstreamBandwidthKbps(downKbps);
216             return this;
217         }
218 
219         /**
220          * Sets the optional bearer specific network specifier.
221          * This has no meaning if a single transport is also not specified, so calling
222          * this without a single transport set will generate an exception, as will
223          * subsequently adding or removing transports after this is set.
224          * </p>
225          * The interpretation of this {@code String} is bearer specific and bearers that use
226          * it should document their particulars.  For example, Bluetooth may use some sort of
227          * device id while WiFi could used ssid and/or bssid.  Cellular may use carrier spn.
228          *
229          * @param networkSpecifier An {@code String} of opaque format used to specify the bearer
230          *                         specific network specifier where the bearer has a choice of
231          *                         networks.
232          */
setNetworkSpecifier(String networkSpecifier)233         public Builder setNetworkSpecifier(String networkSpecifier) {
234             if (NetworkCapabilities.MATCH_ALL_REQUESTS_NETWORK_SPECIFIER.equals(networkSpecifier)) {
235                 throw new IllegalArgumentException("Invalid network specifier - must not be '"
236                         + NetworkCapabilities.MATCH_ALL_REQUESTS_NETWORK_SPECIFIER + "'");
237             }
238             mNetworkCapabilities.setNetworkSpecifier(networkSpecifier);
239             return this;
240         }
241 
242         /**
243          * Sets the signal strength. This is a signed integer, with higher values indicating a
244          * stronger signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same
245          * RSSI units reported by WifiManager.
246          * <p>
247          * Note that when used to register a network callback, this specifies the minimum acceptable
248          * signal strength. When received as the state of an existing network it specifies the
249          * current value. A value of {@code SIGNAL_STRENGTH_UNSPECIFIED} means no value when
250          * received and has no effect when requesting a callback.
251          *
252          * @param signalStrength the bearer-specific signal strength.
253          * @hide
254          */
setSignalStrength(int signalStrength)255         public Builder setSignalStrength(int signalStrength) {
256             mNetworkCapabilities.setSignalStrength(signalStrength);
257             return this;
258         }
259     }
260 
261     // implement the Parcelable interface
describeContents()262     public int describeContents() {
263         return 0;
264     }
writeToParcel(Parcel dest, int flags)265     public void writeToParcel(Parcel dest, int flags) {
266         dest.writeParcelable(networkCapabilities, flags);
267         dest.writeInt(legacyType);
268         dest.writeInt(requestId);
269         dest.writeString(type.name());
270     }
271     public static final Creator<NetworkRequest> CREATOR =
272         new Creator<NetworkRequest>() {
273             public NetworkRequest createFromParcel(Parcel in) {
274                 NetworkCapabilities nc = (NetworkCapabilities)in.readParcelable(null);
275                 int legacyType = in.readInt();
276                 int requestId = in.readInt();
277                 Type type = Type.valueOf(in.readString());  // IllegalArgumentException if invalid.
278                 NetworkRequest result = new NetworkRequest(nc, legacyType, requestId, type);
279                 return result;
280             }
281             public NetworkRequest[] newArray(int size) {
282                 return new NetworkRequest[size];
283             }
284         };
285 
286     /**
287      * Returns true iff. the contained NetworkRequest is of type LISTEN.
288      *
289      * @hide
290      */
isListen()291     public boolean isListen() {
292         return type == Type.LISTEN;
293     }
294 
295     /**
296      * Returns true iff. the contained NetworkRequest is one that:
297      *
298      *     - should be associated with at most one satisfying network
299      *       at a time;
300      *
301      *     - should cause a network to be kept up if it is the best network
302      *       which can satisfy the NetworkRequest.
303      *
304      * For full detail of how isRequest() is used for pairing Networks with
305      * NetworkRequests read rematchNetworkAndRequests().
306      *
307      * @hide
308      */
isRequest()309     public boolean isRequest() {
310         return type == Type.TRACK_DEFAULT || type == Type.REQUEST;
311     }
312 
toString()313     public String toString() {
314         return "NetworkRequest [ " + type + " id=" + requestId +
315                 (legacyType != ConnectivityManager.TYPE_NONE ? ", legacyType=" + legacyType : "") +
316                 ", " + networkCapabilities.toString() + " ]";
317     }
318 
equals(Object obj)319     public boolean equals(Object obj) {
320         if (obj instanceof NetworkRequest == false) return false;
321         NetworkRequest that = (NetworkRequest)obj;
322         return (that.legacyType == this.legacyType &&
323                 that.requestId == this.requestId &&
324                 that.type == this.type &&
325                 Objects.equals(that.networkCapabilities, this.networkCapabilities));
326     }
327 
hashCode()328     public int hashCode() {
329         return Objects.hash(requestId, legacyType, networkCapabilities, type);
330     }
331 }
332