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 /**
23  * Defines a request for a network, made through {@link NetworkRequest.Builder} and used
24  * to request a network via {@link ConnectivityManager#requestNetwork} or listen for changes
25  * via {@link ConnectivityManager#registerNetworkCallback}.
26  */
27 public class NetworkRequest implements Parcelable {
28     /**
29      * The {@link NetworkCapabilities} that define this request.
30      * @hide
31      */
32     public final NetworkCapabilities networkCapabilities;
33 
34     /**
35      * Identifies the request.  NetworkRequests should only be constructed by
36      * the Framework and given out to applications as tokens to be used to identify
37      * the request.
38      * @hide
39      */
40     public final int requestId;
41 
42     /**
43      * Set for legacy requests and the default.  Set to TYPE_NONE for none.
44      * Causes CONNECTIVITY_ACTION broadcasts to be sent.
45      * @hide
46      */
47     public final int legacyType;
48 
49     /**
50      * @hide
51      */
NetworkRequest(NetworkCapabilities nc, int legacyType, int rId)52     public NetworkRequest(NetworkCapabilities nc, int legacyType, int rId) {
53         if (nc == null) {
54             throw new NullPointerException();
55         }
56         requestId = rId;
57         networkCapabilities = nc;
58         this.legacyType = legacyType;
59     }
60 
61     /**
62      * @hide
63      */
NetworkRequest(NetworkRequest that)64     public NetworkRequest(NetworkRequest that) {
65         networkCapabilities = new NetworkCapabilities(that.networkCapabilities);
66         requestId = that.requestId;
67         this.legacyType = that.legacyType;
68     }
69 
70     /**
71      * Builder used to create {@link NetworkRequest} objects.  Specify the Network features
72      * needed in terms of {@link NetworkCapabilities} features
73      */
74     public static class Builder {
75         private final NetworkCapabilities mNetworkCapabilities = new NetworkCapabilities();
76 
77         /**
78          * Default constructor for Builder.
79          */
Builder()80         public Builder() {}
81 
82         /**
83          * Build {@link NetworkRequest} give the current set of capabilities.
84          */
build()85         public NetworkRequest build() {
86             // Make a copy of mNetworkCapabilities so we don't inadvertently remove NOT_RESTRICTED
87             // when later an unrestricted capability could be added to mNetworkCapabilities, in
88             // which case NOT_RESTRICTED should be returned to mNetworkCapabilities, which
89             // maybeMarkCapabilitiesRestricted() doesn't add back.
90             final NetworkCapabilities nc = new NetworkCapabilities(mNetworkCapabilities);
91             nc.maybeMarkCapabilitiesRestricted();
92             return new NetworkRequest(nc, ConnectivityManager.TYPE_NONE,
93                     ConnectivityManager.REQUEST_ID_UNSET);
94         }
95 
96         /**
97          * Add the given capability requirement to this builder.  These represent
98          * the requested network's required capabilities.  Note that when searching
99          * for a network to satisfy a request, all capabilities requested must be
100          * satisfied.  See {@link NetworkCapabilities} for {@code NET_CAPABILITIY_*}
101          * definitions.
102          *
103          * @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to add.
104          * @return The builder to facilitate chaining
105          *         {@code builder.addCapability(...).addCapability();}.
106          */
addCapability(int capability)107         public Builder addCapability(int capability) {
108             mNetworkCapabilities.addCapability(capability);
109             return this;
110         }
111 
112         /**
113          * Removes (if found) the given capability from this builder instance.
114          *
115          * @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to remove.
116          * @return The builder to facilitate chaining.
117          */
removeCapability(int capability)118         public Builder removeCapability(int capability) {
119             mNetworkCapabilities.removeCapability(capability);
120             return this;
121         }
122 
123         /**
124          * Completely clears all the {@code NetworkCapabilities} from this builder instance,
125          * removing even the capabilities that are set by default when the object is constructed.
126          *
127          * @return The builder to facilitate chaining.
128          * @hide
129          */
clearCapabilities()130         public Builder clearCapabilities() {
131             mNetworkCapabilities.clearAll();
132             return this;
133         }
134 
135         /**
136          * Adds the given transport requirement to this builder.  These represent
137          * the set of allowed transports for the request.  Only networks using one
138          * of these transports will satisfy the request.  If no particular transports
139          * are required, none should be specified here.  See {@link NetworkCapabilities}
140          * for {@code TRANSPORT_*} definitions.
141          *
142          * @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to add.
143          * @return The builder to facilitate chaining.
144          */
addTransportType(int transportType)145         public Builder addTransportType(int transportType) {
146             mNetworkCapabilities.addTransportType(transportType);
147             return this;
148         }
149 
150         /**
151          * Removes (if found) the given transport from this builder instance.
152          *
153          * @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to remove.
154          * @return The builder to facilitate chaining.
155          */
removeTransportType(int transportType)156         public Builder removeTransportType(int transportType) {
157             mNetworkCapabilities.removeTransportType(transportType);
158             return this;
159         }
160 
161         /**
162          * @hide
163          */
setLinkUpstreamBandwidthKbps(int upKbps)164         public Builder setLinkUpstreamBandwidthKbps(int upKbps) {
165             mNetworkCapabilities.setLinkUpstreamBandwidthKbps(upKbps);
166             return this;
167         }
168         /**
169          * @hide
170          */
setLinkDownstreamBandwidthKbps(int downKbps)171         public Builder setLinkDownstreamBandwidthKbps(int downKbps) {
172             mNetworkCapabilities.setLinkDownstreamBandwidthKbps(downKbps);
173             return this;
174         }
175 
176         /**
177          * Sets the optional bearer specific network specifier.
178          * This has no meaning if a single transport is also not specified, so calling
179          * this without a single transport set will generate an exception, as will
180          * subsequently adding or removing transports after this is set.
181          * </p>
182          * The interpretation of this {@code String} is bearer specific and bearers that use
183          * it should document their particulars.  For example, Bluetooth may use some sort of
184          * device id while WiFi could used ssid and/or bssid.  Cellular may use carrier spn.
185          *
186          * @param networkSpecifier An {@code String} of opaque format used to specify the bearer
187          *                         specific network specifier where the bearer has a choice of
188          *                         networks.
189          */
setNetworkSpecifier(String networkSpecifier)190         public Builder setNetworkSpecifier(String networkSpecifier) {
191             if (NetworkCapabilities.MATCH_ALL_REQUESTS_NETWORK_SPECIFIER.equals(networkSpecifier)) {
192                 throw new IllegalArgumentException("Invalid network specifier - must not be '"
193                         + NetworkCapabilities.MATCH_ALL_REQUESTS_NETWORK_SPECIFIER + "'");
194             }
195             mNetworkCapabilities.setNetworkSpecifier(networkSpecifier);
196             return this;
197         }
198 
199         /**
200          * Sets the signal strength. This is a signed integer, with higher values indicating a
201          * stronger signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same
202          * RSSI units reported by WifiManager.
203          * <p>
204          * Note that when used to register a network callback, this specifies the minimum acceptable
205          * signal strength. When received as the state of an existing network it specifies the
206          * current value. A value of {@code SIGNAL_STRENGTH_UNSPECIFIED} means no value when
207          * received and has no effect when requesting a callback.
208          *
209          * @param signalStrength the bearer-specific signal strength.
210          * @hide
211          */
setSignalStrength(int signalStrength)212         public Builder setSignalStrength(int signalStrength) {
213             mNetworkCapabilities.setSignalStrength(signalStrength);
214             return this;
215         }
216     }
217 
218     // implement the Parcelable interface
describeContents()219     public int describeContents() {
220         return 0;
221     }
writeToParcel(Parcel dest, int flags)222     public void writeToParcel(Parcel dest, int flags) {
223         dest.writeParcelable(networkCapabilities, flags);
224         dest.writeInt(legacyType);
225         dest.writeInt(requestId);
226     }
227     public static final Creator<NetworkRequest> CREATOR =
228         new Creator<NetworkRequest>() {
229             public NetworkRequest createFromParcel(Parcel in) {
230                 NetworkCapabilities nc = (NetworkCapabilities)in.readParcelable(null);
231                 int legacyType = in.readInt();
232                 int requestId = in.readInt();
233                 NetworkRequest result = new NetworkRequest(nc, legacyType, requestId);
234                 return result;
235             }
236             public NetworkRequest[] newArray(int size) {
237                 return new NetworkRequest[size];
238             }
239         };
240 
toString()241     public String toString() {
242         return "NetworkRequest [ id=" + requestId + ", legacyType=" + legacyType +
243                 ", " + networkCapabilities.toString() + " ]";
244     }
245 
equals(Object obj)246     public boolean equals(Object obj) {
247         if (obj instanceof NetworkRequest == false) return false;
248         NetworkRequest that = (NetworkRequest)obj;
249         return (that.legacyType == this.legacyType &&
250                 that.requestId == this.requestId &&
251                 ((that.networkCapabilities == null && this.networkCapabilities == null) ||
252                  (that.networkCapabilities != null &&
253                   that.networkCapabilities.equals(this.networkCapabilities))));
254     }
255 
hashCode()256     public int hashCode() {
257         return requestId + (legacyType * 1013) +
258                 (networkCapabilities.hashCode() * 1051);
259     }
260 }
261