blob: 0b9289345dbe7c206923c67768cde575e684763a [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;
Hugo Benichi16f0a942017-06-20 14:07:59 +090024import com.android.internal.util.Preconditions;
Etan Cohena7434272017-04-03 12:17:51 -070025
26import java.util.Objects;
Hugo Benichieae7a222017-07-25 11:40:56 +090027import java.util.StringJoiner;
Robert Greenwalt1448f052014-04-08 13:41:39 -070028
29/**
Robert Greenwalt01d004e2014-05-18 15:24:21 -070030 * This class represents the capabilities of a network. This is used both to specify
31 * needs to {@link ConnectivityManager} and when inspecting a network.
32 *
33 * Note that this replaces the old {@link ConnectivityManager#TYPE_MOBILE} method
34 * of network selection. Rather than indicate a need for Wi-Fi because an application
Wink Saville4e2dea72014-09-20 11:04:03 -070035 * needs high bandwidth and risk obsolescence when a new, fast network appears (like LTE),
Robert Greenwalt01d004e2014-05-18 15:24:21 -070036 * the application should specify it needs high bandwidth. Similarly if an application
37 * needs an unmetered network for a bulk transfer it can specify that rather than assuming
38 * all cellular based connections are metered and all Wi-Fi based connections are not.
Robert Greenwalt1448f052014-04-08 13:41:39 -070039 */
40public final class NetworkCapabilities implements Parcelable {
Etan Cohena7434272017-04-03 12:17:51 -070041 private static final String TAG = "NetworkCapabilities";
42
Robert Greenwalt7569f182014-06-08 16:42:59 -070043 /**
44 * @hide
45 */
Robert Greenwalt01d004e2014-05-18 15:24:21 -070046 public NetworkCapabilities() {
Lorenzo Colittif7058f52015-04-27 11:31:55 +090047 clearAll();
Lorenzo Colitti260a36d2015-07-08 12:49:04 +090048 mNetworkCapabilities = DEFAULT_CAPABILITIES;
Robert Greenwalt01d004e2014-05-18 15:24:21 -070049 }
50
51 public NetworkCapabilities(NetworkCapabilities nc) {
52 if (nc != null) {
53 mNetworkCapabilities = nc.mNetworkCapabilities;
54 mTransportTypes = nc.mTransportTypes;
55 mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps;
56 mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
Robert Greenwalt94badcc2014-07-10 14:53:24 -070057 mNetworkSpecifier = nc.mNetworkSpecifier;
Lorenzo Colittic3f21f32015-07-06 23:50:27 +090058 mSignalStrength = nc.mSignalStrength;
Robert Greenwalt01d004e2014-05-18 15:24:21 -070059 }
60 }
Robert Greenwalt1448f052014-04-08 13:41:39 -070061
62 /**
Lorenzo Colittif7058f52015-04-27 11:31:55 +090063 * Completely clears the contents of this object, removing even the capabilities that are set
64 * by default when the object is constructed.
65 * @hide
66 */
67 public void clearAll() {
68 mNetworkCapabilities = mTransportTypes = 0;
69 mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = 0;
70 mNetworkSpecifier = null;
Lorenzo Colittic3f21f32015-07-06 23:50:27 +090071 mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
Lorenzo Colittif7058f52015-04-27 11:31:55 +090072 }
73
74 /**
Robert Greenwalt1448f052014-04-08 13:41:39 -070075 * Represents the network's capabilities. If any are specified they will be satisfied
76 * by any Network that matches all of them.
77 */
Lorenzo Colittif7058f52015-04-27 11:31:55 +090078 private long mNetworkCapabilities;
Robert Greenwalt1448f052014-04-08 13:41:39 -070079
80 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -070081 * Indicates this is a network that has the ability to reach the
82 * carrier's MMSC for sending and receiving MMS messages.
Robert Greenwalt1448f052014-04-08 13:41:39 -070083 */
84 public static final int NET_CAPABILITY_MMS = 0;
Robert Greenwalt01d004e2014-05-18 15:24:21 -070085
86 /**
87 * Indicates this is a network that has the ability to reach the carrier's
88 * SUPL server, used to retrieve GPS information.
89 */
Robert Greenwalt1448f052014-04-08 13:41:39 -070090 public static final int NET_CAPABILITY_SUPL = 1;
Robert Greenwalt01d004e2014-05-18 15:24:21 -070091
92 /**
93 * Indicates this is a network that has the ability to reach the carrier's
94 * DUN or tethering gateway.
95 */
Robert Greenwalt1448f052014-04-08 13:41:39 -070096 public static final int NET_CAPABILITY_DUN = 2;
Robert Greenwalt01d004e2014-05-18 15:24:21 -070097
98 /**
99 * Indicates this is a network that has the ability to reach the carrier's
100 * FOTA portal, used for over the air updates.
101 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700102 public static final int NET_CAPABILITY_FOTA = 3;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700103
104 /**
105 * Indicates this is a network that has the ability to reach the carrier's
106 * IMS servers, used for network registration and signaling.
107 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700108 public static final int NET_CAPABILITY_IMS = 4;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700109
110 /**
111 * Indicates this is a network that has the ability to reach the carrier's
112 * CBS servers, used for carrier specific services.
113 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700114 public static final int NET_CAPABILITY_CBS = 5;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700115
116 /**
117 * Indicates this is a network that has the ability to reach a Wi-Fi direct
118 * peer.
119 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700120 public static final int NET_CAPABILITY_WIFI_P2P = 6;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700121
122 /**
123 * Indicates this is a network that has the ability to reach a carrier's
124 * Initial Attach servers.
125 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700126 public static final int NET_CAPABILITY_IA = 7;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700127
128 /**
129 * Indicates this is a network that has the ability to reach a carrier's
130 * RCS servers, used for Rich Communication Services.
131 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700132 public static final int NET_CAPABILITY_RCS = 8;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700133
134 /**
135 * Indicates this is a network that has the ability to reach a carrier's
136 * XCAP servers, used for configuration and control.
137 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700138 public static final int NET_CAPABILITY_XCAP = 9;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700139
140 /**
141 * Indicates this is a network that has the ability to reach a carrier's
Robert Greenwalt4bd43892015-07-09 14:49:35 -0700142 * Emergency IMS servers or other services, used for network signaling
143 * during emergency calls.
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700144 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700145 public static final int NET_CAPABILITY_EIMS = 10;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700146
147 /**
148 * Indicates that this network is unmetered.
149 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700150 public static final int NET_CAPABILITY_NOT_METERED = 11;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700151
152 /**
153 * Indicates that this network should be able to reach the internet.
154 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700155 public static final int NET_CAPABILITY_INTERNET = 12;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700156
157 /**
158 * Indicates that this network is available for general use. If this is not set
159 * applications should not attempt to communicate on this network. Note that this
160 * is simply informative and not enforcement - enforcement is handled via other means.
161 * Set by default.
162 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700163 public static final int NET_CAPABILITY_NOT_RESTRICTED = 13;
164
Robert Greenwalt16e12ab2014-07-08 15:31:37 -0700165 /**
166 * Indicates that the user has indicated implicit trust of this network. This
167 * generally means it's a sim-selected carrier, a plugged in ethernet, a paired
168 * BT device or a wifi the user asked to connect to. Untrusted networks
169 * are probably limited to unknown wifi AP. Set by default.
170 */
171 public static final int NET_CAPABILITY_TRUSTED = 14;
172
Paul Jensen76b610a2015-03-18 09:33:07 -0400173 /**
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400174 * Indicates that this network is not a VPN. This capability is set by default and should be
Paul Jensen76b610a2015-03-18 09:33:07 -0400175 * explicitly cleared for VPN networks.
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400176 */
177 public static final int NET_CAPABILITY_NOT_VPN = 15;
178
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900179 /**
180 * Indicates that connectivity on this network was successfully validated. For example, for a
181 * network with NET_CAPABILITY_INTERNET, it means that Internet connectivity was successfully
182 * detected.
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900183 */
184 public static final int NET_CAPABILITY_VALIDATED = 16;
Robert Greenwalt16e12ab2014-07-08 15:31:37 -0700185
Paul Jensen3d194ea2015-06-16 14:27:36 -0400186 /**
187 * Indicates that this network was found to have a captive portal in place last time it was
188 * probed.
189 */
190 public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17;
191
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900192 /**
193 * Indicates that this network is available for use by apps, and not a network that is being
194 * kept up in the background to facilitate fast network switching.
195 * @hide
196 */
197 public static final int NET_CAPABILITY_FOREGROUND = 18;
198
Robert Greenwalt1448f052014-04-08 13:41:39 -0700199 private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900200 private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_FOREGROUND;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700201
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700202 /**
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900203 * Network capabilities that are expected to be mutable, i.e., can change while a particular
204 * network is connected.
205 */
206 private static final long MUTABLE_CAPABILITIES =
207 // TRUSTED can change when user explicitly connects to an untrusted network in Settings.
208 // http://b/18206275
209 (1 << NET_CAPABILITY_TRUSTED) |
210 (1 << NET_CAPABILITY_VALIDATED) |
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900211 (1 << NET_CAPABILITY_CAPTIVE_PORTAL) |
212 (1 << NET_CAPABILITY_FOREGROUND);
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900213
214 /**
215 * Network capabilities that are not allowed in NetworkRequests. This exists because the
216 * NetworkFactory / NetworkAgent model does not deal well with the situation where a
217 * capability's presence cannot be known in advance. If such a capability is requested, then we
218 * can get into a cycle where the NetworkFactory endlessly churns out NetworkAgents that then
219 * get immediately torn down because they do not have the requested capability.
220 */
221 private static final long NON_REQUESTABLE_CAPABILITIES =
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900222 MUTABLE_CAPABILITIES & ~(1 << NET_CAPABILITY_TRUSTED);
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900223
224 /**
225 * Capabilities that are set by default when the object is constructed.
226 */
227 private static final long DEFAULT_CAPABILITIES =
228 (1 << NET_CAPABILITY_NOT_RESTRICTED) |
229 (1 << NET_CAPABILITY_TRUSTED) |
230 (1 << NET_CAPABILITY_NOT_VPN);
231
232 /**
Paul Jensen487ffe72015-07-24 15:57:11 -0400233 * Capabilities that suggest that a network is restricted.
234 * {@see #maybeMarkCapabilitiesRestricted}.
235 */
Robert Greenwalta7e148a2017-04-10 14:32:23 -0700236 @VisibleForTesting
237 /* package */ static final long RESTRICTED_CAPABILITIES =
Paul Jensen487ffe72015-07-24 15:57:11 -0400238 (1 << NET_CAPABILITY_CBS) |
239 (1 << NET_CAPABILITY_DUN) |
240 (1 << NET_CAPABILITY_EIMS) |
241 (1 << NET_CAPABILITY_FOTA) |
242 (1 << NET_CAPABILITY_IA) |
243 (1 << NET_CAPABILITY_IMS) |
244 (1 << NET_CAPABILITY_RCS) |
245 (1 << NET_CAPABILITY_XCAP);
246
247 /**
Robert Greenwalta7e148a2017-04-10 14:32:23 -0700248 * Capabilities that suggest that a network is unrestricted.
249 * {@see #maybeMarkCapabilitiesRestricted}.
250 */
251 @VisibleForTesting
252 /* package */ static final long UNRESTRICTED_CAPABILITIES =
253 (1 << NET_CAPABILITY_INTERNET) |
254 (1 << NET_CAPABILITY_MMS) |
255 (1 << NET_CAPABILITY_SUPL) |
256 (1 << NET_CAPABILITY_WIFI_P2P);
257
258 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700259 * Adds the given capability to this {@code NetworkCapability} instance.
260 * Multiple capabilities may be applied sequentially. Note that when searching
261 * for a network to satisfy a request, all capabilities requested must be satisfied.
262 *
Robert Greenwalt7569f182014-06-08 16:42:59 -0700263 * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be added.
Pierre Imaic8419a82016-03-22 17:54:54 +0900264 * @return This NetworkCapabilities instance, to facilitate chaining.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700265 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700266 */
Robert Greenwalt7569f182014-06-08 16:42:59 -0700267 public NetworkCapabilities addCapability(int capability) {
268 if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700269 throw new IllegalArgumentException("NetworkCapability out of range");
270 }
Robert Greenwalt7569f182014-06-08 16:42:59 -0700271 mNetworkCapabilities |= 1 << capability;
272 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700273 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700274
275 /**
276 * Removes (if found) the given capability from this {@code NetworkCapability} instance.
277 *
Robert Greenwalt7569f182014-06-08 16:42:59 -0700278 * @param capability the {@code NetworkCapabilities.NET_CAPABILTIY_*} to be removed.
Pierre Imaic8419a82016-03-22 17:54:54 +0900279 * @return This NetworkCapabilities instance, to facilitate chaining.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700280 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700281 */
Robert Greenwalt7569f182014-06-08 16:42:59 -0700282 public NetworkCapabilities removeCapability(int capability) {
283 if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700284 throw new IllegalArgumentException("NetworkCapability out of range");
285 }
Robert Greenwalt7569f182014-06-08 16:42:59 -0700286 mNetworkCapabilities &= ~(1 << capability);
287 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700288 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700289
290 /**
291 * Gets all the capabilities set on this {@code NetworkCapability} instance.
292 *
Robert Greenwalt7569f182014-06-08 16:42:59 -0700293 * @return an array of {@code NetworkCapabilities.NET_CAPABILITY_*} values
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700294 * for this instance.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700295 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700296 */
Robert Greenwalt7569f182014-06-08 16:42:59 -0700297 public int[] getCapabilities() {
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900298 return BitUtils.unpackBits(mNetworkCapabilities);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700299 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700300
301 /**
302 * Tests for the presence of a capabilitity on this instance.
303 *
Robert Greenwalt7569f182014-06-08 16:42:59 -0700304 * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be tested for.
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700305 * @return {@code true} if set on this instance.
306 */
Robert Greenwalt7569f182014-06-08 16:42:59 -0700307 public boolean hasCapability(int capability) {
308 if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
Robert Greenwalt5c55e332014-05-08 00:02:04 -0700309 return false;
310 }
Robert Greenwalt7569f182014-06-08 16:42:59 -0700311 return ((mNetworkCapabilities & (1 << capability)) != 0);
Robert Greenwalt5c55e332014-05-08 00:02:04 -0700312 }
Robert Greenwalt1448f052014-04-08 13:41:39 -0700313
Robert Greenwalt1448f052014-04-08 13:41:39 -0700314 private void combineNetCapabilities(NetworkCapabilities nc) {
315 this.mNetworkCapabilities |= nc.mNetworkCapabilities;
316 }
317
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900318 /**
319 * Convenience function that returns a human-readable description of the first mutable
320 * capability we find. Used to present an error message to apps that request mutable
321 * capabilities.
322 *
323 * @hide
324 */
325 public String describeFirstNonRequestableCapability() {
326 if (hasCapability(NET_CAPABILITY_VALIDATED)) return "NET_CAPABILITY_VALIDATED";
327 if (hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return "NET_CAPABILITY_CAPTIVE_PORTAL";
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900328 if (hasCapability(NET_CAPABILITY_FOREGROUND)) return "NET_CAPABILITY_FOREGROUND";
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900329 // This cannot happen unless the preceding checks are incomplete.
330 if ((mNetworkCapabilities & NON_REQUESTABLE_CAPABILITIES) != 0) {
331 return "unknown non-requestable capabilities " + Long.toHexString(mNetworkCapabilities);
332 }
333 if (mLinkUpBandwidthKbps != 0 || mLinkDownBandwidthKbps != 0) return "link bandwidth";
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900334 if (hasSignalStrength()) return "signalStrength";
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900335 return null;
336 }
337
338 private boolean satisfiedByNetCapabilities(NetworkCapabilities nc, boolean onlyImmutable) {
339 long networkCapabilities = this.mNetworkCapabilities;
340 if (onlyImmutable) {
341 networkCapabilities = networkCapabilities & ~MUTABLE_CAPABILITIES;
342 }
343 return ((nc.mNetworkCapabilities & networkCapabilities) == networkCapabilities);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700344 }
345
Robert Greenwalt06314e42014-10-29 14:04:06 -0700346 /** @hide */
347 public boolean equalsNetCapabilities(NetworkCapabilities nc) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700348 return (nc.mNetworkCapabilities == this.mNetworkCapabilities);
349 }
350
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900351 private boolean equalsNetCapabilitiesRequestable(NetworkCapabilities that) {
352 return ((this.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) ==
353 (that.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES));
354 }
355
Robert Greenwalt1448f052014-04-08 13:41:39 -0700356 /**
Paul Jensen487ffe72015-07-24 15:57:11 -0400357 * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if all the capabilities it provides are
358 * typically provided by restricted networks.
359 *
360 * TODO: consider:
361 * - Renaming it to guessRestrictedCapability and make it set the
362 * restricted capability bit in addition to clearing it.
363 * @hide
364 */
365 public void maybeMarkCapabilitiesRestricted() {
Robert Greenwalta7e148a2017-04-10 14:32:23 -0700366 // Verify there aren't any unrestricted capabilities. If there are we say
367 // the whole thing is unrestricted.
368 final boolean hasUnrestrictedCapabilities =
369 ((mNetworkCapabilities & UNRESTRICTED_CAPABILITIES) != 0);
370
371 // Must have at least some restricted capabilities.
372 final boolean hasRestrictedCapabilities =
373 ((mNetworkCapabilities & RESTRICTED_CAPABILITIES) != 0);
374
375 if (hasRestrictedCapabilities && !hasUnrestrictedCapabilities) {
Paul Jensen487ffe72015-07-24 15:57:11 -0400376 removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
Paul Jensenaae613d2015-08-19 11:06:15 -0400377 }
Paul Jensen487ffe72015-07-24 15:57:11 -0400378 }
379
380 /**
Robert Greenwalt1448f052014-04-08 13:41:39 -0700381 * Representing the transport type. Apps should generally not care about transport. A
382 * request for a fast internet connection could be satisfied by a number of different
383 * transports. If any are specified here it will be satisfied a Network that matches
384 * any of them. If a caller doesn't care about the transport it should not specify any.
385 */
386 private long mTransportTypes;
387
388 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700389 * Indicates this network uses a Cellular transport.
Robert Greenwalt1448f052014-04-08 13:41:39 -0700390 */
391 public static final int TRANSPORT_CELLULAR = 0;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700392
393 /**
394 * Indicates this network uses a Wi-Fi transport.
395 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700396 public static final int TRANSPORT_WIFI = 1;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700397
398 /**
399 * Indicates this network uses a Bluetooth transport.
400 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700401 public static final int TRANSPORT_BLUETOOTH = 2;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700402
403 /**
404 * Indicates this network uses an Ethernet transport.
405 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700406 public static final int TRANSPORT_ETHERNET = 3;
407
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400408 /**
409 * Indicates this network uses a VPN transport.
410 */
411 public static final int TRANSPORT_VPN = 4;
412
Etan Cohen305ea282016-06-20 09:27:12 -0700413 /**
Etan Cohen0849ded2016-10-26 11:22:06 -0700414 * Indicates this network uses a Wi-Fi Aware transport.
Etan Cohen305ea282016-06-20 09:27:12 -0700415 */
Etan Cohen0849ded2016-10-26 11:22:06 -0700416 public static final int TRANSPORT_WIFI_AWARE = 5;
Etan Cohen305ea282016-06-20 09:27:12 -0700417
Robert Quattlebaum5f915762017-05-15 15:53:29 -0700418 /**
419 * Indicates this network uses a LoWPAN transport.
Robert Quattlebaum5f915762017-05-15 15:53:29 -0700420 */
421 public static final int TRANSPORT_LOWPAN = 6;
422
Hugo Benichi6a9bb8e2017-03-15 23:05:01 +0900423 /** @hide */
424 public static final int MIN_TRANSPORT = TRANSPORT_CELLULAR;
425 /** @hide */
Robert Quattlebaum5f915762017-05-15 15:53:29 -0700426 public static final int MAX_TRANSPORT = TRANSPORT_LOWPAN;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700427
Hugo Benichi16f0a942017-06-20 14:07:59 +0900428 /** @hide */
429 public static boolean isValidTransport(int transportType) {
430 return (MIN_TRANSPORT <= transportType) && (transportType <= MAX_TRANSPORT);
431 }
432
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900433 private static final String[] TRANSPORT_NAMES = {
434 "CELLULAR",
435 "WIFI",
436 "BLUETOOTH",
437 "ETHERNET",
438 "VPN",
Robert Quattlebaum5f915762017-05-15 15:53:29 -0700439 "WIFI_AWARE",
440 "LOWPAN"
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900441 };
442
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700443 /**
444 * Adds the given transport type to this {@code NetworkCapability} instance.
445 * Multiple transports may be applied sequentially. Note that when searching
446 * for a network to satisfy a request, any listed in the request will satisfy the request.
447 * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a
448 * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network
449 * to be selected. This is logically different than
450 * {@code NetworkCapabilities.NET_CAPABILITY_*} listed above.
451 *
452 * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be added.
Pierre Imaic8419a82016-03-22 17:54:54 +0900453 * @return This NetworkCapabilities instance, to facilitate chaining.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700454 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700455 */
Robert Greenwalt7569f182014-06-08 16:42:59 -0700456 public NetworkCapabilities addTransportType(int transportType) {
Hugo Benichi16f0a942017-06-20 14:07:59 +0900457 checkValidTransportType(transportType);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700458 mTransportTypes |= 1 << transportType;
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700459 setNetworkSpecifier(mNetworkSpecifier); // used for exception checking
Robert Greenwalt7569f182014-06-08 16:42:59 -0700460 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700461 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700462
463 /**
464 * Removes (if found) the given transport from this {@code NetworkCapability} instance.
465 *
466 * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be removed.
Pierre Imaic8419a82016-03-22 17:54:54 +0900467 * @return This NetworkCapabilities instance, to facilitate chaining.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700468 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700469 */
Robert Greenwalt7569f182014-06-08 16:42:59 -0700470 public NetworkCapabilities removeTransportType(int transportType) {
Hugo Benichi16f0a942017-06-20 14:07:59 +0900471 checkValidTransportType(transportType);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700472 mTransportTypes &= ~(1 << transportType);
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700473 setNetworkSpecifier(mNetworkSpecifier); // used for exception checking
Robert Greenwalt7569f182014-06-08 16:42:59 -0700474 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700475 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700476
477 /**
478 * Gets all the transports set on this {@code NetworkCapability} instance.
479 *
Robert Greenwalt7569f182014-06-08 16:42:59 -0700480 * @return an array of {@code NetworkCapabilities.TRANSPORT_*} values
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700481 * for this instance.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700482 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700483 */
Robert Greenwalt7569f182014-06-08 16:42:59 -0700484 public int[] getTransportTypes() {
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900485 return BitUtils.unpackBits(mTransportTypes);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700486 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700487
488 /**
489 * Tests for the presence of a transport on this instance.
490 *
491 * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be tested for.
492 * @return {@code true} if set on this instance.
493 */
Robert Greenwalt5c55e332014-05-08 00:02:04 -0700494 public boolean hasTransport(int transportType) {
Hugo Benichi16f0a942017-06-20 14:07:59 +0900495 return isValidTransport(transportType) && ((mTransportTypes & (1 << transportType)) != 0);
Robert Greenwalt5c55e332014-05-08 00:02:04 -0700496 }
Robert Greenwalt1448f052014-04-08 13:41:39 -0700497
498 private void combineTransportTypes(NetworkCapabilities nc) {
499 this.mTransportTypes |= nc.mTransportTypes;
500 }
Hugo Benichieae7a222017-07-25 11:40:56 +0900501
Robert Greenwalt1448f052014-04-08 13:41:39 -0700502 private boolean satisfiedByTransportTypes(NetworkCapabilities nc) {
503 return ((this.mTransportTypes == 0) ||
504 ((this.mTransportTypes & nc.mTransportTypes) != 0));
505 }
Hugo Benichieae7a222017-07-25 11:40:56 +0900506
Robert Greenwalt06314e42014-10-29 14:04:06 -0700507 /** @hide */
508 public boolean equalsTransportTypes(NetworkCapabilities nc) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700509 return (nc.mTransportTypes == this.mTransportTypes);
510 }
511
512 /**
513 * Passive link bandwidth. This is a rough guide of the expected peak bandwidth
514 * for the first hop on the given transport. It is not measured, but may take into account
515 * link parameters (Radio technology, allocated channels, etc).
516 */
517 private int mLinkUpBandwidthKbps;
518 private int mLinkDownBandwidthKbps;
519
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700520 /**
521 * Sets the upstream bandwidth for this network in Kbps. This always only refers to
522 * the estimated first hop transport bandwidth.
523 * <p>
524 * Note that when used to request a network, this specifies the minimum acceptable.
525 * When received as the state of an existing network this specifies the typical
526 * first hop bandwidth expected. This is never measured, but rather is inferred
527 * from technology type and other link parameters. It could be used to differentiate
528 * between very slow 1xRTT cellular links and other faster networks or even between
529 * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
530 * fast backhauls and slow backhauls.
531 *
532 * @param upKbps the estimated first hop upstream (device to network) bandwidth.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700533 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700534 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700535 public void setLinkUpstreamBandwidthKbps(int upKbps) {
536 mLinkUpBandwidthKbps = upKbps;
537 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700538
539 /**
540 * Retrieves the upstream bandwidth for this network in Kbps. This always only refers to
541 * the estimated first hop transport bandwidth.
542 *
543 * @return The estimated first hop upstream (device to network) bandwidth.
544 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700545 public int getLinkUpstreamBandwidthKbps() {
546 return mLinkUpBandwidthKbps;
547 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700548
549 /**
550 * Sets the downstream bandwidth for this network in Kbps. This always only refers to
551 * the estimated first hop transport bandwidth.
552 * <p>
553 * Note that when used to request a network, this specifies the minimum acceptable.
554 * When received as the state of an existing network this specifies the typical
555 * first hop bandwidth expected. This is never measured, but rather is inferred
556 * from technology type and other link parameters. It could be used to differentiate
557 * between very slow 1xRTT cellular links and other faster networks or even between
558 * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
559 * fast backhauls and slow backhauls.
560 *
561 * @param downKbps the estimated first hop downstream (network to device) bandwidth.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700562 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700563 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700564 public void setLinkDownstreamBandwidthKbps(int downKbps) {
565 mLinkDownBandwidthKbps = downKbps;
566 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700567
568 /**
569 * Retrieves the downstream bandwidth for this network in Kbps. This always only refers to
570 * the estimated first hop transport bandwidth.
571 *
572 * @return The estimated first hop downstream (network to device) bandwidth.
573 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700574 public int getLinkDownstreamBandwidthKbps() {
575 return mLinkDownBandwidthKbps;
576 }
577
578 private void combineLinkBandwidths(NetworkCapabilities nc) {
579 this.mLinkUpBandwidthKbps =
580 Math.max(this.mLinkUpBandwidthKbps, nc.mLinkUpBandwidthKbps);
581 this.mLinkDownBandwidthKbps =
582 Math.max(this.mLinkDownBandwidthKbps, nc.mLinkDownBandwidthKbps);
583 }
584 private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) {
585 return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps ||
586 this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps);
587 }
588 private boolean equalsLinkBandwidths(NetworkCapabilities nc) {
589 return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps &&
590 this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
591 }
592
Etan Cohena7434272017-04-03 12:17:51 -0700593 private NetworkSpecifier mNetworkSpecifier = null;
594
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700595 /**
596 * Sets the optional bearer specific network specifier.
597 * This has no meaning if a single transport is also not specified, so calling
598 * this without a single transport set will generate an exception, as will
599 * subsequently adding or removing transports after this is set.
600 * </p>
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700601 *
Etan Cohena7434272017-04-03 12:17:51 -0700602 * @param networkSpecifier A concrete, parcelable framework class that extends
603 * NetworkSpecifier.
Pierre Imaic8419a82016-03-22 17:54:54 +0900604 * @return This NetworkCapabilities instance, to facilitate chaining.
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700605 * @hide
606 */
Etan Cohena7434272017-04-03 12:17:51 -0700607 public NetworkCapabilities setNetworkSpecifier(NetworkSpecifier networkSpecifier) {
608 if (networkSpecifier != null && Long.bitCount(mTransportTypes) != 1) {
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700609 throw new IllegalStateException("Must have a single transport specified to use " +
610 "setNetworkSpecifier");
611 }
Etan Cohena7434272017-04-03 12:17:51 -0700612
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700613 mNetworkSpecifier = networkSpecifier;
Etan Cohena7434272017-04-03 12:17:51 -0700614
Pierre Imaic8419a82016-03-22 17:54:54 +0900615 return this;
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700616 }
617
618 /**
619 * Gets the optional bearer specific network specifier.
620 *
Etan Cohena7434272017-04-03 12:17:51 -0700621 * @return The optional {@link NetworkSpecifier} specifying the bearer specific network
622 * specifier. See {@link #setNetworkSpecifier}.
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700623 * @hide
624 */
Etan Cohena7434272017-04-03 12:17:51 -0700625 public NetworkSpecifier getNetworkSpecifier() {
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700626 return mNetworkSpecifier;
627 }
628
629 private void combineSpecifiers(NetworkCapabilities nc) {
Etan Cohena7434272017-04-03 12:17:51 -0700630 if (mNetworkSpecifier != null && !mNetworkSpecifier.equals(nc.mNetworkSpecifier)) {
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700631 throw new IllegalStateException("Can't combine two networkSpecifiers");
632 }
Etan Cohena7434272017-04-03 12:17:51 -0700633 setNetworkSpecifier(nc.mNetworkSpecifier);
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700634 }
Etan Cohena7434272017-04-03 12:17:51 -0700635
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700636 private boolean satisfiedBySpecifier(NetworkCapabilities nc) {
Etan Cohena7434272017-04-03 12:17:51 -0700637 return mNetworkSpecifier == null || mNetworkSpecifier.satisfiedBy(nc.mNetworkSpecifier)
638 || nc.mNetworkSpecifier instanceof MatchAllNetworkSpecifier;
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700639 }
Etan Cohena7434272017-04-03 12:17:51 -0700640
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700641 private boolean equalsSpecifier(NetworkCapabilities nc) {
Etan Cohena7434272017-04-03 12:17:51 -0700642 return Objects.equals(mNetworkSpecifier, nc.mNetworkSpecifier);
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700643 }
644
Robert Greenwalt1448f052014-04-08 13:41:39 -0700645 /**
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900646 * Magic value that indicates no signal strength provided. A request specifying this value is
647 * always satisfied.
648 *
649 * @hide
650 */
651 public static final int SIGNAL_STRENGTH_UNSPECIFIED = Integer.MIN_VALUE;
652
653 /**
654 * Signal strength. This is a signed integer, and higher values indicate better signal.
655 * The exact units are bearer-dependent. For example, Wi-Fi uses RSSI.
656 */
657 private int mSignalStrength;
658
659 /**
660 * Sets the signal strength. This is a signed integer, with higher values indicating a stronger
661 * signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same RSSI units
662 * reported by WifiManager.
663 * <p>
664 * Note that when used to register a network callback, this specifies the minimum acceptable
665 * signal strength. When received as the state of an existing network it specifies the current
666 * value. A value of code SIGNAL_STRENGTH_UNSPECIFIED} means no value when received and has no
667 * effect when requesting a callback.
668 *
669 * @param signalStrength the bearer-specific signal strength.
670 * @hide
671 */
672 public void setSignalStrength(int signalStrength) {
673 mSignalStrength = signalStrength;
674 }
675
676 /**
677 * Returns {@code true} if this object specifies a signal strength.
678 *
679 * @hide
680 */
681 public boolean hasSignalStrength() {
682 return mSignalStrength > SIGNAL_STRENGTH_UNSPECIFIED;
683 }
684
685 /**
686 * Retrieves the signal strength.
687 *
688 * @return The bearer-specific signal strength.
689 * @hide
690 */
691 public int getSignalStrength() {
692 return mSignalStrength;
693 }
694
695 private void combineSignalStrength(NetworkCapabilities nc) {
696 this.mSignalStrength = Math.max(this.mSignalStrength, nc.mSignalStrength);
697 }
698
699 private boolean satisfiedBySignalStrength(NetworkCapabilities nc) {
700 return this.mSignalStrength <= nc.mSignalStrength;
701 }
702
703 private boolean equalsSignalStrength(NetworkCapabilities nc) {
704 return this.mSignalStrength == nc.mSignalStrength;
705 }
706
707 /**
Robert Greenwalt1448f052014-04-08 13:41:39 -0700708 * Combine a set of Capabilities to this one. Useful for coming up with the complete set
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900709 * @hide
Robert Greenwalt1448f052014-04-08 13:41:39 -0700710 */
711 public void combineCapabilities(NetworkCapabilities nc) {
712 combineNetCapabilities(nc);
713 combineTransportTypes(nc);
714 combineLinkBandwidths(nc);
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700715 combineSpecifiers(nc);
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900716 combineSignalStrength(nc);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700717 }
718
719 /**
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900720 * Check if our requirements are satisfied by the given {@code NetworkCapabilities}.
721 *
722 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
723 * @param onlyImmutable if {@code true}, do not consider mutable requirements such as link
724 * bandwidth, signal strength, or validation / captive portal status.
725 *
726 * @hide
727 */
728 private boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc, boolean onlyImmutable) {
729 return (nc != null &&
730 satisfiedByNetCapabilities(nc, onlyImmutable) &&
731 satisfiedByTransportTypes(nc) &&
732 (onlyImmutable || satisfiedByLinkBandwidths(nc)) &&
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900733 satisfiedBySpecifier(nc) &&
734 (onlyImmutable || satisfiedBySignalStrength(nc)));
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900735 }
736
737 /**
738 * Check if our requirements are satisfied by the given {@code NetworkCapabilities}.
739 *
740 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
741 *
742 * @hide
Robert Greenwalt1448f052014-04-08 13:41:39 -0700743 */
744 public boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc) {
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900745 return satisfiedByNetworkCapabilities(nc, false);
746 }
747
748 /**
749 * Check if our immutable requirements are satisfied by the given {@code NetworkCapabilities}.
750 *
751 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
752 *
753 * @hide
754 */
755 public boolean satisfiedByImmutableNetworkCapabilities(NetworkCapabilities nc) {
756 return satisfiedByNetworkCapabilities(nc, true);
757 }
758
759 /**
760 * Checks that our immutable capabilities are the same as those of the given
Hugo Benichieae7a222017-07-25 11:40:56 +0900761 * {@code NetworkCapabilities} and return a String describing any difference.
762 * The returned String is empty if there is no difference.
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900763 *
764 * @hide
765 */
Hugo Benichieae7a222017-07-25 11:40:56 +0900766 public String describeImmutableDifferences(NetworkCapabilities that) {
767 if (that == null) {
768 return "other NetworkCapabilities was null";
769 }
770
771 StringJoiner joiner = new StringJoiner(", ");
772
773 // TODO: consider only enforcing that capabilities are not removed, allowing addition.
774 // Ignore NOT_METERED being added or removed as it is effectively dynamic. http://b/63326103
775 // TODO: properly support NOT_METERED as a mutable and requestable capability.
Hugo Benichi2ecb9402017-08-04 13:18:40 +0900776 final long mask = ~MUTABLE_CAPABILITIES & ~(1 << NET_CAPABILITY_NOT_METERED);
Hugo Benichieae7a222017-07-25 11:40:56 +0900777 long oldImmutableCapabilities = this.mNetworkCapabilities & mask;
778 long newImmutableCapabilities = that.mNetworkCapabilities & mask;
779 if (oldImmutableCapabilities != newImmutableCapabilities) {
780 String before = capabilityNamesOf(BitUtils.unpackBits(oldImmutableCapabilities));
781 String after = capabilityNamesOf(BitUtils.unpackBits(newImmutableCapabilities));
782 joiner.add(String.format("immutable capabilities changed: %s -> %s", before, after));
783 }
784
785 if (!equalsSpecifier(that)) {
786 NetworkSpecifier before = this.getNetworkSpecifier();
787 NetworkSpecifier after = that.getNetworkSpecifier();
788 joiner.add(String.format("specifier changed: %s -> %s", before, after));
789 }
790
791 if (!equalsTransportTypes(that)) {
792 String before = transportNamesOf(this.getTransportTypes());
793 String after = transportNamesOf(that.getTransportTypes());
794 joiner.add(String.format("transports changed: %s -> %s", before, after));
795 }
796
797 return joiner.toString();
Robert Greenwalt1448f052014-04-08 13:41:39 -0700798 }
799
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900800 /**
801 * Checks that our requestable capabilities are the same as those of the given
802 * {@code NetworkCapabilities}.
803 *
804 * @hide
805 */
806 public boolean equalRequestableCapabilities(NetworkCapabilities nc) {
807 if (nc == null) return false;
808 return (equalsNetCapabilitiesRequestable(nc) &&
809 equalsTransportTypes(nc) &&
810 equalsSpecifier(nc));
811 }
812
Robert Greenwalt1448f052014-04-08 13:41:39 -0700813 @Override
814 public boolean equals(Object obj) {
815 if (obj == null || (obj instanceof NetworkCapabilities == false)) return false;
816 NetworkCapabilities that = (NetworkCapabilities)obj;
817 return (equalsNetCapabilities(that) &&
818 equalsTransportTypes(that) &&
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700819 equalsLinkBandwidths(that) &&
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900820 equalsSignalStrength(that) &&
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700821 equalsSpecifier(that));
Robert Greenwalt1448f052014-04-08 13:41:39 -0700822 }
823
824 @Override
825 public int hashCode() {
826 return ((int)(mNetworkCapabilities & 0xFFFFFFFF) +
827 ((int)(mNetworkCapabilities >> 32) * 3) +
828 ((int)(mTransportTypes & 0xFFFFFFFF) * 5) +
829 ((int)(mTransportTypes >> 32) * 7) +
830 (mLinkUpBandwidthKbps * 11) +
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700831 (mLinkDownBandwidthKbps * 13) +
Etan Cohena7434272017-04-03 12:17:51 -0700832 Objects.hashCode(mNetworkSpecifier) * 17 +
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900833 (mSignalStrength * 19));
Robert Greenwalt1448f052014-04-08 13:41:39 -0700834 }
835
Wink Saville4e2dea72014-09-20 11:04:03 -0700836 @Override
Robert Greenwalt1448f052014-04-08 13:41:39 -0700837 public int describeContents() {
838 return 0;
839 }
Wink Saville4e2dea72014-09-20 11:04:03 -0700840 @Override
Robert Greenwalt1448f052014-04-08 13:41:39 -0700841 public void writeToParcel(Parcel dest, int flags) {
842 dest.writeLong(mNetworkCapabilities);
843 dest.writeLong(mTransportTypes);
844 dest.writeInt(mLinkUpBandwidthKbps);
845 dest.writeInt(mLinkDownBandwidthKbps);
Etan Cohena7434272017-04-03 12:17:51 -0700846 dest.writeParcelable((Parcelable) mNetworkSpecifier, flags);
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900847 dest.writeInt(mSignalStrength);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700848 }
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900849
Robert Greenwalt1448f052014-04-08 13:41:39 -0700850 public static final Creator<NetworkCapabilities> CREATOR =
851 new Creator<NetworkCapabilities>() {
Wink Saville4e2dea72014-09-20 11:04:03 -0700852 @Override
Robert Greenwalt1448f052014-04-08 13:41:39 -0700853 public NetworkCapabilities createFromParcel(Parcel in) {
854 NetworkCapabilities netCap = new NetworkCapabilities();
855
856 netCap.mNetworkCapabilities = in.readLong();
857 netCap.mTransportTypes = in.readLong();
858 netCap.mLinkUpBandwidthKbps = in.readInt();
859 netCap.mLinkDownBandwidthKbps = in.readInt();
Etan Cohena7434272017-04-03 12:17:51 -0700860 netCap.mNetworkSpecifier = in.readParcelable(null);
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900861 netCap.mSignalStrength = in.readInt();
Robert Greenwalt1448f052014-04-08 13:41:39 -0700862 return netCap;
863 }
Wink Saville4e2dea72014-09-20 11:04:03 -0700864 @Override
Robert Greenwalt1448f052014-04-08 13:41:39 -0700865 public NetworkCapabilities[] newArray(int size) {
866 return new NetworkCapabilities[size];
867 }
868 };
869
Wink Saville4e2dea72014-09-20 11:04:03 -0700870 @Override
Robert Greenwalt1448f052014-04-08 13:41:39 -0700871 public String toString() {
Hugo Benichieae7a222017-07-25 11:40:56 +0900872 // TODO: enumerate bits for transports and capabilities instead of creating arrays.
873 // TODO: use a StringBuilder instead of string concatenation.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700874 int[] types = getTransportTypes();
Hugo Benichi5df9d722016-04-25 17:16:35 +0900875 String transports = (types.length > 0) ? " Transports: " + transportNamesOf(types) : "";
Robert Greenwalt1448f052014-04-08 13:41:39 -0700876
Robert Greenwalt7569f182014-06-08 16:42:59 -0700877 types = getCapabilities();
878 String capabilities = (types.length > 0 ? " Capabilities: " : "");
879 for (int i = 0; i < types.length; ) {
Hugo Benichieae7a222017-07-25 11:40:56 +0900880 capabilities += capabilityNameOf(types[i]);
Robert Greenwalt7569f182014-06-08 16:42:59 -0700881 if (++i < types.length) capabilities += "&";
Robert Greenwalt1448f052014-04-08 13:41:39 -0700882 }
883
884 String upBand = ((mLinkUpBandwidthKbps > 0) ? " LinkUpBandwidth>=" +
885 mLinkUpBandwidthKbps + "Kbps" : "");
886 String dnBand = ((mLinkDownBandwidthKbps > 0) ? " LinkDnBandwidth>=" +
887 mLinkDownBandwidthKbps + "Kbps" : "");
888
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700889 String specifier = (mNetworkSpecifier == null ?
890 "" : " Specifier: <" + mNetworkSpecifier + ">");
891
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900892 String signalStrength = (hasSignalStrength() ? " SignalStrength: " + mSignalStrength : "");
893
894 return "[" + transports + capabilities + upBand + dnBand + specifier + signalStrength + "]";
Robert Greenwalt1448f052014-04-08 13:41:39 -0700895 }
Hugo Benichi5df9d722016-04-25 17:16:35 +0900896
897 /**
898 * @hide
899 */
Hugo Benichieae7a222017-07-25 11:40:56 +0900900 public static String capabilityNamesOf(int[] capabilities) {
901 StringJoiner joiner = new StringJoiner("|");
902 if (capabilities != null) {
903 for (int c : capabilities) {
904 joiner.add(capabilityNameOf(c));
905 }
906 }
907 return joiner.toString();
908 }
909
910 /**
911 * @hide
912 */
913 public static String capabilityNameOf(int capability) {
914 switch (capability) {
915 case NET_CAPABILITY_MMS: return "MMS";
916 case NET_CAPABILITY_SUPL: return "SUPL";
917 case NET_CAPABILITY_DUN: return "DUN";
918 case NET_CAPABILITY_FOTA: return "FOTA";
919 case NET_CAPABILITY_IMS: return "IMS";
920 case NET_CAPABILITY_CBS: return "CBS";
921 case NET_CAPABILITY_WIFI_P2P: return "WIFI_P2P";
922 case NET_CAPABILITY_IA: return "IA";
923 case NET_CAPABILITY_RCS: return "RCS";
924 case NET_CAPABILITY_XCAP: return "XCAP";
925 case NET_CAPABILITY_EIMS: return "EIMS";
926 case NET_CAPABILITY_NOT_METERED: return "NOT_METERED";
927 case NET_CAPABILITY_INTERNET: return "INTERNET";
928 case NET_CAPABILITY_NOT_RESTRICTED: return "NOT_RESTRICTED";
929 case NET_CAPABILITY_TRUSTED: return "TRUSTED";
930 case NET_CAPABILITY_NOT_VPN: return "NOT_VPN";
931 case NET_CAPABILITY_VALIDATED: return "VALIDATED";
932 case NET_CAPABILITY_CAPTIVE_PORTAL: return "CAPTIVE_PORTAL";
933 case NET_CAPABILITY_FOREGROUND: return "FOREGROUND";
934 default: return Integer.toString(capability);
935 }
936 }
937
938 /**
939 * @hide
940 */
Hugo Benichi5df9d722016-04-25 17:16:35 +0900941 public static String transportNamesOf(int[] types) {
Hugo Benichieae7a222017-07-25 11:40:56 +0900942 StringJoiner joiner = new StringJoiner("|");
943 if (types != null) {
944 for (int t : types) {
945 joiner.add(transportNameOf(t));
946 }
Hugo Benichi5df9d722016-04-25 17:16:35 +0900947 }
Hugo Benichieae7a222017-07-25 11:40:56 +0900948 return joiner.toString();
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900949 }
950
951 /**
952 * @hide
953 */
954 public static String transportNameOf(int transport) {
Hugo Benichi16f0a942017-06-20 14:07:59 +0900955 if (!isValidTransport(transport)) {
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900956 return "UNKNOWN";
957 }
958 return TRANSPORT_NAMES[transport];
Hugo Benichi5df9d722016-04-25 17:16:35 +0900959 }
Hugo Benichi16f0a942017-06-20 14:07:59 +0900960
961 private static void checkValidTransportType(int transport) {
962 Preconditions.checkArgument(
963 isValidTransport(transport), "Invalid TransportType " + transport);
964 }
Robert Greenwalt1448f052014-04-08 13:41:39 -0700965}