blob: f468e5d2f92b48712cb1a038fc16509bdd28faf0 [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
Jeff Sharkeyde570312017-10-24 21:25:50 -060019import android.annotation.IntDef;
Jeff Sharkey72f9c422017-10-27 17:22:59 -060020import android.net.ConnectivityManager.NetworkCallback;
Robert Greenwalt1448f052014-04-08 13:41:39 -070021import android.os.Parcel;
22import android.os.Parcelable;
Robert Greenwalta7e148a2017-04-10 14:32:23 -070023
24import com.android.internal.annotations.VisibleForTesting;
Hugo Benichi9910dbc2017-03-22 18:29:58 +090025import com.android.internal.util.BitUtils;
Hugo Benichi16f0a942017-06-20 14:07:59 +090026import com.android.internal.util.Preconditions;
Etan Cohena7434272017-04-03 12:17:51 -070027
Jeff Sharkeyde570312017-10-24 21:25:50 -060028import java.lang.annotation.Retention;
29import java.lang.annotation.RetentionPolicy;
Etan Cohena7434272017-04-03 12:17:51 -070030import java.util.Objects;
Hugo Benichieae7a222017-07-25 11:40:56 +090031import java.util.StringJoiner;
Robert Greenwalt1448f052014-04-08 13:41:39 -070032
33/**
Jeff Sharkey49bcd602017-11-09 13:11:50 -070034 * Representation of the capabilities of an active network. Instances are
35 * typically obtained through
Jeff Sharkey72f9c422017-10-27 17:22:59 -060036 * {@link NetworkCallback#onCapabilitiesChanged(Network, NetworkCapabilities)}
37 * or {@link ConnectivityManager#getNetworkCapabilities(Network)}.
Jeff Sharkey72f9c422017-10-27 17:22:59 -060038 * <p>
39 * This replaces the old {@link ConnectivityManager#TYPE_MOBILE} method of
40 * network selection. Rather than indicate a need for Wi-Fi because an
41 * application needs high bandwidth and risk obsolescence when a new, fast
42 * network appears (like LTE), the application should specify it needs high
43 * bandwidth. Similarly if an application needs an unmetered network for a bulk
44 * transfer it can specify that rather than assuming all cellular based
45 * connections are metered and all Wi-Fi based connections are not.
Robert Greenwalt1448f052014-04-08 13:41:39 -070046 */
47public final class NetworkCapabilities implements Parcelable {
Etan Cohena7434272017-04-03 12:17:51 -070048 private static final String TAG = "NetworkCapabilities";
49
Robert Greenwalt7569f182014-06-08 16:42:59 -070050 /**
51 * @hide
52 */
Robert Greenwalt01d004e2014-05-18 15:24:21 -070053 public NetworkCapabilities() {
Lorenzo Colittif7058f52015-04-27 11:31:55 +090054 clearAll();
Lorenzo Colitti260a36d2015-07-08 12:49:04 +090055 mNetworkCapabilities = DEFAULT_CAPABILITIES;
Robert Greenwalt01d004e2014-05-18 15:24:21 -070056 }
57
58 public NetworkCapabilities(NetworkCapabilities nc) {
59 if (nc != null) {
60 mNetworkCapabilities = nc.mNetworkCapabilities;
61 mTransportTypes = nc.mTransportTypes;
62 mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps;
63 mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
Robert Greenwalt94badcc2014-07-10 14:53:24 -070064 mNetworkSpecifier = nc.mNetworkSpecifier;
Lorenzo Colittic3f21f32015-07-06 23:50:27 +090065 mSignalStrength = nc.mSignalStrength;
Robert Greenwalt01d004e2014-05-18 15:24:21 -070066 }
67 }
Robert Greenwalt1448f052014-04-08 13:41:39 -070068
69 /**
Lorenzo Colittif7058f52015-04-27 11:31:55 +090070 * Completely clears the contents of this object, removing even the capabilities that are set
71 * by default when the object is constructed.
72 * @hide
73 */
74 public void clearAll() {
75 mNetworkCapabilities = mTransportTypes = 0;
Jeff Sharkey49bcd602017-11-09 13:11:50 -070076 mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
Lorenzo Colittif7058f52015-04-27 11:31:55 +090077 mNetworkSpecifier = null;
Lorenzo Colittic3f21f32015-07-06 23:50:27 +090078 mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
Lorenzo Colittif7058f52015-04-27 11:31:55 +090079 }
80
81 /**
Robert Greenwalt1448f052014-04-08 13:41:39 -070082 * Represents the network's capabilities. If any are specified they will be satisfied
83 * by any Network that matches all of them.
84 */
Lorenzo Colittif7058f52015-04-27 11:31:55 +090085 private long mNetworkCapabilities;
Robert Greenwalt1448f052014-04-08 13:41:39 -070086
Jeff Sharkeyde570312017-10-24 21:25:50 -060087 /** @hide */
88 @Retention(RetentionPolicy.SOURCE)
89 @IntDef(prefix = { "NET_CAPABILITY_" }, value = {
90 NET_CAPABILITY_MMS,
91 NET_CAPABILITY_SUPL,
92 NET_CAPABILITY_DUN,
93 NET_CAPABILITY_FOTA,
94 NET_CAPABILITY_IMS,
95 NET_CAPABILITY_CBS,
96 NET_CAPABILITY_WIFI_P2P,
97 NET_CAPABILITY_IA,
98 NET_CAPABILITY_RCS,
99 NET_CAPABILITY_XCAP,
100 NET_CAPABILITY_EIMS,
101 NET_CAPABILITY_NOT_METERED,
102 NET_CAPABILITY_INTERNET,
103 NET_CAPABILITY_NOT_RESTRICTED,
104 NET_CAPABILITY_TRUSTED,
105 NET_CAPABILITY_NOT_VPN,
106 NET_CAPABILITY_VALIDATED,
107 NET_CAPABILITY_CAPTIVE_PORTAL,
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600108 NET_CAPABILITY_NOT_ROAMING,
Jeff Sharkeyde570312017-10-24 21:25:50 -0600109 NET_CAPABILITY_FOREGROUND,
110 })
111 public @interface NetCapability { }
112
Robert Greenwalt1448f052014-04-08 13:41:39 -0700113 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700114 * Indicates this is a network that has the ability to reach the
115 * carrier's MMSC for sending and receiving MMS messages.
Robert Greenwalt1448f052014-04-08 13:41:39 -0700116 */
117 public static final int NET_CAPABILITY_MMS = 0;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700118
119 /**
120 * Indicates this is a network that has the ability to reach the carrier's
121 * SUPL server, used to retrieve GPS information.
122 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700123 public static final int NET_CAPABILITY_SUPL = 1;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700124
125 /**
126 * Indicates this is a network that has the ability to reach the carrier's
127 * DUN or tethering gateway.
128 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700129 public static final int NET_CAPABILITY_DUN = 2;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700130
131 /**
132 * Indicates this is a network that has the ability to reach the carrier's
133 * FOTA portal, used for over the air updates.
134 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700135 public static final int NET_CAPABILITY_FOTA = 3;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700136
137 /**
138 * Indicates this is a network that has the ability to reach the carrier's
139 * IMS servers, used for network registration and signaling.
140 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700141 public static final int NET_CAPABILITY_IMS = 4;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700142
143 /**
144 * Indicates this is a network that has the ability to reach the carrier's
145 * CBS servers, used for carrier specific services.
146 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700147 public static final int NET_CAPABILITY_CBS = 5;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700148
149 /**
150 * Indicates this is a network that has the ability to reach a Wi-Fi direct
151 * peer.
152 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700153 public static final int NET_CAPABILITY_WIFI_P2P = 6;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700154
155 /**
156 * Indicates this is a network that has the ability to reach a carrier's
157 * Initial Attach servers.
158 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700159 public static final int NET_CAPABILITY_IA = 7;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700160
161 /**
162 * Indicates this is a network that has the ability to reach a carrier's
163 * RCS servers, used for Rich Communication Services.
164 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700165 public static final int NET_CAPABILITY_RCS = 8;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700166
167 /**
168 * Indicates this is a network that has the ability to reach a carrier's
169 * XCAP servers, used for configuration and control.
170 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700171 public static final int NET_CAPABILITY_XCAP = 9;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700172
173 /**
174 * Indicates this is a network that has the ability to reach a carrier's
Robert Greenwalt4bd43892015-07-09 14:49:35 -0700175 * Emergency IMS servers or other services, used for network signaling
176 * during emergency calls.
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700177 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700178 public static final int NET_CAPABILITY_EIMS = 10;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700179
180 /**
181 * Indicates that this network is unmetered.
182 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700183 public static final int NET_CAPABILITY_NOT_METERED = 11;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700184
185 /**
186 * Indicates that this network should be able to reach the internet.
187 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700188 public static final int NET_CAPABILITY_INTERNET = 12;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700189
190 /**
191 * Indicates that this network is available for general use. If this is not set
192 * applications should not attempt to communicate on this network. Note that this
193 * is simply informative and not enforcement - enforcement is handled via other means.
194 * Set by default.
195 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700196 public static final int NET_CAPABILITY_NOT_RESTRICTED = 13;
197
Robert Greenwalt16e12ab2014-07-08 15:31:37 -0700198 /**
199 * Indicates that the user has indicated implicit trust of this network. This
200 * generally means it's a sim-selected carrier, a plugged in ethernet, a paired
201 * BT device or a wifi the user asked to connect to. Untrusted networks
202 * are probably limited to unknown wifi AP. Set by default.
203 */
204 public static final int NET_CAPABILITY_TRUSTED = 14;
205
Paul Jensen76b610a2015-03-18 09:33:07 -0400206 /**
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400207 * Indicates that this network is not a VPN. This capability is set by default and should be
Paul Jensen76b610a2015-03-18 09:33:07 -0400208 * explicitly cleared for VPN networks.
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400209 */
210 public static final int NET_CAPABILITY_NOT_VPN = 15;
211
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900212 /**
213 * Indicates that connectivity on this network was successfully validated. For example, for a
214 * network with NET_CAPABILITY_INTERNET, it means that Internet connectivity was successfully
215 * detected.
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900216 */
217 public static final int NET_CAPABILITY_VALIDATED = 16;
Robert Greenwalt16e12ab2014-07-08 15:31:37 -0700218
Paul Jensen3d194ea2015-06-16 14:27:36 -0400219 /**
220 * Indicates that this network was found to have a captive portal in place last time it was
221 * probed.
222 */
223 public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17;
224
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900225 /**
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600226 * Indicates that this network is not roaming.
227 */
228 public static final int NET_CAPABILITY_NOT_ROAMING = 18;
229
230 /**
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900231 * Indicates that this network is available for use by apps, and not a network that is being
232 * kept up in the background to facilitate fast network switching.
233 * @hide
234 */
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600235 public static final int NET_CAPABILITY_FOREGROUND = 19;
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900236
Robert Greenwalt1448f052014-04-08 13:41:39 -0700237 private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900238 private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_FOREGROUND;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700239
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700240 /**
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900241 * Network capabilities that are expected to be mutable, i.e., can change while a particular
242 * network is connected.
243 */
244 private static final long MUTABLE_CAPABILITIES =
245 // TRUSTED can change when user explicitly connects to an untrusted network in Settings.
246 // http://b/18206275
247 (1 << NET_CAPABILITY_TRUSTED) |
248 (1 << NET_CAPABILITY_VALIDATED) |
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900249 (1 << NET_CAPABILITY_CAPTIVE_PORTAL) |
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600250 (1 << NET_CAPABILITY_NOT_ROAMING) |
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900251 (1 << NET_CAPABILITY_FOREGROUND);
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900252
253 /**
254 * Network capabilities that are not allowed in NetworkRequests. This exists because the
255 * NetworkFactory / NetworkAgent model does not deal well with the situation where a
256 * capability's presence cannot be known in advance. If such a capability is requested, then we
257 * can get into a cycle where the NetworkFactory endlessly churns out NetworkAgents that then
258 * get immediately torn down because they do not have the requested capability.
259 */
260 private static final long NON_REQUESTABLE_CAPABILITIES =
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900261 MUTABLE_CAPABILITIES & ~(1 << NET_CAPABILITY_TRUSTED);
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900262
263 /**
264 * Capabilities that are set by default when the object is constructed.
265 */
266 private static final long DEFAULT_CAPABILITIES =
267 (1 << NET_CAPABILITY_NOT_RESTRICTED) |
268 (1 << NET_CAPABILITY_TRUSTED) |
269 (1 << NET_CAPABILITY_NOT_VPN);
270
271 /**
Paul Jensen487ffe72015-07-24 15:57:11 -0400272 * Capabilities that suggest that a network is restricted.
273 * {@see #maybeMarkCapabilitiesRestricted}.
274 */
Robert Greenwalta7e148a2017-04-10 14:32:23 -0700275 @VisibleForTesting
276 /* package */ static final long RESTRICTED_CAPABILITIES =
Paul Jensen487ffe72015-07-24 15:57:11 -0400277 (1 << NET_CAPABILITY_CBS) |
278 (1 << NET_CAPABILITY_DUN) |
279 (1 << NET_CAPABILITY_EIMS) |
280 (1 << NET_CAPABILITY_FOTA) |
281 (1 << NET_CAPABILITY_IA) |
282 (1 << NET_CAPABILITY_IMS) |
283 (1 << NET_CAPABILITY_RCS) |
284 (1 << NET_CAPABILITY_XCAP);
285
286 /**
Robert Greenwalta7e148a2017-04-10 14:32:23 -0700287 * Capabilities that suggest that a network is unrestricted.
288 * {@see #maybeMarkCapabilitiesRestricted}.
289 */
290 @VisibleForTesting
291 /* package */ static final long UNRESTRICTED_CAPABILITIES =
292 (1 << NET_CAPABILITY_INTERNET) |
293 (1 << NET_CAPABILITY_MMS) |
294 (1 << NET_CAPABILITY_SUPL) |
295 (1 << NET_CAPABILITY_WIFI_P2P);
296
297 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700298 * Adds the given capability to this {@code NetworkCapability} instance.
299 * Multiple capabilities may be applied sequentially. Note that when searching
300 * for a network to satisfy a request, all capabilities requested must be satisfied.
301 *
Jeff Sharkeyde570312017-10-24 21:25:50 -0600302 * @param capability the capability to be added.
Pierre Imaic8419a82016-03-22 17:54:54 +0900303 * @return This NetworkCapabilities instance, to facilitate chaining.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700304 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700305 */
Jeff Sharkeyde570312017-10-24 21:25:50 -0600306 public NetworkCapabilities addCapability(@NetCapability int capability) {
Robert Greenwalt7569f182014-06-08 16:42:59 -0700307 if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700308 throw new IllegalArgumentException("NetworkCapability out of range");
309 }
Robert Greenwalt7569f182014-06-08 16:42:59 -0700310 mNetworkCapabilities |= 1 << capability;
311 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700312 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700313
314 /**
315 * Removes (if found) the given capability from this {@code NetworkCapability} instance.
316 *
Jeff Sharkeyde570312017-10-24 21:25:50 -0600317 * @param capability the capability to be removed.
Pierre Imaic8419a82016-03-22 17:54:54 +0900318 * @return This NetworkCapabilities instance, to facilitate chaining.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700319 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700320 */
Jeff Sharkeyde570312017-10-24 21:25:50 -0600321 public NetworkCapabilities removeCapability(@NetCapability int capability) {
Robert Greenwalt7569f182014-06-08 16:42:59 -0700322 if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700323 throw new IllegalArgumentException("NetworkCapability out of range");
324 }
Robert Greenwalt7569f182014-06-08 16:42:59 -0700325 mNetworkCapabilities &= ~(1 << capability);
326 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700327 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700328
329 /**
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600330 * Sets (or clears) the given capability on this {@link NetworkCapabilities}
331 * instance.
332 *
333 * @hide
334 */
335 public NetworkCapabilities setCapability(@NetCapability int capability, boolean value) {
336 if (value) {
337 addCapability(capability);
338 } else {
339 removeCapability(capability);
340 }
341 return this;
342 }
343
344 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700345 * Gets all the capabilities set on this {@code NetworkCapability} instance.
346 *
Jeff Sharkeyde570312017-10-24 21:25:50 -0600347 * @return an array of capability values for this instance.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700348 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700349 */
Jeff Sharkeyde570312017-10-24 21:25:50 -0600350 public @NetCapability int[] getCapabilities() {
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900351 return BitUtils.unpackBits(mNetworkCapabilities);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700352 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700353
354 /**
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600355 * Sets all the capabilities set on this {@code NetworkCapability} instance.
Jeff Sharkey49bcd602017-11-09 13:11:50 -0700356 * This overwrites any existing capabilities.
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600357 *
358 * @hide
359 */
360 public void setCapabilities(@NetCapability int[] capabilities) {
361 mNetworkCapabilities = BitUtils.packBits(capabilities);
362 }
363
364 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700365 * Tests for the presence of a capabilitity on this instance.
366 *
Jeff Sharkeyde570312017-10-24 21:25:50 -0600367 * @param capability the capabilities to be tested for.
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700368 * @return {@code true} if set on this instance.
369 */
Jeff Sharkeyde570312017-10-24 21:25:50 -0600370 public boolean hasCapability(@NetCapability int capability) {
Robert Greenwalt7569f182014-06-08 16:42:59 -0700371 if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
Robert Greenwalt5c55e332014-05-08 00:02:04 -0700372 return false;
373 }
Robert Greenwalt7569f182014-06-08 16:42:59 -0700374 return ((mNetworkCapabilities & (1 << capability)) != 0);
Robert Greenwalt5c55e332014-05-08 00:02:04 -0700375 }
Robert Greenwalt1448f052014-04-08 13:41:39 -0700376
Robert Greenwalt1448f052014-04-08 13:41:39 -0700377 private void combineNetCapabilities(NetworkCapabilities nc) {
378 this.mNetworkCapabilities |= nc.mNetworkCapabilities;
379 }
380
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900381 /**
382 * Convenience function that returns a human-readable description of the first mutable
383 * capability we find. Used to present an error message to apps that request mutable
384 * capabilities.
385 *
386 * @hide
387 */
388 public String describeFirstNonRequestableCapability() {
389 if (hasCapability(NET_CAPABILITY_VALIDATED)) return "NET_CAPABILITY_VALIDATED";
390 if (hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return "NET_CAPABILITY_CAPTIVE_PORTAL";
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900391 if (hasCapability(NET_CAPABILITY_FOREGROUND)) return "NET_CAPABILITY_FOREGROUND";
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900392 // This cannot happen unless the preceding checks are incomplete.
393 if ((mNetworkCapabilities & NON_REQUESTABLE_CAPABILITIES) != 0) {
394 return "unknown non-requestable capabilities " + Long.toHexString(mNetworkCapabilities);
395 }
396 if (mLinkUpBandwidthKbps != 0 || mLinkDownBandwidthKbps != 0) return "link bandwidth";
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900397 if (hasSignalStrength()) return "signalStrength";
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900398 return null;
399 }
400
401 private boolean satisfiedByNetCapabilities(NetworkCapabilities nc, boolean onlyImmutable) {
402 long networkCapabilities = this.mNetworkCapabilities;
403 if (onlyImmutable) {
404 networkCapabilities = networkCapabilities & ~MUTABLE_CAPABILITIES;
405 }
406 return ((nc.mNetworkCapabilities & networkCapabilities) == networkCapabilities);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700407 }
408
Robert Greenwalt06314e42014-10-29 14:04:06 -0700409 /** @hide */
410 public boolean equalsNetCapabilities(NetworkCapabilities nc) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700411 return (nc.mNetworkCapabilities == this.mNetworkCapabilities);
412 }
413
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900414 private boolean equalsNetCapabilitiesRequestable(NetworkCapabilities that) {
415 return ((this.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) ==
416 (that.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES));
417 }
418
Robert Greenwalt1448f052014-04-08 13:41:39 -0700419 /**
Paul Jensen487ffe72015-07-24 15:57:11 -0400420 * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if all the capabilities it provides are
421 * typically provided by restricted networks.
422 *
423 * TODO: consider:
424 * - Renaming it to guessRestrictedCapability and make it set the
425 * restricted capability bit in addition to clearing it.
426 * @hide
427 */
428 public void maybeMarkCapabilitiesRestricted() {
Robert Greenwalta7e148a2017-04-10 14:32:23 -0700429 // Verify there aren't any unrestricted capabilities. If there are we say
430 // the whole thing is unrestricted.
431 final boolean hasUnrestrictedCapabilities =
432 ((mNetworkCapabilities & UNRESTRICTED_CAPABILITIES) != 0);
433
434 // Must have at least some restricted capabilities.
435 final boolean hasRestrictedCapabilities =
436 ((mNetworkCapabilities & RESTRICTED_CAPABILITIES) != 0);
437
438 if (hasRestrictedCapabilities && !hasUnrestrictedCapabilities) {
Paul Jensen487ffe72015-07-24 15:57:11 -0400439 removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
Paul Jensenaae613d2015-08-19 11:06:15 -0400440 }
Paul Jensen487ffe72015-07-24 15:57:11 -0400441 }
442
443 /**
Robert Greenwalt1448f052014-04-08 13:41:39 -0700444 * Representing the transport type. Apps should generally not care about transport. A
445 * request for a fast internet connection could be satisfied by a number of different
446 * transports. If any are specified here it will be satisfied a Network that matches
447 * any of them. If a caller doesn't care about the transport it should not specify any.
448 */
449 private long mTransportTypes;
450
Jeff Sharkeyde570312017-10-24 21:25:50 -0600451 /** @hide */
452 @Retention(RetentionPolicy.SOURCE)
453 @IntDef(prefix = { "TRANSPORT_" }, value = {
454 TRANSPORT_CELLULAR,
455 TRANSPORT_WIFI,
456 TRANSPORT_BLUETOOTH,
457 TRANSPORT_ETHERNET,
458 TRANSPORT_VPN,
459 TRANSPORT_WIFI_AWARE,
460 TRANSPORT_LOWPAN,
461 })
462 public @interface Transport { }
463
Robert Greenwalt1448f052014-04-08 13:41:39 -0700464 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700465 * Indicates this network uses a Cellular transport.
Robert Greenwalt1448f052014-04-08 13:41:39 -0700466 */
467 public static final int TRANSPORT_CELLULAR = 0;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700468
469 /**
470 * Indicates this network uses a Wi-Fi transport.
471 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700472 public static final int TRANSPORT_WIFI = 1;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700473
474 /**
475 * Indicates this network uses a Bluetooth transport.
476 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700477 public static final int TRANSPORT_BLUETOOTH = 2;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700478
479 /**
480 * Indicates this network uses an Ethernet transport.
481 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700482 public static final int TRANSPORT_ETHERNET = 3;
483
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400484 /**
485 * Indicates this network uses a VPN transport.
486 */
487 public static final int TRANSPORT_VPN = 4;
488
Etan Cohen305ea282016-06-20 09:27:12 -0700489 /**
Etan Cohen0849ded2016-10-26 11:22:06 -0700490 * Indicates this network uses a Wi-Fi Aware transport.
Etan Cohen305ea282016-06-20 09:27:12 -0700491 */
Etan Cohen0849ded2016-10-26 11:22:06 -0700492 public static final int TRANSPORT_WIFI_AWARE = 5;
Etan Cohen305ea282016-06-20 09:27:12 -0700493
Robert Quattlebaum5f915762017-05-15 15:53:29 -0700494 /**
495 * Indicates this network uses a LoWPAN transport.
Robert Quattlebaum5f915762017-05-15 15:53:29 -0700496 */
497 public static final int TRANSPORT_LOWPAN = 6;
498
Hugo Benichi6a9bb8e2017-03-15 23:05:01 +0900499 /** @hide */
500 public static final int MIN_TRANSPORT = TRANSPORT_CELLULAR;
501 /** @hide */
Robert Quattlebaum5f915762017-05-15 15:53:29 -0700502 public static final int MAX_TRANSPORT = TRANSPORT_LOWPAN;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700503
Hugo Benichi16f0a942017-06-20 14:07:59 +0900504 /** @hide */
Jeff Sharkeyde570312017-10-24 21:25:50 -0600505 public static boolean isValidTransport(@Transport int transportType) {
Hugo Benichi16f0a942017-06-20 14:07:59 +0900506 return (MIN_TRANSPORT <= transportType) && (transportType <= MAX_TRANSPORT);
507 }
508
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900509 private static final String[] TRANSPORT_NAMES = {
510 "CELLULAR",
511 "WIFI",
512 "BLUETOOTH",
513 "ETHERNET",
514 "VPN",
Robert Quattlebaum5f915762017-05-15 15:53:29 -0700515 "WIFI_AWARE",
516 "LOWPAN"
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900517 };
518
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700519 /**
520 * Adds the given transport type to this {@code NetworkCapability} instance.
521 * Multiple transports may be applied sequentially. Note that when searching
522 * for a network to satisfy a request, any listed in the request will satisfy the request.
523 * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a
524 * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network
525 * to be selected. This is logically different than
526 * {@code NetworkCapabilities.NET_CAPABILITY_*} listed above.
527 *
Jeff Sharkeyde570312017-10-24 21:25:50 -0600528 * @param transportType the transport type to be added.
Pierre Imaic8419a82016-03-22 17:54:54 +0900529 * @return This NetworkCapabilities instance, to facilitate chaining.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700530 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700531 */
Jeff Sharkeyde570312017-10-24 21:25:50 -0600532 public NetworkCapabilities addTransportType(@Transport int transportType) {
Hugo Benichi16f0a942017-06-20 14:07:59 +0900533 checkValidTransportType(transportType);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700534 mTransportTypes |= 1 << transportType;
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700535 setNetworkSpecifier(mNetworkSpecifier); // used for exception checking
Robert Greenwalt7569f182014-06-08 16:42:59 -0700536 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700537 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700538
539 /**
540 * Removes (if found) the given transport from this {@code NetworkCapability} instance.
541 *
Jeff Sharkeyde570312017-10-24 21:25:50 -0600542 * @param transportType the transport type to be removed.
Pierre Imaic8419a82016-03-22 17:54:54 +0900543 * @return This NetworkCapabilities instance, to facilitate chaining.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700544 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700545 */
Jeff Sharkeyde570312017-10-24 21:25:50 -0600546 public NetworkCapabilities removeTransportType(@Transport int transportType) {
Hugo Benichi16f0a942017-06-20 14:07:59 +0900547 checkValidTransportType(transportType);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700548 mTransportTypes &= ~(1 << transportType);
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700549 setNetworkSpecifier(mNetworkSpecifier); // used for exception checking
Robert Greenwalt7569f182014-06-08 16:42:59 -0700550 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700551 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700552
553 /**
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600554 * Sets (or clears) the given transport on this {@link NetworkCapabilities}
555 * instance.
556 *
557 * @hide
558 */
559 public NetworkCapabilities setTransportType(@Transport int transportType, boolean value) {
560 if (value) {
561 addTransportType(transportType);
562 } else {
563 removeTransportType(transportType);
564 }
565 return this;
566 }
567
568 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700569 * Gets all the transports set on this {@code NetworkCapability} instance.
570 *
Jeff Sharkeyde570312017-10-24 21:25:50 -0600571 * @return an array of transport type values for this instance.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700572 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700573 */
Jeff Sharkeyde570312017-10-24 21:25:50 -0600574 public @Transport int[] getTransportTypes() {
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900575 return BitUtils.unpackBits(mTransportTypes);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700576 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700577
578 /**
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600579 * Sets all the transports set on this {@code NetworkCapability} instance.
Jeff Sharkey49bcd602017-11-09 13:11:50 -0700580 * This overwrites any existing transports.
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600581 *
582 * @hide
583 */
584 public void setTransportTypes(@Transport int[] transportTypes) {
585 mTransportTypes = BitUtils.packBits(transportTypes);
586 }
587
588 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700589 * Tests for the presence of a transport on this instance.
590 *
Jeff Sharkeyde570312017-10-24 21:25:50 -0600591 * @param transportType the transport type to be tested for.
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700592 * @return {@code true} if set on this instance.
593 */
Jeff Sharkeyde570312017-10-24 21:25:50 -0600594 public boolean hasTransport(@Transport int transportType) {
Hugo Benichi16f0a942017-06-20 14:07:59 +0900595 return isValidTransport(transportType) && ((mTransportTypes & (1 << transportType)) != 0);
Robert Greenwalt5c55e332014-05-08 00:02:04 -0700596 }
Robert Greenwalt1448f052014-04-08 13:41:39 -0700597
598 private void combineTransportTypes(NetworkCapabilities nc) {
599 this.mTransportTypes |= nc.mTransportTypes;
600 }
Hugo Benichieae7a222017-07-25 11:40:56 +0900601
Robert Greenwalt1448f052014-04-08 13:41:39 -0700602 private boolean satisfiedByTransportTypes(NetworkCapabilities nc) {
603 return ((this.mTransportTypes == 0) ||
604 ((this.mTransportTypes & nc.mTransportTypes) != 0));
605 }
Hugo Benichieae7a222017-07-25 11:40:56 +0900606
Robert Greenwalt06314e42014-10-29 14:04:06 -0700607 /** @hide */
608 public boolean equalsTransportTypes(NetworkCapabilities nc) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700609 return (nc.mTransportTypes == this.mTransportTypes);
610 }
611
612 /**
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600613 * Value indicating that link bandwidth is unspecified.
614 * @hide
615 */
616 public static final int LINK_BANDWIDTH_UNSPECIFIED = 0;
617
618 /**
Robert Greenwalt1448f052014-04-08 13:41:39 -0700619 * Passive link bandwidth. This is a rough guide of the expected peak bandwidth
620 * for the first hop on the given transport. It is not measured, but may take into account
621 * link parameters (Radio technology, allocated channels, etc).
622 */
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600623 private int mLinkUpBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
624 private int mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700625
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700626 /**
627 * Sets the upstream bandwidth for this network in Kbps. This always only refers to
628 * the estimated first hop transport bandwidth.
629 * <p>
630 * Note that when used to request a network, this specifies the minimum acceptable.
631 * When received as the state of an existing network this specifies the typical
632 * first hop bandwidth expected. This is never measured, but rather is inferred
633 * from technology type and other link parameters. It could be used to differentiate
634 * between very slow 1xRTT cellular links and other faster networks or even between
635 * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
636 * fast backhauls and slow backhauls.
637 *
638 * @param upKbps the estimated first hop upstream (device to network) bandwidth.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700639 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700640 */
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600641 public NetworkCapabilities setLinkUpstreamBandwidthKbps(int upKbps) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700642 mLinkUpBandwidthKbps = upKbps;
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600643 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700644 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700645
646 /**
647 * Retrieves the upstream bandwidth for this network in Kbps. This always only refers to
648 * the estimated first hop transport bandwidth.
649 *
650 * @return The estimated first hop upstream (device to network) bandwidth.
651 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700652 public int getLinkUpstreamBandwidthKbps() {
653 return mLinkUpBandwidthKbps;
654 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700655
656 /**
657 * Sets the downstream bandwidth for this network in Kbps. This always only refers to
658 * the estimated first hop transport bandwidth.
659 * <p>
660 * Note that when used to request a network, this specifies the minimum acceptable.
661 * When received as the state of an existing network this specifies the typical
662 * first hop bandwidth expected. This is never measured, but rather is inferred
663 * from technology type and other link parameters. It could be used to differentiate
664 * between very slow 1xRTT cellular links and other faster networks or even between
665 * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
666 * fast backhauls and slow backhauls.
667 *
668 * @param downKbps the estimated first hop downstream (network to device) bandwidth.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700669 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700670 */
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600671 public NetworkCapabilities setLinkDownstreamBandwidthKbps(int downKbps) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700672 mLinkDownBandwidthKbps = downKbps;
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600673 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700674 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700675
676 /**
677 * Retrieves the downstream bandwidth for this network in Kbps. This always only refers to
678 * the estimated first hop transport bandwidth.
679 *
680 * @return The estimated first hop downstream (network to device) bandwidth.
681 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700682 public int getLinkDownstreamBandwidthKbps() {
683 return mLinkDownBandwidthKbps;
684 }
685
686 private void combineLinkBandwidths(NetworkCapabilities nc) {
687 this.mLinkUpBandwidthKbps =
688 Math.max(this.mLinkUpBandwidthKbps, nc.mLinkUpBandwidthKbps);
689 this.mLinkDownBandwidthKbps =
690 Math.max(this.mLinkDownBandwidthKbps, nc.mLinkDownBandwidthKbps);
691 }
692 private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) {
693 return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps ||
694 this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps);
695 }
696 private boolean equalsLinkBandwidths(NetworkCapabilities nc) {
697 return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps &&
698 this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
699 }
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600700 /** @hide */
701 public static int minBandwidth(int a, int b) {
702 if (a == LINK_BANDWIDTH_UNSPECIFIED) {
703 return b;
704 } else if (b == LINK_BANDWIDTH_UNSPECIFIED) {
705 return a;
706 } else {
707 return Math.min(a, b);
708 }
709 }
710 /** @hide */
711 public static int maxBandwidth(int a, int b) {
712 return Math.max(a, b);
713 }
Robert Greenwalt1448f052014-04-08 13:41:39 -0700714
Etan Cohena7434272017-04-03 12:17:51 -0700715 private NetworkSpecifier mNetworkSpecifier = null;
716
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700717 /**
718 * Sets the optional bearer specific network specifier.
719 * This has no meaning if a single transport is also not specified, so calling
720 * this without a single transport set will generate an exception, as will
721 * subsequently adding or removing transports after this is set.
722 * </p>
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700723 *
Etan Cohena7434272017-04-03 12:17:51 -0700724 * @param networkSpecifier A concrete, parcelable framework class that extends
725 * NetworkSpecifier.
Pierre Imaic8419a82016-03-22 17:54:54 +0900726 * @return This NetworkCapabilities instance, to facilitate chaining.
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700727 * @hide
728 */
Etan Cohena7434272017-04-03 12:17:51 -0700729 public NetworkCapabilities setNetworkSpecifier(NetworkSpecifier networkSpecifier) {
730 if (networkSpecifier != null && Long.bitCount(mTransportTypes) != 1) {
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700731 throw new IllegalStateException("Must have a single transport specified to use " +
732 "setNetworkSpecifier");
733 }
Etan Cohena7434272017-04-03 12:17:51 -0700734
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700735 mNetworkSpecifier = networkSpecifier;
Etan Cohena7434272017-04-03 12:17:51 -0700736
Pierre Imaic8419a82016-03-22 17:54:54 +0900737 return this;
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700738 }
739
740 /**
741 * Gets the optional bearer specific network specifier.
742 *
Etan Cohena7434272017-04-03 12:17:51 -0700743 * @return The optional {@link NetworkSpecifier} specifying the bearer specific network
744 * specifier. See {@link #setNetworkSpecifier}.
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700745 * @hide
746 */
Etan Cohena7434272017-04-03 12:17:51 -0700747 public NetworkSpecifier getNetworkSpecifier() {
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700748 return mNetworkSpecifier;
749 }
750
751 private void combineSpecifiers(NetworkCapabilities nc) {
Etan Cohena7434272017-04-03 12:17:51 -0700752 if (mNetworkSpecifier != null && !mNetworkSpecifier.equals(nc.mNetworkSpecifier)) {
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700753 throw new IllegalStateException("Can't combine two networkSpecifiers");
754 }
Etan Cohena7434272017-04-03 12:17:51 -0700755 setNetworkSpecifier(nc.mNetworkSpecifier);
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700756 }
Etan Cohena7434272017-04-03 12:17:51 -0700757
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700758 private boolean satisfiedBySpecifier(NetworkCapabilities nc) {
Etan Cohena7434272017-04-03 12:17:51 -0700759 return mNetworkSpecifier == null || mNetworkSpecifier.satisfiedBy(nc.mNetworkSpecifier)
760 || nc.mNetworkSpecifier instanceof MatchAllNetworkSpecifier;
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700761 }
Etan Cohena7434272017-04-03 12:17:51 -0700762
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700763 private boolean equalsSpecifier(NetworkCapabilities nc) {
Etan Cohena7434272017-04-03 12:17:51 -0700764 return Objects.equals(mNetworkSpecifier, nc.mNetworkSpecifier);
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700765 }
766
Robert Greenwalt1448f052014-04-08 13:41:39 -0700767 /**
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900768 * Magic value that indicates no signal strength provided. A request specifying this value is
769 * always satisfied.
770 *
771 * @hide
772 */
773 public static final int SIGNAL_STRENGTH_UNSPECIFIED = Integer.MIN_VALUE;
774
775 /**
776 * Signal strength. This is a signed integer, and higher values indicate better signal.
777 * The exact units are bearer-dependent. For example, Wi-Fi uses RSSI.
778 */
Jeff Sharkey49bcd602017-11-09 13:11:50 -0700779 private int mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900780
781 /**
782 * Sets the signal strength. This is a signed integer, with higher values indicating a stronger
783 * signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same RSSI units
784 * reported by WifiManager.
785 * <p>
786 * Note that when used to register a network callback, this specifies the minimum acceptable
787 * signal strength. When received as the state of an existing network it specifies the current
788 * value. A value of code SIGNAL_STRENGTH_UNSPECIFIED} means no value when received and has no
789 * effect when requesting a callback.
790 *
791 * @param signalStrength the bearer-specific signal strength.
792 * @hide
793 */
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600794 public NetworkCapabilities setSignalStrength(int signalStrength) {
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900795 mSignalStrength = signalStrength;
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600796 return this;
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900797 }
798
799 /**
800 * Returns {@code true} if this object specifies a signal strength.
801 *
802 * @hide
803 */
804 public boolean hasSignalStrength() {
805 return mSignalStrength > SIGNAL_STRENGTH_UNSPECIFIED;
806 }
807
808 /**
809 * Retrieves the signal strength.
810 *
811 * @return The bearer-specific signal strength.
812 * @hide
813 */
814 public int getSignalStrength() {
815 return mSignalStrength;
816 }
817
818 private void combineSignalStrength(NetworkCapabilities nc) {
819 this.mSignalStrength = Math.max(this.mSignalStrength, nc.mSignalStrength);
820 }
821
822 private boolean satisfiedBySignalStrength(NetworkCapabilities nc) {
823 return this.mSignalStrength <= nc.mSignalStrength;
824 }
825
826 private boolean equalsSignalStrength(NetworkCapabilities nc) {
827 return this.mSignalStrength == nc.mSignalStrength;
828 }
829
830 /**
Robert Greenwalt1448f052014-04-08 13:41:39 -0700831 * Combine a set of Capabilities to this one. Useful for coming up with the complete set
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900832 * @hide
Robert Greenwalt1448f052014-04-08 13:41:39 -0700833 */
834 public void combineCapabilities(NetworkCapabilities nc) {
835 combineNetCapabilities(nc);
836 combineTransportTypes(nc);
837 combineLinkBandwidths(nc);
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700838 combineSpecifiers(nc);
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900839 combineSignalStrength(nc);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700840 }
841
842 /**
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900843 * Check if our requirements are satisfied by the given {@code NetworkCapabilities}.
844 *
845 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
846 * @param onlyImmutable if {@code true}, do not consider mutable requirements such as link
847 * bandwidth, signal strength, or validation / captive portal status.
848 *
849 * @hide
850 */
851 private boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc, boolean onlyImmutable) {
852 return (nc != null &&
853 satisfiedByNetCapabilities(nc, onlyImmutable) &&
854 satisfiedByTransportTypes(nc) &&
855 (onlyImmutable || satisfiedByLinkBandwidths(nc)) &&
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900856 satisfiedBySpecifier(nc) &&
857 (onlyImmutable || satisfiedBySignalStrength(nc)));
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900858 }
859
860 /**
861 * Check if our requirements are satisfied by the given {@code NetworkCapabilities}.
862 *
863 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
864 *
865 * @hide
Robert Greenwalt1448f052014-04-08 13:41:39 -0700866 */
867 public boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc) {
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900868 return satisfiedByNetworkCapabilities(nc, false);
869 }
870
871 /**
872 * Check if our immutable requirements are satisfied by the given {@code NetworkCapabilities}.
873 *
874 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
875 *
876 * @hide
877 */
878 public boolean satisfiedByImmutableNetworkCapabilities(NetworkCapabilities nc) {
879 return satisfiedByNetworkCapabilities(nc, true);
880 }
881
882 /**
883 * Checks that our immutable capabilities are the same as those of the given
Hugo Benichieae7a222017-07-25 11:40:56 +0900884 * {@code NetworkCapabilities} and return a String describing any difference.
885 * The returned String is empty if there is no difference.
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900886 *
887 * @hide
888 */
Hugo Benichieae7a222017-07-25 11:40:56 +0900889 public String describeImmutableDifferences(NetworkCapabilities that) {
890 if (that == null) {
891 return "other NetworkCapabilities was null";
892 }
893
894 StringJoiner joiner = new StringJoiner(", ");
895
Hugo Benichieae7a222017-07-25 11:40:56 +0900896 // Ignore NOT_METERED being added or removed as it is effectively dynamic. http://b/63326103
897 // TODO: properly support NOT_METERED as a mutable and requestable capability.
Hugo Benichi2ecb9402017-08-04 13:18:40 +0900898 final long mask = ~MUTABLE_CAPABILITIES & ~(1 << NET_CAPABILITY_NOT_METERED);
Hugo Benichieae7a222017-07-25 11:40:56 +0900899 long oldImmutableCapabilities = this.mNetworkCapabilities & mask;
900 long newImmutableCapabilities = that.mNetworkCapabilities & mask;
901 if (oldImmutableCapabilities != newImmutableCapabilities) {
902 String before = capabilityNamesOf(BitUtils.unpackBits(oldImmutableCapabilities));
903 String after = capabilityNamesOf(BitUtils.unpackBits(newImmutableCapabilities));
904 joiner.add(String.format("immutable capabilities changed: %s -> %s", before, after));
905 }
906
907 if (!equalsSpecifier(that)) {
908 NetworkSpecifier before = this.getNetworkSpecifier();
909 NetworkSpecifier after = that.getNetworkSpecifier();
910 joiner.add(String.format("specifier changed: %s -> %s", before, after));
911 }
912
913 if (!equalsTransportTypes(that)) {
914 String before = transportNamesOf(this.getTransportTypes());
915 String after = transportNamesOf(that.getTransportTypes());
916 joiner.add(String.format("transports changed: %s -> %s", before, after));
917 }
918
919 return joiner.toString();
Robert Greenwalt1448f052014-04-08 13:41:39 -0700920 }
921
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900922 /**
923 * Checks that our requestable capabilities are the same as those of the given
924 * {@code NetworkCapabilities}.
925 *
926 * @hide
927 */
928 public boolean equalRequestableCapabilities(NetworkCapabilities nc) {
929 if (nc == null) return false;
930 return (equalsNetCapabilitiesRequestable(nc) &&
931 equalsTransportTypes(nc) &&
932 equalsSpecifier(nc));
933 }
934
Robert Greenwalt1448f052014-04-08 13:41:39 -0700935 @Override
936 public boolean equals(Object obj) {
937 if (obj == null || (obj instanceof NetworkCapabilities == false)) return false;
938 NetworkCapabilities that = (NetworkCapabilities)obj;
939 return (equalsNetCapabilities(that) &&
940 equalsTransportTypes(that) &&
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700941 equalsLinkBandwidths(that) &&
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900942 equalsSignalStrength(that) &&
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700943 equalsSpecifier(that));
Robert Greenwalt1448f052014-04-08 13:41:39 -0700944 }
945
946 @Override
947 public int hashCode() {
948 return ((int)(mNetworkCapabilities & 0xFFFFFFFF) +
949 ((int)(mNetworkCapabilities >> 32) * 3) +
950 ((int)(mTransportTypes & 0xFFFFFFFF) * 5) +
951 ((int)(mTransportTypes >> 32) * 7) +
952 (mLinkUpBandwidthKbps * 11) +
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700953 (mLinkDownBandwidthKbps * 13) +
Etan Cohena7434272017-04-03 12:17:51 -0700954 Objects.hashCode(mNetworkSpecifier) * 17 +
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900955 (mSignalStrength * 19));
Robert Greenwalt1448f052014-04-08 13:41:39 -0700956 }
957
Wink Saville4e2dea72014-09-20 11:04:03 -0700958 @Override
Robert Greenwalt1448f052014-04-08 13:41:39 -0700959 public int describeContents() {
960 return 0;
961 }
Wink Saville4e2dea72014-09-20 11:04:03 -0700962 @Override
Robert Greenwalt1448f052014-04-08 13:41:39 -0700963 public void writeToParcel(Parcel dest, int flags) {
964 dest.writeLong(mNetworkCapabilities);
965 dest.writeLong(mTransportTypes);
966 dest.writeInt(mLinkUpBandwidthKbps);
967 dest.writeInt(mLinkDownBandwidthKbps);
Etan Cohena7434272017-04-03 12:17:51 -0700968 dest.writeParcelable((Parcelable) mNetworkSpecifier, flags);
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900969 dest.writeInt(mSignalStrength);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700970 }
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900971
Robert Greenwalt1448f052014-04-08 13:41:39 -0700972 public static final Creator<NetworkCapabilities> CREATOR =
973 new Creator<NetworkCapabilities>() {
Wink Saville4e2dea72014-09-20 11:04:03 -0700974 @Override
Robert Greenwalt1448f052014-04-08 13:41:39 -0700975 public NetworkCapabilities createFromParcel(Parcel in) {
976 NetworkCapabilities netCap = new NetworkCapabilities();
977
978 netCap.mNetworkCapabilities = in.readLong();
979 netCap.mTransportTypes = in.readLong();
980 netCap.mLinkUpBandwidthKbps = in.readInt();
981 netCap.mLinkDownBandwidthKbps = in.readInt();
Etan Cohena7434272017-04-03 12:17:51 -0700982 netCap.mNetworkSpecifier = in.readParcelable(null);
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900983 netCap.mSignalStrength = in.readInt();
Robert Greenwalt1448f052014-04-08 13:41:39 -0700984 return netCap;
985 }
Wink Saville4e2dea72014-09-20 11:04:03 -0700986 @Override
Robert Greenwalt1448f052014-04-08 13:41:39 -0700987 public NetworkCapabilities[] newArray(int size) {
988 return new NetworkCapabilities[size];
989 }
990 };
991
Wink Saville4e2dea72014-09-20 11:04:03 -0700992 @Override
Robert Greenwalt1448f052014-04-08 13:41:39 -0700993 public String toString() {
Hugo Benichieae7a222017-07-25 11:40:56 +0900994 // TODO: enumerate bits for transports and capabilities instead of creating arrays.
995 // TODO: use a StringBuilder instead of string concatenation.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700996 int[] types = getTransportTypes();
Hugo Benichi5df9d722016-04-25 17:16:35 +0900997 String transports = (types.length > 0) ? " Transports: " + transportNamesOf(types) : "";
Robert Greenwalt1448f052014-04-08 13:41:39 -0700998
Robert Greenwalt7569f182014-06-08 16:42:59 -0700999 types = getCapabilities();
1000 String capabilities = (types.length > 0 ? " Capabilities: " : "");
1001 for (int i = 0; i < types.length; ) {
Hugo Benichieae7a222017-07-25 11:40:56 +09001002 capabilities += capabilityNameOf(types[i]);
Robert Greenwalt7569f182014-06-08 16:42:59 -07001003 if (++i < types.length) capabilities += "&";
Robert Greenwalt1448f052014-04-08 13:41:39 -07001004 }
1005
1006 String upBand = ((mLinkUpBandwidthKbps > 0) ? " LinkUpBandwidth>=" +
1007 mLinkUpBandwidthKbps + "Kbps" : "");
1008 String dnBand = ((mLinkDownBandwidthKbps > 0) ? " LinkDnBandwidth>=" +
1009 mLinkDownBandwidthKbps + "Kbps" : "");
1010
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -07001011 String specifier = (mNetworkSpecifier == null ?
1012 "" : " Specifier: <" + mNetworkSpecifier + ">");
1013
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09001014 String signalStrength = (hasSignalStrength() ? " SignalStrength: " + mSignalStrength : "");
1015
1016 return "[" + transports + capabilities + upBand + dnBand + specifier + signalStrength + "]";
Robert Greenwalt1448f052014-04-08 13:41:39 -07001017 }
Hugo Benichi5df9d722016-04-25 17:16:35 +09001018
1019 /**
1020 * @hide
1021 */
Jeff Sharkeyde570312017-10-24 21:25:50 -06001022 public static String capabilityNamesOf(@NetCapability int[] capabilities) {
Hugo Benichieae7a222017-07-25 11:40:56 +09001023 StringJoiner joiner = new StringJoiner("|");
1024 if (capabilities != null) {
1025 for (int c : capabilities) {
1026 joiner.add(capabilityNameOf(c));
1027 }
1028 }
1029 return joiner.toString();
1030 }
1031
1032 /**
1033 * @hide
1034 */
Jeff Sharkeyde570312017-10-24 21:25:50 -06001035 public static String capabilityNameOf(@NetCapability int capability) {
Hugo Benichieae7a222017-07-25 11:40:56 +09001036 switch (capability) {
1037 case NET_CAPABILITY_MMS: return "MMS";
1038 case NET_CAPABILITY_SUPL: return "SUPL";
1039 case NET_CAPABILITY_DUN: return "DUN";
1040 case NET_CAPABILITY_FOTA: return "FOTA";
1041 case NET_CAPABILITY_IMS: return "IMS";
1042 case NET_CAPABILITY_CBS: return "CBS";
1043 case NET_CAPABILITY_WIFI_P2P: return "WIFI_P2P";
1044 case NET_CAPABILITY_IA: return "IA";
1045 case NET_CAPABILITY_RCS: return "RCS";
1046 case NET_CAPABILITY_XCAP: return "XCAP";
1047 case NET_CAPABILITY_EIMS: return "EIMS";
1048 case NET_CAPABILITY_NOT_METERED: return "NOT_METERED";
1049 case NET_CAPABILITY_INTERNET: return "INTERNET";
1050 case NET_CAPABILITY_NOT_RESTRICTED: return "NOT_RESTRICTED";
1051 case NET_CAPABILITY_TRUSTED: return "TRUSTED";
1052 case NET_CAPABILITY_NOT_VPN: return "NOT_VPN";
1053 case NET_CAPABILITY_VALIDATED: return "VALIDATED";
1054 case NET_CAPABILITY_CAPTIVE_PORTAL: return "CAPTIVE_PORTAL";
Jeff Sharkey72f9c422017-10-27 17:22:59 -06001055 case NET_CAPABILITY_NOT_ROAMING: return "NOT_ROAMING";
Hugo Benichieae7a222017-07-25 11:40:56 +09001056 case NET_CAPABILITY_FOREGROUND: return "FOREGROUND";
1057 default: return Integer.toString(capability);
1058 }
1059 }
1060
1061 /**
1062 * @hide
1063 */
Jeff Sharkeyde570312017-10-24 21:25:50 -06001064 public static String transportNamesOf(@Transport int[] types) {
Hugo Benichieae7a222017-07-25 11:40:56 +09001065 StringJoiner joiner = new StringJoiner("|");
1066 if (types != null) {
1067 for (int t : types) {
1068 joiner.add(transportNameOf(t));
1069 }
Hugo Benichi5df9d722016-04-25 17:16:35 +09001070 }
Hugo Benichieae7a222017-07-25 11:40:56 +09001071 return joiner.toString();
Hugo Benichi9910dbc2017-03-22 18:29:58 +09001072 }
1073
1074 /**
1075 * @hide
1076 */
Jeff Sharkeyde570312017-10-24 21:25:50 -06001077 public static String transportNameOf(@Transport int transport) {
Hugo Benichi16f0a942017-06-20 14:07:59 +09001078 if (!isValidTransport(transport)) {
Hugo Benichi9910dbc2017-03-22 18:29:58 +09001079 return "UNKNOWN";
1080 }
1081 return TRANSPORT_NAMES[transport];
Hugo Benichi5df9d722016-04-25 17:16:35 +09001082 }
Hugo Benichi16f0a942017-06-20 14:07:59 +09001083
Jeff Sharkeyde570312017-10-24 21:25:50 -06001084 private static void checkValidTransportType(@Transport int transport) {
Hugo Benichi16f0a942017-06-20 14:07:59 +09001085 Preconditions.checkArgument(
1086 isValidTransport(transport), "Invalid TransportType " + transport);
1087 }
Robert Greenwalt1448f052014-04-08 13:41:39 -07001088}