blob: 35274f1e7e9c47c2864e3821163f39d9e6d7e04f [file] [log] [blame]
Robert Greenwalt1448f052014-04-08 13:41:39 -07001/*
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
17package android.net;
18
19import android.os.Parcel;
20import android.os.Parcelable;
21import android.util.Log;
22
23import java.lang.IllegalArgumentException;
24import java.util.ArrayList;
25import java.util.Collection;
26import java.util.HashMap;
27import java.util.Iterator;
28import java.util.Map;
29import java.util.Map.Entry;
30import java.util.Set;
31
32/**
Robert Greenwalt01d004e2014-05-18 15:24:21 -070033 * This class represents the capabilities of a network. This is used both to specify
34 * needs to {@link ConnectivityManager} and when inspecting a network.
35 *
36 * Note that this replaces the old {@link ConnectivityManager#TYPE_MOBILE} method
37 * of network selection. Rather than indicate a need for Wi-Fi because an application
38 * needs high bandwidth and risk obselence when a new, fast network appears (like LTE),
39 * the application should specify it needs high bandwidth. Similarly if an application
40 * needs an unmetered network for a bulk transfer it can specify that rather than assuming
41 * all cellular based connections are metered and all Wi-Fi based connections are not.
Robert Greenwalt1448f052014-04-08 13:41:39 -070042 */
43public final class NetworkCapabilities implements Parcelable {
44 private static final String TAG = "NetworkCapabilities";
45 private static final boolean DBG = false;
46
Robert Greenwalt01d004e2014-05-18 15:24:21 -070047 public NetworkCapabilities() {
48 }
49
50 public NetworkCapabilities(NetworkCapabilities nc) {
51 if (nc != null) {
52 mNetworkCapabilities = nc.mNetworkCapabilities;
53 mTransportTypes = nc.mTransportTypes;
54 mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps;
55 mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
56 }
57 }
Robert Greenwalt1448f052014-04-08 13:41:39 -070058
59 /**
60 * Represents the network's capabilities. If any are specified they will be satisfied
61 * by any Network that matches all of them.
62 */
63 private long mNetworkCapabilities = (1 << NET_CAPABILITY_NOT_RESTRICTED);
64
65 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -070066 * Indicates this is a network that has the ability to reach the
67 * carrier's MMSC for sending and receiving MMS messages.
Robert Greenwalt1448f052014-04-08 13:41:39 -070068 */
69 public static final int NET_CAPABILITY_MMS = 0;
Robert Greenwalt01d004e2014-05-18 15:24:21 -070070
71 /**
72 * Indicates this is a network that has the ability to reach the carrier's
73 * SUPL server, used to retrieve GPS information.
74 */
Robert Greenwalt1448f052014-04-08 13:41:39 -070075 public static final int NET_CAPABILITY_SUPL = 1;
Robert Greenwalt01d004e2014-05-18 15:24:21 -070076
77 /**
78 * Indicates this is a network that has the ability to reach the carrier's
79 * DUN or tethering gateway.
80 */
Robert Greenwalt1448f052014-04-08 13:41:39 -070081 public static final int NET_CAPABILITY_DUN = 2;
Robert Greenwalt01d004e2014-05-18 15:24:21 -070082
83 /**
84 * Indicates this is a network that has the ability to reach the carrier's
85 * FOTA portal, used for over the air updates.
86 */
Robert Greenwalt1448f052014-04-08 13:41:39 -070087 public static final int NET_CAPABILITY_FOTA = 3;
Robert Greenwalt01d004e2014-05-18 15:24:21 -070088
89 /**
90 * Indicates this is a network that has the ability to reach the carrier's
91 * IMS servers, used for network registration and signaling.
92 */
Robert Greenwalt1448f052014-04-08 13:41:39 -070093 public static final int NET_CAPABILITY_IMS = 4;
Robert Greenwalt01d004e2014-05-18 15:24:21 -070094
95 /**
96 * Indicates this is a network that has the ability to reach the carrier's
97 * CBS servers, used for carrier specific services.
98 */
Robert Greenwalt1448f052014-04-08 13:41:39 -070099 public static final int NET_CAPABILITY_CBS = 5;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700100
101 /**
102 * Indicates this is a network that has the ability to reach a Wi-Fi direct
103 * peer.
104 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700105 public static final int NET_CAPABILITY_WIFI_P2P = 6;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700106
107 /**
108 * Indicates this is a network that has the ability to reach a carrier's
109 * Initial Attach servers.
110 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700111 public static final int NET_CAPABILITY_IA = 7;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700112
113 /**
114 * Indicates this is a network that has the ability to reach a carrier's
115 * RCS servers, used for Rich Communication Services.
116 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700117 public static final int NET_CAPABILITY_RCS = 8;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700118
119 /**
120 * Indicates this is a network that has the ability to reach a carrier's
121 * XCAP servers, used for configuration and control.
122 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700123 public static final int NET_CAPABILITY_XCAP = 9;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700124
125 /**
126 * Indicates this is a network that has the ability to reach a carrier's
127 * Emergency IMS servers, used for network signaling during emergency calls.
128 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700129 public static final int NET_CAPABILITY_EIMS = 10;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700130
131 /**
132 * Indicates that this network is unmetered.
133 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700134 public static final int NET_CAPABILITY_NOT_METERED = 11;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700135
136 /**
137 * Indicates that this network should be able to reach the internet.
138 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700139 public static final int NET_CAPABILITY_INTERNET = 12;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700140
141 /**
142 * Indicates that this network is available for general use. If this is not set
143 * applications should not attempt to communicate on this network. Note that this
144 * is simply informative and not enforcement - enforcement is handled via other means.
145 * Set by default.
146 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700147 public static final int NET_CAPABILITY_NOT_RESTRICTED = 13;
148
149 private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
150 private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_NOT_RESTRICTED;
151
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700152 /**
153 * Adds the given capability to this {@code NetworkCapability} instance.
154 * Multiple capabilities may be applied sequentially. Note that when searching
155 * for a network to satisfy a request, all capabilities requested must be satisfied.
156 *
157 * @param networkCapability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be added.
158 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700159 public void addNetworkCapability(int networkCapability) {
160 if (networkCapability < MIN_NET_CAPABILITY ||
161 networkCapability > MAX_NET_CAPABILITY) {
162 throw new IllegalArgumentException("NetworkCapability out of range");
163 }
164 mNetworkCapabilities |= 1 << networkCapability;
165 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700166
167 /**
168 * Removes (if found) the given capability from this {@code NetworkCapability} instance.
169 *
170 * @param networkCapability the {@code NetworkCapabilities.NET_CAPABILTIY_*} to be removed.
171 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700172 public void removeNetworkCapability(int networkCapability) {
173 if (networkCapability < MIN_NET_CAPABILITY ||
174 networkCapability > MAX_NET_CAPABILITY) {
175 throw new IllegalArgumentException("NetworkCapability out of range");
176 }
177 mNetworkCapabilities &= ~(1 << networkCapability);
178 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700179
180 /**
181 * Gets all the capabilities set on this {@code NetworkCapability} instance.
182 *
183 * @return a {@link Collection} of {@code NetworkCapabilities.NET_CAPABILITY_*} values
184 * for this instance.
185 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700186 public Collection<Integer> getNetworkCapabilities() {
187 return enumerateBits(mNetworkCapabilities);
188 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700189
190 /**
191 * Tests for the presence of a capabilitity on this instance.
192 *
193 * @param networkCapability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be tested for.
194 * @return {@code true} if set on this instance.
195 */
Robert Greenwalt5c55e332014-05-08 00:02:04 -0700196 public boolean hasCapability(int networkCapability) {
197 if (networkCapability < MIN_NET_CAPABILITY ||
198 networkCapability > MAX_NET_CAPABILITY) {
199 return false;
200 }
201 return ((mNetworkCapabilities & (1 << networkCapability)) != 0);
202 }
Robert Greenwalt1448f052014-04-08 13:41:39 -0700203
204 private Collection<Integer> enumerateBits(long val) {
205 ArrayList<Integer> result = new ArrayList<Integer>();
206 int resource = 0;
207 while (val > 0) {
208 if ((val & 1) == 1) result.add(resource);
209 val = val >> 1;
210 resource++;
211 }
212 return result;
213 }
214
215 private void combineNetCapabilities(NetworkCapabilities nc) {
216 this.mNetworkCapabilities |= nc.mNetworkCapabilities;
217 }
218
219 private boolean satisfiedByNetCapabilities(NetworkCapabilities nc) {
220 return ((nc.mNetworkCapabilities & this.mNetworkCapabilities) == this.mNetworkCapabilities);
221 }
222
223 private boolean equalsNetCapabilities(NetworkCapabilities nc) {
224 return (nc.mNetworkCapabilities == this.mNetworkCapabilities);
225 }
226
227 /**
228 * Representing the transport type. Apps should generally not care about transport. A
229 * request for a fast internet connection could be satisfied by a number of different
230 * transports. If any are specified here it will be satisfied a Network that matches
231 * any of them. If a caller doesn't care about the transport it should not specify any.
232 */
233 private long mTransportTypes;
234
235 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700236 * Indicates this network uses a Cellular transport.
Robert Greenwalt1448f052014-04-08 13:41:39 -0700237 */
238 public static final int TRANSPORT_CELLULAR = 0;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700239
240 /**
241 * Indicates this network uses a Wi-Fi transport.
242 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700243 public static final int TRANSPORT_WIFI = 1;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700244
245 /**
246 * Indicates this network uses a Bluetooth transport.
247 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700248 public static final int TRANSPORT_BLUETOOTH = 2;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700249
250 /**
251 * Indicates this network uses an Ethernet transport.
252 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700253 public static final int TRANSPORT_ETHERNET = 3;
254
255 private static final int MIN_TRANSPORT = TRANSPORT_CELLULAR;
256 private static final int MAX_TRANSPORT = TRANSPORT_ETHERNET;
257
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700258 /**
259 * Adds the given transport type to this {@code NetworkCapability} instance.
260 * Multiple transports may be applied sequentially. Note that when searching
261 * for a network to satisfy a request, any listed in the request will satisfy the request.
262 * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a
263 * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network
264 * to be selected. This is logically different than
265 * {@code NetworkCapabilities.NET_CAPABILITY_*} listed above.
266 *
267 * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be added.
268 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700269 public void addTransportType(int transportType) {
270 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
271 throw new IllegalArgumentException("TransportType out of range");
272 }
273 mTransportTypes |= 1 << transportType;
274 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700275
276 /**
277 * Removes (if found) the given transport from this {@code NetworkCapability} instance.
278 *
279 * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be removed.
280 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700281 public void removeTransportType(int transportType) {
282 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
283 throw new IllegalArgumentException("TransportType out of range");
284 }
285 mTransportTypes &= ~(1 << transportType);
286 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700287
288 /**
289 * Gets all the transports set on this {@code NetworkCapability} instance.
290 *
291 * @return a {@link Collection} of {@code NetworkCapabilities.TRANSPORT_*} values
292 * for this instance.
293 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700294 public Collection<Integer> getTransportTypes() {
295 return enumerateBits(mTransportTypes);
296 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700297
298 /**
299 * Tests for the presence of a transport on this instance.
300 *
301 * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be tested for.
302 * @return {@code true} if set on this instance.
303 */
Robert Greenwalt5c55e332014-05-08 00:02:04 -0700304 public boolean hasTransport(int transportType) {
305 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
306 return false;
307 }
308 return ((mTransportTypes & (1 << transportType)) != 0);
309 }
Robert Greenwalt1448f052014-04-08 13:41:39 -0700310
311 private void combineTransportTypes(NetworkCapabilities nc) {
312 this.mTransportTypes |= nc.mTransportTypes;
313 }
314 private boolean satisfiedByTransportTypes(NetworkCapabilities nc) {
315 return ((this.mTransportTypes == 0) ||
316 ((this.mTransportTypes & nc.mTransportTypes) != 0));
317 }
318 private boolean equalsTransportTypes(NetworkCapabilities nc) {
319 return (nc.mTransportTypes == this.mTransportTypes);
320 }
321
322 /**
323 * Passive link bandwidth. This is a rough guide of the expected peak bandwidth
324 * for the first hop on the given transport. It is not measured, but may take into account
325 * link parameters (Radio technology, allocated channels, etc).
326 */
327 private int mLinkUpBandwidthKbps;
328 private int mLinkDownBandwidthKbps;
329
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700330 /**
331 * Sets the upstream bandwidth for this network in Kbps. This always only refers to
332 * the estimated first hop transport bandwidth.
333 * <p>
334 * Note that when used to request a network, this specifies the minimum acceptable.
335 * When received as the state of an existing network this specifies the typical
336 * first hop bandwidth expected. This is never measured, but rather is inferred
337 * from technology type and other link parameters. It could be used to differentiate
338 * between very slow 1xRTT cellular links and other faster networks or even between
339 * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
340 * fast backhauls and slow backhauls.
341 *
342 * @param upKbps the estimated first hop upstream (device to network) bandwidth.
343 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700344 public void setLinkUpstreamBandwidthKbps(int upKbps) {
345 mLinkUpBandwidthKbps = upKbps;
346 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700347
348 /**
349 * Retrieves the upstream bandwidth for this network in Kbps. This always only refers to
350 * the estimated first hop transport bandwidth.
351 *
352 * @return The estimated first hop upstream (device to network) bandwidth.
353 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700354 public int getLinkUpstreamBandwidthKbps() {
355 return mLinkUpBandwidthKbps;
356 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700357
358 /**
359 * Sets the downstream bandwidth for this network in Kbps. This always only refers to
360 * the estimated first hop transport bandwidth.
361 * <p>
362 * Note that when used to request a network, this specifies the minimum acceptable.
363 * When received as the state of an existing network this specifies the typical
364 * first hop bandwidth expected. This is never measured, but rather is inferred
365 * from technology type and other link parameters. It could be used to differentiate
366 * between very slow 1xRTT cellular links and other faster networks or even between
367 * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
368 * fast backhauls and slow backhauls.
369 *
370 * @param downKbps the estimated first hop downstream (network to device) bandwidth.
371 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700372 public void setLinkDownstreamBandwidthKbps(int downKbps) {
373 mLinkDownBandwidthKbps = downKbps;
374 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700375
376 /**
377 * Retrieves the downstream bandwidth for this network in Kbps. This always only refers to
378 * the estimated first hop transport bandwidth.
379 *
380 * @return The estimated first hop downstream (network to device) bandwidth.
381 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700382 public int getLinkDownstreamBandwidthKbps() {
383 return mLinkDownBandwidthKbps;
384 }
385
386 private void combineLinkBandwidths(NetworkCapabilities nc) {
387 this.mLinkUpBandwidthKbps =
388 Math.max(this.mLinkUpBandwidthKbps, nc.mLinkUpBandwidthKbps);
389 this.mLinkDownBandwidthKbps =
390 Math.max(this.mLinkDownBandwidthKbps, nc.mLinkDownBandwidthKbps);
391 }
392 private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) {
393 return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps ||
394 this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps);
395 }
396 private boolean equalsLinkBandwidths(NetworkCapabilities nc) {
397 return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps &&
398 this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
399 }
400
401 /**
402 * Combine a set of Capabilities to this one. Useful for coming up with the complete set
403 * {@hide}
404 */
405 public void combineCapabilities(NetworkCapabilities nc) {
406 combineNetCapabilities(nc);
407 combineTransportTypes(nc);
408 combineLinkBandwidths(nc);
409 }
410
411 /**
412 * Check if our requirements are satisfied by the given Capabilities.
413 * {@hide}
414 */
415 public boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc) {
Robert Greenwalt5c55e332014-05-08 00:02:04 -0700416 return (nc != null &&
417 satisfiedByNetCapabilities(nc) &&
Robert Greenwalt1448f052014-04-08 13:41:39 -0700418 satisfiedByTransportTypes(nc) &&
419 satisfiedByLinkBandwidths(nc));
420 }
421
422 @Override
423 public boolean equals(Object obj) {
424 if (obj == null || (obj instanceof NetworkCapabilities == false)) return false;
425 NetworkCapabilities that = (NetworkCapabilities)obj;
426 return (equalsNetCapabilities(that) &&
427 equalsTransportTypes(that) &&
428 equalsLinkBandwidths(that));
429 }
430
431 @Override
432 public int hashCode() {
433 return ((int)(mNetworkCapabilities & 0xFFFFFFFF) +
434 ((int)(mNetworkCapabilities >> 32) * 3) +
435 ((int)(mTransportTypes & 0xFFFFFFFF) * 5) +
436 ((int)(mTransportTypes >> 32) * 7) +
437 (mLinkUpBandwidthKbps * 11) +
438 (mLinkDownBandwidthKbps * 13));
439 }
440
Robert Greenwalt1448f052014-04-08 13:41:39 -0700441 public int describeContents() {
442 return 0;
443 }
444 public void writeToParcel(Parcel dest, int flags) {
445 dest.writeLong(mNetworkCapabilities);
446 dest.writeLong(mTransportTypes);
447 dest.writeInt(mLinkUpBandwidthKbps);
448 dest.writeInt(mLinkDownBandwidthKbps);
449 }
450 public static final Creator<NetworkCapabilities> CREATOR =
451 new Creator<NetworkCapabilities>() {
452 public NetworkCapabilities createFromParcel(Parcel in) {
453 NetworkCapabilities netCap = new NetworkCapabilities();
454
455 netCap.mNetworkCapabilities = in.readLong();
456 netCap.mTransportTypes = in.readLong();
457 netCap.mLinkUpBandwidthKbps = in.readInt();
458 netCap.mLinkDownBandwidthKbps = in.readInt();
459 return netCap;
460 }
461 public NetworkCapabilities[] newArray(int size) {
462 return new NetworkCapabilities[size];
463 }
464 };
465
466 public String toString() {
467 Collection<Integer> types = getTransportTypes();
468 String transports = (types.size() > 0 ? " Transports: " : "");
469 Iterator<Integer> i = types.iterator();
470 while (i.hasNext()) {
471 switch (i.next()) {
472 case TRANSPORT_CELLULAR: transports += "CELLULAR"; break;
473 case TRANSPORT_WIFI: transports += "WIFI"; break;
474 case TRANSPORT_BLUETOOTH: transports += "BLUETOOTH"; break;
475 case TRANSPORT_ETHERNET: transports += "ETHERNET"; break;
476 }
477 if (i.hasNext()) transports += "|";
478 }
479
480 types = getNetworkCapabilities();
481 String capabilities = (types.size() > 0 ? " Capabilities: " : "");
482 i = types.iterator();
483 while (i.hasNext()) {
484 switch (i.next().intValue()) {
485 case NET_CAPABILITY_MMS: capabilities += "MMS"; break;
486 case NET_CAPABILITY_SUPL: capabilities += "SUPL"; break;
487 case NET_CAPABILITY_DUN: capabilities += "DUN"; break;
488 case NET_CAPABILITY_FOTA: capabilities += "FOTA"; break;
489 case NET_CAPABILITY_IMS: capabilities += "IMS"; break;
490 case NET_CAPABILITY_CBS: capabilities += "CBS"; break;
491 case NET_CAPABILITY_WIFI_P2P: capabilities += "WIFI_P2P"; break;
492 case NET_CAPABILITY_IA: capabilities += "IA"; break;
493 case NET_CAPABILITY_RCS: capabilities += "RCS"; break;
494 case NET_CAPABILITY_XCAP: capabilities += "XCAP"; break;
495 case NET_CAPABILITY_EIMS: capabilities += "EIMS"; break;
496 case NET_CAPABILITY_NOT_METERED: capabilities += "NOT_METERED"; break;
497 case NET_CAPABILITY_INTERNET: capabilities += "INTERNET"; break;
498 case NET_CAPABILITY_NOT_RESTRICTED: capabilities += "NOT_RESTRICTED"; break;
499 }
500 if (i.hasNext()) capabilities += "&";
501 }
502
503 String upBand = ((mLinkUpBandwidthKbps > 0) ? " LinkUpBandwidth>=" +
504 mLinkUpBandwidthKbps + "Kbps" : "");
505 String dnBand = ((mLinkDownBandwidthKbps > 0) ? " LinkDnBandwidth>=" +
506 mLinkDownBandwidthKbps + "Kbps" : "");
507
Robert Greenwaltc9c90c72014-05-13 15:36:27 -0700508 return "[" + transports + capabilities + upBand + dnBand + "]";
Robert Greenwalt1448f052014-04-08 13:41:39 -0700509 }
510}