blob: 2dd7f757aea37ee1369e92b4fdf075c464417ac7 [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;
Robert Greenwalta7e148a2017-04-10 14:32:23 -070021
22import com.android.internal.annotations.VisibleForTesting;
Hugo Benichi9910dbc2017-03-22 18:29:58 +090023import com.android.internal.util.BitUtils;
Etan Cohena7434272017-04-03 12:17:51 -070024
25import java.util.Objects;
Robert Greenwalt1448f052014-04-08 13:41:39 -070026
27/**
Robert Greenwalt01d004e2014-05-18 15:24:21 -070028 * This class represents the capabilities of a network. This is used both to specify
29 * needs to {@link ConnectivityManager} and when inspecting a network.
30 *
31 * Note that this replaces the old {@link ConnectivityManager#TYPE_MOBILE} method
32 * of network selection. Rather than indicate a need for Wi-Fi because an application
Wink Saville4e2dea72014-09-20 11:04:03 -070033 * needs high bandwidth and risk obsolescence when a new, fast network appears (like LTE),
Robert Greenwalt01d004e2014-05-18 15:24:21 -070034 * the application should specify it needs high bandwidth. Similarly if an application
35 * needs an unmetered network for a bulk transfer it can specify that rather than assuming
36 * all cellular based connections are metered and all Wi-Fi based connections are not.
Robert Greenwalt1448f052014-04-08 13:41:39 -070037 */
38public final class NetworkCapabilities implements Parcelable {
Etan Cohena7434272017-04-03 12:17:51 -070039 private static final String TAG = "NetworkCapabilities";
40
Robert Greenwalt7569f182014-06-08 16:42:59 -070041 /**
42 * @hide
43 */
Robert Greenwalt01d004e2014-05-18 15:24:21 -070044 public NetworkCapabilities() {
Lorenzo Colittif7058f52015-04-27 11:31:55 +090045 clearAll();
Lorenzo Colitti260a36d2015-07-08 12:49:04 +090046 mNetworkCapabilities = DEFAULT_CAPABILITIES;
Robert Greenwalt01d004e2014-05-18 15:24:21 -070047 }
48
49 public NetworkCapabilities(NetworkCapabilities nc) {
50 if (nc != null) {
51 mNetworkCapabilities = nc.mNetworkCapabilities;
52 mTransportTypes = nc.mTransportTypes;
53 mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps;
54 mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
Robert Greenwalt94badcc2014-07-10 14:53:24 -070055 mNetworkSpecifier = nc.mNetworkSpecifier;
Lorenzo Colittic3f21f32015-07-06 23:50:27 +090056 mSignalStrength = nc.mSignalStrength;
Robert Greenwalt01d004e2014-05-18 15:24:21 -070057 }
58 }
Robert Greenwalt1448f052014-04-08 13:41:39 -070059
60 /**
Lorenzo Colittif7058f52015-04-27 11:31:55 +090061 * Completely clears the contents of this object, removing even the capabilities that are set
62 * by default when the object is constructed.
63 * @hide
64 */
65 public void clearAll() {
66 mNetworkCapabilities = mTransportTypes = 0;
67 mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = 0;
68 mNetworkSpecifier = null;
Lorenzo Colittic3f21f32015-07-06 23:50:27 +090069 mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
Lorenzo Colittif7058f52015-04-27 11:31:55 +090070 }
71
72 /**
Robert Greenwalt1448f052014-04-08 13:41:39 -070073 * Represents the network's capabilities. If any are specified they will be satisfied
74 * by any Network that matches all of them.
75 */
Lorenzo Colittif7058f52015-04-27 11:31:55 +090076 private long mNetworkCapabilities;
Robert Greenwalt1448f052014-04-08 13:41:39 -070077
78 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -070079 * Indicates this is a network that has the ability to reach the
80 * carrier's MMSC for sending and receiving MMS messages.
Robert Greenwalt1448f052014-04-08 13:41:39 -070081 */
82 public static final int NET_CAPABILITY_MMS = 0;
Robert Greenwalt01d004e2014-05-18 15:24:21 -070083
84 /**
85 * Indicates this is a network that has the ability to reach the carrier's
86 * SUPL server, used to retrieve GPS information.
87 */
Robert Greenwalt1448f052014-04-08 13:41:39 -070088 public static final int NET_CAPABILITY_SUPL = 1;
Robert Greenwalt01d004e2014-05-18 15:24:21 -070089
90 /**
91 * Indicates this is a network that has the ability to reach the carrier's
92 * DUN or tethering gateway.
93 */
Robert Greenwalt1448f052014-04-08 13:41:39 -070094 public static final int NET_CAPABILITY_DUN = 2;
Robert Greenwalt01d004e2014-05-18 15:24:21 -070095
96 /**
97 * Indicates this is a network that has the ability to reach the carrier's
98 * FOTA portal, used for over the air updates.
99 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700100 public static final int NET_CAPABILITY_FOTA = 3;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700101
102 /**
103 * Indicates this is a network that has the ability to reach the carrier's
104 * IMS servers, used for network registration and signaling.
105 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700106 public static final int NET_CAPABILITY_IMS = 4;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700107
108 /**
109 * Indicates this is a network that has the ability to reach the carrier's
110 * CBS servers, used for carrier specific services.
111 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700112 public static final int NET_CAPABILITY_CBS = 5;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700113
114 /**
115 * Indicates this is a network that has the ability to reach a Wi-Fi direct
116 * peer.
117 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700118 public static final int NET_CAPABILITY_WIFI_P2P = 6;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700119
120 /**
121 * Indicates this is a network that has the ability to reach a carrier's
122 * Initial Attach servers.
123 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700124 public static final int NET_CAPABILITY_IA = 7;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700125
126 /**
127 * Indicates this is a network that has the ability to reach a carrier's
128 * RCS servers, used for Rich Communication Services.
129 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700130 public static final int NET_CAPABILITY_RCS = 8;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700131
132 /**
133 * Indicates this is a network that has the ability to reach a carrier's
134 * XCAP servers, used for configuration and control.
135 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700136 public static final int NET_CAPABILITY_XCAP = 9;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700137
138 /**
139 * Indicates this is a network that has the ability to reach a carrier's
Robert Greenwalt4bd43892015-07-09 14:49:35 -0700140 * Emergency IMS servers or other services, used for network signaling
141 * during emergency calls.
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700142 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700143 public static final int NET_CAPABILITY_EIMS = 10;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700144
145 /**
146 * Indicates that this network is unmetered.
147 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700148 public static final int NET_CAPABILITY_NOT_METERED = 11;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700149
150 /**
151 * Indicates that this network should be able to reach the internet.
152 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700153 public static final int NET_CAPABILITY_INTERNET = 12;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700154
155 /**
156 * Indicates that this network is available for general use. If this is not set
157 * applications should not attempt to communicate on this network. Note that this
158 * is simply informative and not enforcement - enforcement is handled via other means.
159 * Set by default.
160 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700161 public static final int NET_CAPABILITY_NOT_RESTRICTED = 13;
162
Robert Greenwalt16e12ab2014-07-08 15:31:37 -0700163 /**
164 * Indicates that the user has indicated implicit trust of this network. This
165 * generally means it's a sim-selected carrier, a plugged in ethernet, a paired
166 * BT device or a wifi the user asked to connect to. Untrusted networks
167 * are probably limited to unknown wifi AP. Set by default.
168 */
169 public static final int NET_CAPABILITY_TRUSTED = 14;
170
Paul Jensen76b610a2015-03-18 09:33:07 -0400171 /**
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400172 * Indicates that this network is not a VPN. This capability is set by default and should be
Paul Jensen76b610a2015-03-18 09:33:07 -0400173 * explicitly cleared for VPN networks.
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400174 */
175 public static final int NET_CAPABILITY_NOT_VPN = 15;
176
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900177 /**
178 * Indicates that connectivity on this network was successfully validated. For example, for a
179 * network with NET_CAPABILITY_INTERNET, it means that Internet connectivity was successfully
180 * detected.
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900181 */
182 public static final int NET_CAPABILITY_VALIDATED = 16;
Robert Greenwalt16e12ab2014-07-08 15:31:37 -0700183
Paul Jensen3d194ea2015-06-16 14:27:36 -0400184 /**
185 * Indicates that this network was found to have a captive portal in place last time it was
186 * probed.
187 */
188 public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17;
189
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900190 /**
191 * Indicates that this network is available for use by apps, and not a network that is being
192 * kept up in the background to facilitate fast network switching.
193 * @hide
194 */
195 public static final int NET_CAPABILITY_FOREGROUND = 18;
196
Robert Greenwalt1448f052014-04-08 13:41:39 -0700197 private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900198 private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_FOREGROUND;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700199
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700200 /**
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900201 * Network capabilities that are expected to be mutable, i.e., can change while a particular
202 * network is connected.
203 */
204 private static final long MUTABLE_CAPABILITIES =
205 // TRUSTED can change when user explicitly connects to an untrusted network in Settings.
206 // http://b/18206275
207 (1 << NET_CAPABILITY_TRUSTED) |
208 (1 << NET_CAPABILITY_VALIDATED) |
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900209 (1 << NET_CAPABILITY_CAPTIVE_PORTAL) |
210 (1 << NET_CAPABILITY_FOREGROUND);
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900211
212 /**
213 * Network capabilities that are not allowed in NetworkRequests. This exists because the
214 * NetworkFactory / NetworkAgent model does not deal well with the situation where a
215 * capability's presence cannot be known in advance. If such a capability is requested, then we
216 * can get into a cycle where the NetworkFactory endlessly churns out NetworkAgents that then
217 * get immediately torn down because they do not have the requested capability.
218 */
219 private static final long NON_REQUESTABLE_CAPABILITIES =
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900220 MUTABLE_CAPABILITIES & ~(1 << NET_CAPABILITY_TRUSTED);
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900221
222 /**
223 * Capabilities that are set by default when the object is constructed.
224 */
225 private static final long DEFAULT_CAPABILITIES =
226 (1 << NET_CAPABILITY_NOT_RESTRICTED) |
227 (1 << NET_CAPABILITY_TRUSTED) |
228 (1 << NET_CAPABILITY_NOT_VPN);
229
230 /**
Paul Jensen487ffe72015-07-24 15:57:11 -0400231 * Capabilities that suggest that a network is restricted.
232 * {@see #maybeMarkCapabilitiesRestricted}.
233 */
Robert Greenwalta7e148a2017-04-10 14:32:23 -0700234 @VisibleForTesting
235 /* package */ static final long RESTRICTED_CAPABILITIES =
Paul Jensen487ffe72015-07-24 15:57:11 -0400236 (1 << NET_CAPABILITY_CBS) |
237 (1 << NET_CAPABILITY_DUN) |
238 (1 << NET_CAPABILITY_EIMS) |
239 (1 << NET_CAPABILITY_FOTA) |
240 (1 << NET_CAPABILITY_IA) |
241 (1 << NET_CAPABILITY_IMS) |
242 (1 << NET_CAPABILITY_RCS) |
243 (1 << NET_CAPABILITY_XCAP);
244
245 /**
Robert Greenwalta7e148a2017-04-10 14:32:23 -0700246 * Capabilities that suggest that a network is unrestricted.
247 * {@see #maybeMarkCapabilitiesRestricted}.
248 */
249 @VisibleForTesting
250 /* package */ static final long UNRESTRICTED_CAPABILITIES =
251 (1 << NET_CAPABILITY_INTERNET) |
252 (1 << NET_CAPABILITY_MMS) |
253 (1 << NET_CAPABILITY_SUPL) |
254 (1 << NET_CAPABILITY_WIFI_P2P);
255
256 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700257 * Adds the given capability to this {@code NetworkCapability} instance.
258 * Multiple capabilities may be applied sequentially. Note that when searching
259 * for a network to satisfy a request, all capabilities requested must be satisfied.
260 *
Robert Greenwalt7569f182014-06-08 16:42:59 -0700261 * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be added.
Pierre Imaic8419a82016-03-22 17:54:54 +0900262 * @return This NetworkCapabilities instance, to facilitate chaining.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700263 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700264 */
Robert Greenwalt7569f182014-06-08 16:42:59 -0700265 public NetworkCapabilities addCapability(int capability) {
266 if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700267 throw new IllegalArgumentException("NetworkCapability out of range");
268 }
Robert Greenwalt7569f182014-06-08 16:42:59 -0700269 mNetworkCapabilities |= 1 << capability;
270 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700271 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700272
273 /**
274 * Removes (if found) the given capability from this {@code NetworkCapability} instance.
275 *
Robert Greenwalt7569f182014-06-08 16:42:59 -0700276 * @param capability the {@code NetworkCapabilities.NET_CAPABILTIY_*} to be removed.
Pierre Imaic8419a82016-03-22 17:54:54 +0900277 * @return This NetworkCapabilities instance, to facilitate chaining.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700278 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700279 */
Robert Greenwalt7569f182014-06-08 16:42:59 -0700280 public NetworkCapabilities removeCapability(int capability) {
281 if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700282 throw new IllegalArgumentException("NetworkCapability out of range");
283 }
Robert Greenwalt7569f182014-06-08 16:42:59 -0700284 mNetworkCapabilities &= ~(1 << capability);
285 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700286 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700287
288 /**
289 * Gets all the capabilities set on this {@code NetworkCapability} instance.
290 *
Robert Greenwalt7569f182014-06-08 16:42:59 -0700291 * @return an array of {@code NetworkCapabilities.NET_CAPABILITY_*} values
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700292 * for this instance.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700293 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700294 */
Robert Greenwalt7569f182014-06-08 16:42:59 -0700295 public int[] getCapabilities() {
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900296 return BitUtils.unpackBits(mNetworkCapabilities);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700297 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700298
299 /**
300 * Tests for the presence of a capabilitity on this instance.
301 *
Robert Greenwalt7569f182014-06-08 16:42:59 -0700302 * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be tested for.
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700303 * @return {@code true} if set on this instance.
304 */
Robert Greenwalt7569f182014-06-08 16:42:59 -0700305 public boolean hasCapability(int capability) {
306 if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
Robert Greenwalt5c55e332014-05-08 00:02:04 -0700307 return false;
308 }
Robert Greenwalt7569f182014-06-08 16:42:59 -0700309 return ((mNetworkCapabilities & (1 << capability)) != 0);
Robert Greenwalt5c55e332014-05-08 00:02:04 -0700310 }
Robert Greenwalt1448f052014-04-08 13:41:39 -0700311
Robert Greenwalt1448f052014-04-08 13:41:39 -0700312 private void combineNetCapabilities(NetworkCapabilities nc) {
313 this.mNetworkCapabilities |= nc.mNetworkCapabilities;
314 }
315
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900316 /**
317 * Convenience function that returns a human-readable description of the first mutable
318 * capability we find. Used to present an error message to apps that request mutable
319 * capabilities.
320 *
321 * @hide
322 */
323 public String describeFirstNonRequestableCapability() {
324 if (hasCapability(NET_CAPABILITY_VALIDATED)) return "NET_CAPABILITY_VALIDATED";
325 if (hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return "NET_CAPABILITY_CAPTIVE_PORTAL";
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900326 if (hasCapability(NET_CAPABILITY_FOREGROUND)) return "NET_CAPABILITY_FOREGROUND";
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900327 // This cannot happen unless the preceding checks are incomplete.
328 if ((mNetworkCapabilities & NON_REQUESTABLE_CAPABILITIES) != 0) {
329 return "unknown non-requestable capabilities " + Long.toHexString(mNetworkCapabilities);
330 }
331 if (mLinkUpBandwidthKbps != 0 || mLinkDownBandwidthKbps != 0) return "link bandwidth";
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900332 if (hasSignalStrength()) return "signalStrength";
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900333 return null;
334 }
335
336 private boolean satisfiedByNetCapabilities(NetworkCapabilities nc, boolean onlyImmutable) {
337 long networkCapabilities = this.mNetworkCapabilities;
338 if (onlyImmutable) {
339 networkCapabilities = networkCapabilities & ~MUTABLE_CAPABILITIES;
340 }
341 return ((nc.mNetworkCapabilities & networkCapabilities) == networkCapabilities);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700342 }
343
Robert Greenwalt06314e42014-10-29 14:04:06 -0700344 /** @hide */
345 public boolean equalsNetCapabilities(NetworkCapabilities nc) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700346 return (nc.mNetworkCapabilities == this.mNetworkCapabilities);
347 }
348
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900349 private boolean equalsNetCapabilitiesImmutable(NetworkCapabilities that) {
350 return ((this.mNetworkCapabilities & ~MUTABLE_CAPABILITIES) ==
351 (that.mNetworkCapabilities & ~MUTABLE_CAPABILITIES));
352 }
353
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900354 private boolean equalsNetCapabilitiesRequestable(NetworkCapabilities that) {
355 return ((this.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) ==
356 (that.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES));
357 }
358
Robert Greenwalt1448f052014-04-08 13:41:39 -0700359 /**
Paul Jensen487ffe72015-07-24 15:57:11 -0400360 * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if all the capabilities it provides are
361 * typically provided by restricted networks.
362 *
363 * TODO: consider:
364 * - Renaming it to guessRestrictedCapability and make it set the
365 * restricted capability bit in addition to clearing it.
366 * @hide
367 */
368 public void maybeMarkCapabilitiesRestricted() {
Robert Greenwalta7e148a2017-04-10 14:32:23 -0700369 // Verify there aren't any unrestricted capabilities. If there are we say
370 // the whole thing is unrestricted.
371 final boolean hasUnrestrictedCapabilities =
372 ((mNetworkCapabilities & UNRESTRICTED_CAPABILITIES) != 0);
373
374 // Must have at least some restricted capabilities.
375 final boolean hasRestrictedCapabilities =
376 ((mNetworkCapabilities & RESTRICTED_CAPABILITIES) != 0);
377
378 if (hasRestrictedCapabilities && !hasUnrestrictedCapabilities) {
Paul Jensen487ffe72015-07-24 15:57:11 -0400379 removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
Paul Jensenaae613d2015-08-19 11:06:15 -0400380 }
Paul Jensen487ffe72015-07-24 15:57:11 -0400381 }
382
383 /**
Robert Greenwalt1448f052014-04-08 13:41:39 -0700384 * Representing the transport type. Apps should generally not care about transport. A
385 * request for a fast internet connection could be satisfied by a number of different
386 * transports. If any are specified here it will be satisfied a Network that matches
387 * any of them. If a caller doesn't care about the transport it should not specify any.
388 */
389 private long mTransportTypes;
390
391 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700392 * Indicates this network uses a Cellular transport.
Robert Greenwalt1448f052014-04-08 13:41:39 -0700393 */
394 public static final int TRANSPORT_CELLULAR = 0;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700395
396 /**
397 * Indicates this network uses a Wi-Fi transport.
398 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700399 public static final int TRANSPORT_WIFI = 1;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700400
401 /**
402 * Indicates this network uses a Bluetooth transport.
403 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700404 public static final int TRANSPORT_BLUETOOTH = 2;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700405
406 /**
407 * Indicates this network uses an Ethernet transport.
408 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700409 public static final int TRANSPORT_ETHERNET = 3;
410
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400411 /**
412 * Indicates this network uses a VPN transport.
413 */
414 public static final int TRANSPORT_VPN = 4;
415
Etan Cohen305ea282016-06-20 09:27:12 -0700416 /**
Etan Cohen0849ded2016-10-26 11:22:06 -0700417 * Indicates this network uses a Wi-Fi Aware transport.
Etan Cohen305ea282016-06-20 09:27:12 -0700418 */
Etan Cohen0849ded2016-10-26 11:22:06 -0700419 public static final int TRANSPORT_WIFI_AWARE = 5;
Etan Cohen305ea282016-06-20 09:27:12 -0700420
Robert Quattlebaum5f915762017-05-15 15:53:29 -0700421 /**
422 * Indicates this network uses a LoWPAN transport.
423 * @hide
424 */
425 public static final int TRANSPORT_LOWPAN = 6;
426
Hugo Benichi6a9bb8e2017-03-15 23:05:01 +0900427 /** @hide */
428 public static final int MIN_TRANSPORT = TRANSPORT_CELLULAR;
429 /** @hide */
Robert Quattlebaum5f915762017-05-15 15:53:29 -0700430 public static final int MAX_TRANSPORT = TRANSPORT_LOWPAN;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700431
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900432 private static final String[] TRANSPORT_NAMES = {
433 "CELLULAR",
434 "WIFI",
435 "BLUETOOTH",
436 "ETHERNET",
437 "VPN",
Robert Quattlebaum5f915762017-05-15 15:53:29 -0700438 "WIFI_AWARE",
439 "LOWPAN"
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900440 };
441
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700442 /**
443 * Adds the given transport type to this {@code NetworkCapability} instance.
444 * Multiple transports may be applied sequentially. Note that when searching
445 * for a network to satisfy a request, any listed in the request will satisfy the request.
446 * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a
447 * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network
448 * to be selected. This is logically different than
449 * {@code NetworkCapabilities.NET_CAPABILITY_*} listed above.
450 *
451 * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be added.
Pierre Imaic8419a82016-03-22 17:54:54 +0900452 * @return This NetworkCapabilities instance, to facilitate chaining.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700453 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700454 */
Robert Greenwalt7569f182014-06-08 16:42:59 -0700455 public NetworkCapabilities addTransportType(int transportType) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700456 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
457 throw new IllegalArgumentException("TransportType out of range");
458 }
459 mTransportTypes |= 1 << transportType;
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700460 setNetworkSpecifier(mNetworkSpecifier); // used for exception checking
Robert Greenwalt7569f182014-06-08 16:42:59 -0700461 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700462 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700463
464 /**
465 * Removes (if found) the given transport from this {@code NetworkCapability} instance.
466 *
467 * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be removed.
Pierre Imaic8419a82016-03-22 17:54:54 +0900468 * @return This NetworkCapabilities instance, to facilitate chaining.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700469 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700470 */
Robert Greenwalt7569f182014-06-08 16:42:59 -0700471 public NetworkCapabilities removeTransportType(int transportType) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700472 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
473 throw new IllegalArgumentException("TransportType out of range");
474 }
475 mTransportTypes &= ~(1 << transportType);
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700476 setNetworkSpecifier(mNetworkSpecifier); // used for exception checking
Robert Greenwalt7569f182014-06-08 16:42:59 -0700477 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700478 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700479
480 /**
481 * Gets all the transports set on this {@code NetworkCapability} instance.
482 *
Robert Greenwalt7569f182014-06-08 16:42:59 -0700483 * @return an array of {@code NetworkCapabilities.TRANSPORT_*} values
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700484 * for this instance.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700485 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700486 */
Robert Greenwalt7569f182014-06-08 16:42:59 -0700487 public int[] getTransportTypes() {
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900488 return BitUtils.unpackBits(mTransportTypes);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700489 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700490
491 /**
492 * Tests for the presence of a transport on this instance.
493 *
494 * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be tested for.
495 * @return {@code true} if set on this instance.
496 */
Robert Greenwalt5c55e332014-05-08 00:02:04 -0700497 public boolean hasTransport(int transportType) {
498 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
499 return false;
500 }
501 return ((mTransportTypes & (1 << transportType)) != 0);
502 }
Robert Greenwalt1448f052014-04-08 13:41:39 -0700503
504 private void combineTransportTypes(NetworkCapabilities nc) {
505 this.mTransportTypes |= nc.mTransportTypes;
506 }
507 private boolean satisfiedByTransportTypes(NetworkCapabilities nc) {
508 return ((this.mTransportTypes == 0) ||
509 ((this.mTransportTypes & nc.mTransportTypes) != 0));
510 }
Robert Greenwalt06314e42014-10-29 14:04:06 -0700511 /** @hide */
512 public boolean equalsTransportTypes(NetworkCapabilities nc) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700513 return (nc.mTransportTypes == this.mTransportTypes);
514 }
515
516 /**
517 * Passive link bandwidth. This is a rough guide of the expected peak bandwidth
518 * for the first hop on the given transport. It is not measured, but may take into account
519 * link parameters (Radio technology, allocated channels, etc).
520 */
521 private int mLinkUpBandwidthKbps;
522 private int mLinkDownBandwidthKbps;
523
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700524 /**
525 * Sets the upstream bandwidth for this network in Kbps. This always only refers to
526 * the estimated first hop transport bandwidth.
527 * <p>
528 * Note that when used to request a network, this specifies the minimum acceptable.
529 * When received as the state of an existing network this specifies the typical
530 * first hop bandwidth expected. This is never measured, but rather is inferred
531 * from technology type and other link parameters. It could be used to differentiate
532 * between very slow 1xRTT cellular links and other faster networks or even between
533 * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
534 * fast backhauls and slow backhauls.
535 *
536 * @param upKbps the estimated first hop upstream (device to network) bandwidth.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700537 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700538 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700539 public void setLinkUpstreamBandwidthKbps(int upKbps) {
540 mLinkUpBandwidthKbps = upKbps;
541 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700542
543 /**
544 * Retrieves the upstream bandwidth for this network in Kbps. This always only refers to
545 * the estimated first hop transport bandwidth.
546 *
547 * @return The estimated first hop upstream (device to network) bandwidth.
548 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700549 public int getLinkUpstreamBandwidthKbps() {
550 return mLinkUpBandwidthKbps;
551 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700552
553 /**
554 * Sets the downstream bandwidth for this network in Kbps. This always only refers to
555 * the estimated first hop transport bandwidth.
556 * <p>
557 * Note that when used to request a network, this specifies the minimum acceptable.
558 * When received as the state of an existing network this specifies the typical
559 * first hop bandwidth expected. This is never measured, but rather is inferred
560 * from technology type and other link parameters. It could be used to differentiate
561 * between very slow 1xRTT cellular links and other faster networks or even between
562 * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
563 * fast backhauls and slow backhauls.
564 *
565 * @param downKbps the estimated first hop downstream (network to device) bandwidth.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700566 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700567 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700568 public void setLinkDownstreamBandwidthKbps(int downKbps) {
569 mLinkDownBandwidthKbps = downKbps;
570 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700571
572 /**
573 * Retrieves the downstream bandwidth for this network in Kbps. This always only refers to
574 * the estimated first hop transport bandwidth.
575 *
576 * @return The estimated first hop downstream (network to device) bandwidth.
577 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700578 public int getLinkDownstreamBandwidthKbps() {
579 return mLinkDownBandwidthKbps;
580 }
581
582 private void combineLinkBandwidths(NetworkCapabilities nc) {
583 this.mLinkUpBandwidthKbps =
584 Math.max(this.mLinkUpBandwidthKbps, nc.mLinkUpBandwidthKbps);
585 this.mLinkDownBandwidthKbps =
586 Math.max(this.mLinkDownBandwidthKbps, nc.mLinkDownBandwidthKbps);
587 }
588 private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) {
589 return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps ||
590 this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps);
591 }
592 private boolean equalsLinkBandwidths(NetworkCapabilities nc) {
593 return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps &&
594 this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
595 }
596
Etan Cohena7434272017-04-03 12:17:51 -0700597 private NetworkSpecifier mNetworkSpecifier = null;
598
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700599 /**
600 * Sets the optional bearer specific network specifier.
601 * This has no meaning if a single transport is also not specified, so calling
602 * this without a single transport set will generate an exception, as will
603 * subsequently adding or removing transports after this is set.
604 * </p>
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700605 *
Etan Cohena7434272017-04-03 12:17:51 -0700606 * @param networkSpecifier A concrete, parcelable framework class that extends
607 * NetworkSpecifier.
Pierre Imaic8419a82016-03-22 17:54:54 +0900608 * @return This NetworkCapabilities instance, to facilitate chaining.
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700609 * @hide
610 */
Etan Cohena7434272017-04-03 12:17:51 -0700611 public NetworkCapabilities setNetworkSpecifier(NetworkSpecifier networkSpecifier) {
612 if (networkSpecifier != null && Long.bitCount(mTransportTypes) != 1) {
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700613 throw new IllegalStateException("Must have a single transport specified to use " +
614 "setNetworkSpecifier");
615 }
Etan Cohena7434272017-04-03 12:17:51 -0700616
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700617 mNetworkSpecifier = networkSpecifier;
Etan Cohena7434272017-04-03 12:17:51 -0700618
Pierre Imaic8419a82016-03-22 17:54:54 +0900619 return this;
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700620 }
621
622 /**
623 * Gets the optional bearer specific network specifier.
624 *
Etan Cohena7434272017-04-03 12:17:51 -0700625 * @return The optional {@link NetworkSpecifier} specifying the bearer specific network
626 * specifier. See {@link #setNetworkSpecifier}.
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700627 * @hide
628 */
Etan Cohena7434272017-04-03 12:17:51 -0700629 public NetworkSpecifier getNetworkSpecifier() {
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700630 return mNetworkSpecifier;
631 }
632
633 private void combineSpecifiers(NetworkCapabilities nc) {
Etan Cohena7434272017-04-03 12:17:51 -0700634 if (mNetworkSpecifier != null && !mNetworkSpecifier.equals(nc.mNetworkSpecifier)) {
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700635 throw new IllegalStateException("Can't combine two networkSpecifiers");
636 }
Etan Cohena7434272017-04-03 12:17:51 -0700637 setNetworkSpecifier(nc.mNetworkSpecifier);
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700638 }
Etan Cohena7434272017-04-03 12:17:51 -0700639
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700640 private boolean satisfiedBySpecifier(NetworkCapabilities nc) {
Etan Cohena7434272017-04-03 12:17:51 -0700641 return mNetworkSpecifier == null || mNetworkSpecifier.satisfiedBy(nc.mNetworkSpecifier)
642 || nc.mNetworkSpecifier instanceof MatchAllNetworkSpecifier;
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700643 }
Etan Cohena7434272017-04-03 12:17:51 -0700644
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700645 private boolean equalsSpecifier(NetworkCapabilities nc) {
Etan Cohena7434272017-04-03 12:17:51 -0700646 return Objects.equals(mNetworkSpecifier, nc.mNetworkSpecifier);
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700647 }
648
Robert Greenwalt1448f052014-04-08 13:41:39 -0700649 /**
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900650 * Magic value that indicates no signal strength provided. A request specifying this value is
651 * always satisfied.
652 *
653 * @hide
654 */
655 public static final int SIGNAL_STRENGTH_UNSPECIFIED = Integer.MIN_VALUE;
656
657 /**
658 * Signal strength. This is a signed integer, and higher values indicate better signal.
659 * The exact units are bearer-dependent. For example, Wi-Fi uses RSSI.
660 */
661 private int mSignalStrength;
662
663 /**
664 * Sets the signal strength. This is a signed integer, with higher values indicating a stronger
665 * signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same RSSI units
666 * reported by WifiManager.
667 * <p>
668 * Note that when used to register a network callback, this specifies the minimum acceptable
669 * signal strength. When received as the state of an existing network it specifies the current
670 * value. A value of code SIGNAL_STRENGTH_UNSPECIFIED} means no value when received and has no
671 * effect when requesting a callback.
672 *
673 * @param signalStrength the bearer-specific signal strength.
674 * @hide
675 */
676 public void setSignalStrength(int signalStrength) {
677 mSignalStrength = signalStrength;
678 }
679
680 /**
681 * Returns {@code true} if this object specifies a signal strength.
682 *
683 * @hide
684 */
685 public boolean hasSignalStrength() {
686 return mSignalStrength > SIGNAL_STRENGTH_UNSPECIFIED;
687 }
688
689 /**
690 * Retrieves the signal strength.
691 *
692 * @return The bearer-specific signal strength.
693 * @hide
694 */
695 public int getSignalStrength() {
696 return mSignalStrength;
697 }
698
699 private void combineSignalStrength(NetworkCapabilities nc) {
700 this.mSignalStrength = Math.max(this.mSignalStrength, nc.mSignalStrength);
701 }
702
703 private boolean satisfiedBySignalStrength(NetworkCapabilities nc) {
704 return this.mSignalStrength <= nc.mSignalStrength;
705 }
706
707 private boolean equalsSignalStrength(NetworkCapabilities nc) {
708 return this.mSignalStrength == nc.mSignalStrength;
709 }
710
711 /**
Robert Greenwalt1448f052014-04-08 13:41:39 -0700712 * Combine a set of Capabilities to this one. Useful for coming up with the complete set
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900713 * @hide
Robert Greenwalt1448f052014-04-08 13:41:39 -0700714 */
715 public void combineCapabilities(NetworkCapabilities nc) {
716 combineNetCapabilities(nc);
717 combineTransportTypes(nc);
718 combineLinkBandwidths(nc);
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700719 combineSpecifiers(nc);
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900720 combineSignalStrength(nc);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700721 }
722
723 /**
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900724 * Check if our requirements are satisfied by the given {@code NetworkCapabilities}.
725 *
726 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
727 * @param onlyImmutable if {@code true}, do not consider mutable requirements such as link
728 * bandwidth, signal strength, or validation / captive portal status.
729 *
730 * @hide
731 */
732 private boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc, boolean onlyImmutable) {
733 return (nc != null &&
734 satisfiedByNetCapabilities(nc, onlyImmutable) &&
735 satisfiedByTransportTypes(nc) &&
736 (onlyImmutable || satisfiedByLinkBandwidths(nc)) &&
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900737 satisfiedBySpecifier(nc) &&
738 (onlyImmutable || satisfiedBySignalStrength(nc)));
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900739 }
740
741 /**
742 * Check if our requirements are satisfied by the given {@code NetworkCapabilities}.
743 *
744 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
745 *
746 * @hide
Robert Greenwalt1448f052014-04-08 13:41:39 -0700747 */
748 public boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc) {
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900749 return satisfiedByNetworkCapabilities(nc, false);
750 }
751
752 /**
753 * Check if our immutable requirements are satisfied by the given {@code NetworkCapabilities}.
754 *
755 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
756 *
757 * @hide
758 */
759 public boolean satisfiedByImmutableNetworkCapabilities(NetworkCapabilities nc) {
760 return satisfiedByNetworkCapabilities(nc, true);
761 }
762
763 /**
764 * Checks that our immutable capabilities are the same as those of the given
765 * {@code NetworkCapabilities}.
766 *
767 * @hide
768 */
769 public boolean equalImmutableCapabilities(NetworkCapabilities nc) {
770 if (nc == null) return false;
771 return (equalsNetCapabilitiesImmutable(nc) &&
772 equalsTransportTypes(nc) &&
773 equalsSpecifier(nc));
Robert Greenwalt1448f052014-04-08 13:41:39 -0700774 }
775
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900776 /**
777 * Checks that our requestable capabilities are the same as those of the given
778 * {@code NetworkCapabilities}.
779 *
780 * @hide
781 */
782 public boolean equalRequestableCapabilities(NetworkCapabilities nc) {
783 if (nc == null) return false;
784 return (equalsNetCapabilitiesRequestable(nc) &&
785 equalsTransportTypes(nc) &&
786 equalsSpecifier(nc));
787 }
788
Robert Greenwalt1448f052014-04-08 13:41:39 -0700789 @Override
790 public boolean equals(Object obj) {
791 if (obj == null || (obj instanceof NetworkCapabilities == false)) return false;
792 NetworkCapabilities that = (NetworkCapabilities)obj;
793 return (equalsNetCapabilities(that) &&
794 equalsTransportTypes(that) &&
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700795 equalsLinkBandwidths(that) &&
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900796 equalsSignalStrength(that) &&
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700797 equalsSpecifier(that));
Robert Greenwalt1448f052014-04-08 13:41:39 -0700798 }
799
800 @Override
801 public int hashCode() {
802 return ((int)(mNetworkCapabilities & 0xFFFFFFFF) +
803 ((int)(mNetworkCapabilities >> 32) * 3) +
804 ((int)(mTransportTypes & 0xFFFFFFFF) * 5) +
805 ((int)(mTransportTypes >> 32) * 7) +
806 (mLinkUpBandwidthKbps * 11) +
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700807 (mLinkDownBandwidthKbps * 13) +
Etan Cohena7434272017-04-03 12:17:51 -0700808 Objects.hashCode(mNetworkSpecifier) * 17 +
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900809 (mSignalStrength * 19));
Robert Greenwalt1448f052014-04-08 13:41:39 -0700810 }
811
Wink Saville4e2dea72014-09-20 11:04:03 -0700812 @Override
Robert Greenwalt1448f052014-04-08 13:41:39 -0700813 public int describeContents() {
814 return 0;
815 }
Wink Saville4e2dea72014-09-20 11:04:03 -0700816 @Override
Robert Greenwalt1448f052014-04-08 13:41:39 -0700817 public void writeToParcel(Parcel dest, int flags) {
818 dest.writeLong(mNetworkCapabilities);
819 dest.writeLong(mTransportTypes);
820 dest.writeInt(mLinkUpBandwidthKbps);
821 dest.writeInt(mLinkDownBandwidthKbps);
Etan Cohena7434272017-04-03 12:17:51 -0700822 dest.writeParcelable((Parcelable) mNetworkSpecifier, flags);
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900823 dest.writeInt(mSignalStrength);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700824 }
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900825
Robert Greenwalt1448f052014-04-08 13:41:39 -0700826 public static final Creator<NetworkCapabilities> CREATOR =
827 new Creator<NetworkCapabilities>() {
Wink Saville4e2dea72014-09-20 11:04:03 -0700828 @Override
Robert Greenwalt1448f052014-04-08 13:41:39 -0700829 public NetworkCapabilities createFromParcel(Parcel in) {
830 NetworkCapabilities netCap = new NetworkCapabilities();
831
832 netCap.mNetworkCapabilities = in.readLong();
833 netCap.mTransportTypes = in.readLong();
834 netCap.mLinkUpBandwidthKbps = in.readInt();
835 netCap.mLinkDownBandwidthKbps = in.readInt();
Etan Cohena7434272017-04-03 12:17:51 -0700836 netCap.mNetworkSpecifier = in.readParcelable(null);
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900837 netCap.mSignalStrength = in.readInt();
Robert Greenwalt1448f052014-04-08 13:41:39 -0700838 return netCap;
839 }
Wink Saville4e2dea72014-09-20 11:04:03 -0700840 @Override
Robert Greenwalt1448f052014-04-08 13:41:39 -0700841 public NetworkCapabilities[] newArray(int size) {
842 return new NetworkCapabilities[size];
843 }
844 };
845
Wink Saville4e2dea72014-09-20 11:04:03 -0700846 @Override
Robert Greenwalt1448f052014-04-08 13:41:39 -0700847 public String toString() {
Robert Greenwalt7569f182014-06-08 16:42:59 -0700848 int[] types = getTransportTypes();
Hugo Benichi5df9d722016-04-25 17:16:35 +0900849 String transports = (types.length > 0) ? " Transports: " + transportNamesOf(types) : "";
Robert Greenwalt1448f052014-04-08 13:41:39 -0700850
Robert Greenwalt7569f182014-06-08 16:42:59 -0700851 types = getCapabilities();
852 String capabilities = (types.length > 0 ? " Capabilities: " : "");
853 for (int i = 0; i < types.length; ) {
854 switch (types[i]) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700855 case NET_CAPABILITY_MMS: capabilities += "MMS"; break;
856 case NET_CAPABILITY_SUPL: capabilities += "SUPL"; break;
857 case NET_CAPABILITY_DUN: capabilities += "DUN"; break;
858 case NET_CAPABILITY_FOTA: capabilities += "FOTA"; break;
859 case NET_CAPABILITY_IMS: capabilities += "IMS"; break;
860 case NET_CAPABILITY_CBS: capabilities += "CBS"; break;
861 case NET_CAPABILITY_WIFI_P2P: capabilities += "WIFI_P2P"; break;
862 case NET_CAPABILITY_IA: capabilities += "IA"; break;
863 case NET_CAPABILITY_RCS: capabilities += "RCS"; break;
864 case NET_CAPABILITY_XCAP: capabilities += "XCAP"; break;
865 case NET_CAPABILITY_EIMS: capabilities += "EIMS"; break;
866 case NET_CAPABILITY_NOT_METERED: capabilities += "NOT_METERED"; break;
867 case NET_CAPABILITY_INTERNET: capabilities += "INTERNET"; break;
868 case NET_CAPABILITY_NOT_RESTRICTED: capabilities += "NOT_RESTRICTED"; break;
Robert Greenwalt16e12ab2014-07-08 15:31:37 -0700869 case NET_CAPABILITY_TRUSTED: capabilities += "TRUSTED"; break;
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400870 case NET_CAPABILITY_NOT_VPN: capabilities += "NOT_VPN"; break;
Lorenzo Colitti76f67792015-05-14 17:28:27 +0900871 case NET_CAPABILITY_VALIDATED: capabilities += "VALIDATED"; break;
Paul Jensencf4c2c62015-07-01 14:16:32 -0400872 case NET_CAPABILITY_CAPTIVE_PORTAL: capabilities += "CAPTIVE_PORTAL"; break;
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900873 case NET_CAPABILITY_FOREGROUND: capabilities += "FOREGROUND"; break;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700874 }
Robert Greenwalt7569f182014-06-08 16:42:59 -0700875 if (++i < types.length) capabilities += "&";
Robert Greenwalt1448f052014-04-08 13:41:39 -0700876 }
877
878 String upBand = ((mLinkUpBandwidthKbps > 0) ? " LinkUpBandwidth>=" +
879 mLinkUpBandwidthKbps + "Kbps" : "");
880 String dnBand = ((mLinkDownBandwidthKbps > 0) ? " LinkDnBandwidth>=" +
881 mLinkDownBandwidthKbps + "Kbps" : "");
882
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700883 String specifier = (mNetworkSpecifier == null ?
884 "" : " Specifier: <" + mNetworkSpecifier + ">");
885
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900886 String signalStrength = (hasSignalStrength() ? " SignalStrength: " + mSignalStrength : "");
887
888 return "[" + transports + capabilities + upBand + dnBand + specifier + signalStrength + "]";
Robert Greenwalt1448f052014-04-08 13:41:39 -0700889 }
Hugo Benichi5df9d722016-04-25 17:16:35 +0900890
891 /**
892 * @hide
893 */
894 public static String transportNamesOf(int[] types) {
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900895 if (types == null || types.length == 0) {
896 return "";
Hugo Benichi5df9d722016-04-25 17:16:35 +0900897 }
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900898 StringBuilder transports = new StringBuilder();
899 for (int t : types) {
900 transports.append("|").append(transportNameOf(t));
901 }
902 return transports.substring(1);
903 }
904
905 /**
906 * @hide
907 */
908 public static String transportNameOf(int transport) {
909 if (transport < 0 || TRANSPORT_NAMES.length <= transport) {
910 return "UNKNOWN";
911 }
912 return TRANSPORT_NAMES[transport];
Hugo Benichi5df9d722016-04-25 17:16:35 +0900913 }
Robert Greenwalt1448f052014-04-08 13:41:39 -0700914}