blob: af9414c56654709dd45a8b9accd79dee0365375d [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;
paulhud9736de2019-03-08 16:35:20 +080020import android.annotation.NonNull;
Etan Cohenca9fb562018-11-27 07:32:39 -080021import android.annotation.Nullable;
Chalard Jeane5e38502020-03-18 15:58:50 +090022import android.annotation.RequiresPermission;
Pavel Maltsevd9c9fff2018-03-22 11:41:32 -070023import android.annotation.SystemApi;
Jeff Sharkeya5ee62f2018-05-14 13:49:07 -060024import android.annotation.TestApi;
Artur Satayev26958002019-12-10 17:47:52 +000025import android.compat.annotation.UnsupportedAppUsage;
Jeff Sharkey72f9c422017-10-27 17:22:59 -060026import android.net.ConnectivityManager.NetworkCallback;
Mathew Inwood45d2c252018-09-14 12:35:36 +010027import android.os.Build;
Robert Greenwalt1448f052014-04-08 13:41:39 -070028import android.os.Parcel;
29import android.os.Parcelable;
Qingxi Li7cf06622020-01-17 17:54:27 -080030import android.os.Process;
Roshan Piuse38acab2020-01-16 12:17:17 -080031import android.text.TextUtils;
Chalard Jeanecacd5e2017-12-27 14:23:31 +090032import android.util.ArraySet;
Kweku Adams85f2fbc2017-12-18 12:04:12 -080033import android.util.proto.ProtoOutputStream;
Robert Greenwalta7e148a2017-04-10 14:32:23 -070034
35import com.android.internal.annotations.VisibleForTesting;
Chalard Jeane5e38502020-03-18 15:58:50 +090036import com.android.internal.util.ArrayUtils;
Hugo Benichi9910dbc2017-03-22 18:29:58 +090037import com.android.internal.util.BitUtils;
Hugo Benichi16f0a942017-06-20 14:07:59 +090038import com.android.internal.util.Preconditions;
Etan Cohena7434272017-04-03 12:17:51 -070039
Jeff Sharkeyde570312017-10-24 21:25:50 -060040import java.lang.annotation.Retention;
41import java.lang.annotation.RetentionPolicy;
Cody Kestingf7ac9962020-03-16 18:15:28 -070042import java.util.Arrays;
Etan Cohena7434272017-04-03 12:17:51 -070043import java.util.Objects;
Chalard Jeanecacd5e2017-12-27 14:23:31 +090044import java.util.Set;
Hugo Benichieae7a222017-07-25 11:40:56 +090045import java.util.StringJoiner;
Robert Greenwalt1448f052014-04-08 13:41:39 -070046
47/**
Jeff Sharkey49bcd602017-11-09 13:11:50 -070048 * Representation of the capabilities of an active network. Instances are
49 * typically obtained through
Jeff Sharkey72f9c422017-10-27 17:22:59 -060050 * {@link NetworkCallback#onCapabilitiesChanged(Network, NetworkCapabilities)}
51 * or {@link ConnectivityManager#getNetworkCapabilities(Network)}.
Jeff Sharkey72f9c422017-10-27 17:22:59 -060052 * <p>
53 * This replaces the old {@link ConnectivityManager#TYPE_MOBILE} method of
54 * network selection. Rather than indicate a need for Wi-Fi because an
55 * application needs high bandwidth and risk obsolescence when a new, fast
56 * network appears (like LTE), the application should specify it needs high
57 * bandwidth. Similarly if an application needs an unmetered network for a bulk
58 * transfer it can specify that rather than assuming all cellular based
59 * connections are metered and all Wi-Fi based connections are not.
Robert Greenwalt1448f052014-04-08 13:41:39 -070060 */
61public final class NetworkCapabilities implements Parcelable {
Etan Cohena7434272017-04-03 12:17:51 -070062 private static final String TAG = "NetworkCapabilities";
63
lucaslin783f2212019-10-22 18:27:33 +080064 // Set to true when private DNS is broken.
65 private boolean mPrivateDnsBroken;
66
Roshan Piuse38acab2020-01-16 12:17:17 -080067 /**
68 * Uid of the app making the request.
69 */
70 private int mRequestorUid;
71
72 /**
73 * Package name of the app making the request.
74 */
75 private String mRequestorPackageName;
76
Robert Greenwalt01d004e2014-05-18 15:24:21 -070077 public NetworkCapabilities() {
Lorenzo Colittif7058f52015-04-27 11:31:55 +090078 clearAll();
Lorenzo Colitti260a36d2015-07-08 12:49:04 +090079 mNetworkCapabilities = DEFAULT_CAPABILITIES;
Robert Greenwalt01d004e2014-05-18 15:24:21 -070080 }
81
82 public NetworkCapabilities(NetworkCapabilities nc) {
83 if (nc != null) {
Chalard Jean4c4bc932018-05-18 23:48:49 +090084 set(nc);
Robert Greenwalt01d004e2014-05-18 15:24:21 -070085 }
86 }
Robert Greenwalt1448f052014-04-08 13:41:39 -070087
88 /**
Lorenzo Colittif7058f52015-04-27 11:31:55 +090089 * Completely clears the contents of this object, removing even the capabilities that are set
90 * by default when the object is constructed.
Chalard Jeane5e38502020-03-18 15:58:50 +090091 * @hide
Lorenzo Colittif7058f52015-04-27 11:31:55 +090092 */
93 public void clearAll() {
Pavel Maltsev1cd48da2018-02-01 11:16:02 -080094 mNetworkCapabilities = mTransportTypes = mUnwantedNetworkCapabilities = 0;
Jeff Sharkey49bcd602017-11-09 13:11:50 -070095 mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
Lorenzo Colittif7058f52015-04-27 11:31:55 +090096 mNetworkSpecifier = null;
Etan Cohenca9fb562018-11-27 07:32:39 -080097 mTransportInfo = null;
Lorenzo Colittic3f21f32015-07-06 23:50:27 +090098 mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
Chalard Jeanecacd5e2017-12-27 14:23:31 +090099 mUids = null;
Cody Kestingf7ac9962020-03-16 18:15:28 -0700100 mAdministratorUids = new int[0];
Qingxi Li7cf06622020-01-17 17:54:27 -0800101 mOwnerUid = Process.INVALID_UID;
Chalard Jeanb03a6222018-04-11 21:09:10 +0900102 mSSID = null;
lucaslin783f2212019-10-22 18:27:33 +0800103 mPrivateDnsBroken = false;
Roshan Piuse38acab2020-01-16 12:17:17 -0800104 mRequestorUid = Process.INVALID_UID;
105 mRequestorPackageName = null;
Lorenzo Colittif7058f52015-04-27 11:31:55 +0900106 }
107
108 /**
Chalard Jean4c4bc932018-05-18 23:48:49 +0900109 * Set all contents of this object to the contents of a NetworkCapabilities.
110 * @hide
111 */
paulhud9736de2019-03-08 16:35:20 +0800112 public void set(@NonNull NetworkCapabilities nc) {
Chalard Jean4c4bc932018-05-18 23:48:49 +0900113 mNetworkCapabilities = nc.mNetworkCapabilities;
114 mTransportTypes = nc.mTransportTypes;
115 mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps;
116 mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
117 mNetworkSpecifier = nc.mNetworkSpecifier;
Etan Cohenca9fb562018-11-27 07:32:39 -0800118 mTransportInfo = nc.mTransportInfo;
Chalard Jean4c4bc932018-05-18 23:48:49 +0900119 mSignalStrength = nc.mSignalStrength;
120 setUids(nc.mUids); // Will make the defensive copy
Cody Kesting201fc132020-01-17 11:58:36 -0800121 setAdministratorUids(nc.mAdministratorUids);
Qingxi Li7cf06622020-01-17 17:54:27 -0800122 mOwnerUid = nc.mOwnerUid;
Chalard Jean4c4bc932018-05-18 23:48:49 +0900123 mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities;
124 mSSID = nc.mSSID;
lucaslin783f2212019-10-22 18:27:33 +0800125 mPrivateDnsBroken = nc.mPrivateDnsBroken;
Roshan Piuse38acab2020-01-16 12:17:17 -0800126 mRequestorUid = nc.mRequestorUid;
127 mRequestorPackageName = nc.mRequestorPackageName;
Chalard Jean4c4bc932018-05-18 23:48:49 +0900128 }
129
130 /**
Robert Greenwalt1448f052014-04-08 13:41:39 -0700131 * Represents the network's capabilities. If any are specified they will be satisfied
132 * by any Network that matches all of them.
133 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +0100134 @UnsupportedAppUsage
Lorenzo Colittif7058f52015-04-27 11:31:55 +0900135 private long mNetworkCapabilities;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700136
Pavel Maltsev1cd48da2018-02-01 11:16:02 -0800137 /**
138 * If any capabilities specified here they must not exist in the matching Network.
139 */
140 private long mUnwantedNetworkCapabilities;
141
Jeff Sharkeyde570312017-10-24 21:25:50 -0600142 /** @hide */
143 @Retention(RetentionPolicy.SOURCE)
144 @IntDef(prefix = { "NET_CAPABILITY_" }, value = {
145 NET_CAPABILITY_MMS,
146 NET_CAPABILITY_SUPL,
147 NET_CAPABILITY_DUN,
148 NET_CAPABILITY_FOTA,
149 NET_CAPABILITY_IMS,
150 NET_CAPABILITY_CBS,
151 NET_CAPABILITY_WIFI_P2P,
152 NET_CAPABILITY_IA,
153 NET_CAPABILITY_RCS,
154 NET_CAPABILITY_XCAP,
155 NET_CAPABILITY_EIMS,
156 NET_CAPABILITY_NOT_METERED,
157 NET_CAPABILITY_INTERNET,
158 NET_CAPABILITY_NOT_RESTRICTED,
159 NET_CAPABILITY_TRUSTED,
160 NET_CAPABILITY_NOT_VPN,
161 NET_CAPABILITY_VALIDATED,
162 NET_CAPABILITY_CAPTIVE_PORTAL,
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600163 NET_CAPABILITY_NOT_ROAMING,
Jeff Sharkeyde570312017-10-24 21:25:50 -0600164 NET_CAPABILITY_FOREGROUND,
Jeff Sharkey9b2a10f2018-01-17 13:27:03 +0900165 NET_CAPABILITY_NOT_CONGESTED,
Chalard Jean804b8fb2018-01-30 22:41:41 +0900166 NET_CAPABILITY_NOT_SUSPENDED,
Pavel Maltsev43403202018-01-30 17:19:44 -0800167 NET_CAPABILITY_OEM_PAID,
lucasline252a742019-03-12 13:08:03 +0800168 NET_CAPABILITY_MCX,
169 NET_CAPABILITY_PARTIAL_CONNECTIVITY,
Jeff Sharkeyde570312017-10-24 21:25:50 -0600170 })
171 public @interface NetCapability { }
172
Robert Greenwalt1448f052014-04-08 13:41:39 -0700173 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700174 * Indicates this is a network that has the ability to reach the
175 * carrier's MMSC for sending and receiving MMS messages.
Robert Greenwalt1448f052014-04-08 13:41:39 -0700176 */
177 public static final int NET_CAPABILITY_MMS = 0;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700178
179 /**
180 * Indicates this is a network that has the ability to reach the carrier's
181 * SUPL server, used to retrieve GPS information.
182 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700183 public static final int NET_CAPABILITY_SUPL = 1;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700184
185 /**
186 * Indicates this is a network that has the ability to reach the carrier's
187 * DUN or tethering gateway.
188 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700189 public static final int NET_CAPABILITY_DUN = 2;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700190
191 /**
192 * Indicates this is a network that has the ability to reach the carrier's
193 * FOTA portal, used for over the air updates.
194 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700195 public static final int NET_CAPABILITY_FOTA = 3;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700196
197 /**
198 * Indicates this is a network that has the ability to reach the carrier's
199 * IMS servers, used for network registration and signaling.
200 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700201 public static final int NET_CAPABILITY_IMS = 4;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700202
203 /**
204 * Indicates this is a network that has the ability to reach the carrier's
205 * CBS servers, used for carrier specific services.
206 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700207 public static final int NET_CAPABILITY_CBS = 5;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700208
209 /**
210 * Indicates this is a network that has the ability to reach a Wi-Fi direct
211 * peer.
212 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700213 public static final int NET_CAPABILITY_WIFI_P2P = 6;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700214
215 /**
216 * Indicates this is a network that has the ability to reach a carrier's
217 * Initial Attach servers.
218 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700219 public static final int NET_CAPABILITY_IA = 7;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700220
221 /**
222 * Indicates this is a network that has the ability to reach a carrier's
223 * RCS servers, used for Rich Communication Services.
224 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700225 public static final int NET_CAPABILITY_RCS = 8;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700226
227 /**
228 * Indicates this is a network that has the ability to reach a carrier's
229 * XCAP servers, used for configuration and control.
230 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700231 public static final int NET_CAPABILITY_XCAP = 9;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700232
233 /**
234 * Indicates this is a network that has the ability to reach a carrier's
Robert Greenwalt4bd43892015-07-09 14:49:35 -0700235 * Emergency IMS servers or other services, used for network signaling
236 * during emergency calls.
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700237 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700238 public static final int NET_CAPABILITY_EIMS = 10;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700239
240 /**
241 * Indicates that this network is unmetered.
242 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700243 public static final int NET_CAPABILITY_NOT_METERED = 11;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700244
245 /**
246 * Indicates that this network should be able to reach the internet.
247 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700248 public static final int NET_CAPABILITY_INTERNET = 12;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700249
250 /**
251 * Indicates that this network is available for general use. If this is not set
252 * applications should not attempt to communicate on this network. Note that this
253 * is simply informative and not enforcement - enforcement is handled via other means.
254 * Set by default.
255 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700256 public static final int NET_CAPABILITY_NOT_RESTRICTED = 13;
257
Robert Greenwalt16e12ab2014-07-08 15:31:37 -0700258 /**
259 * Indicates that the user has indicated implicit trust of this network. This
260 * generally means it's a sim-selected carrier, a plugged in ethernet, a paired
261 * BT device or a wifi the user asked to connect to. Untrusted networks
262 * are probably limited to unknown wifi AP. Set by default.
263 */
264 public static final int NET_CAPABILITY_TRUSTED = 14;
265
Paul Jensen76b610a2015-03-18 09:33:07 -0400266 /**
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400267 * Indicates that this network is not a VPN. This capability is set by default and should be
Paul Jensen76b610a2015-03-18 09:33:07 -0400268 * explicitly cleared for VPN networks.
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400269 */
270 public static final int NET_CAPABILITY_NOT_VPN = 15;
271
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900272 /**
273 * Indicates that connectivity on this network was successfully validated. For example, for a
274 * network with NET_CAPABILITY_INTERNET, it means that Internet connectivity was successfully
275 * detected.
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900276 */
277 public static final int NET_CAPABILITY_VALIDATED = 16;
Robert Greenwalt16e12ab2014-07-08 15:31:37 -0700278
Paul Jensen3d194ea2015-06-16 14:27:36 -0400279 /**
280 * Indicates that this network was found to have a captive portal in place last time it was
281 * probed.
282 */
283 public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17;
284
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900285 /**
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600286 * Indicates that this network is not roaming.
287 */
288 public static final int NET_CAPABILITY_NOT_ROAMING = 18;
289
290 /**
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900291 * Indicates that this network is available for use by apps, and not a network that is being
292 * kept up in the background to facilitate fast network switching.
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900293 */
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600294 public static final int NET_CAPABILITY_FOREGROUND = 19;
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900295
Jeff Sharkey9b2a10f2018-01-17 13:27:03 +0900296 /**
297 * Indicates that this network is not congested.
298 * <p>
Jeff Sharkey0a5570d2018-04-10 12:38:29 -0600299 * When a network is congested, applications should defer network traffic
300 * that can be done at a later time, such as uploading analytics.
Jeff Sharkey9b2a10f2018-01-17 13:27:03 +0900301 */
302 public static final int NET_CAPABILITY_NOT_CONGESTED = 20;
303
Chalard Jean804b8fb2018-01-30 22:41:41 +0900304 /**
305 * Indicates that this network is not currently suspended.
306 * <p>
307 * When a network is suspended, the network's IP addresses and any connections
308 * established on the network remain valid, but the network is temporarily unable
309 * to transfer data. This can happen, for example, if a cellular network experiences
310 * a temporary loss of signal, such as when driving through a tunnel, etc.
311 * A network with this capability is not suspended, so is expected to be able to
312 * transfer data.
313 */
314 public static final int NET_CAPABILITY_NOT_SUSPENDED = 21;
315
Pavel Maltsev43403202018-01-30 17:19:44 -0800316 /**
317 * Indicates that traffic that goes through this network is paid by oem. For example,
318 * this network can be used by system apps to upload telemetry data.
319 * @hide
320 */
Pavel Maltsevd9c9fff2018-03-22 11:41:32 -0700321 @SystemApi
Pavel Maltsev43403202018-01-30 17:19:44 -0800322 public static final int NET_CAPABILITY_OEM_PAID = 22;
323
Amit Mahajanfd3ee572019-02-20 15:04:30 -0800324 /**
325 * Indicates this is a network that has the ability to reach a carrier's Mission Critical
326 * servers.
327 */
328 public static final int NET_CAPABILITY_MCX = 23;
329
lucasline252a742019-03-12 13:08:03 +0800330 /**
331 * Indicates that this network was tested to only provide partial connectivity.
332 * @hide
333 */
334 @SystemApi
335 public static final int NET_CAPABILITY_PARTIAL_CONNECTIVITY = 24;
336
Robert Greenwalt1448f052014-04-08 13:41:39 -0700337 private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
lucasline252a742019-03-12 13:08:03 +0800338 private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_PARTIAL_CONNECTIVITY;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700339
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700340 /**
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900341 * Network capabilities that are expected to be mutable, i.e., can change while a particular
342 * network is connected.
343 */
344 private static final long MUTABLE_CAPABILITIES =
345 // TRUSTED can change when user explicitly connects to an untrusted network in Settings.
346 // http://b/18206275
Chalard Jean804b8fb2018-01-30 22:41:41 +0900347 (1 << NET_CAPABILITY_TRUSTED)
348 | (1 << NET_CAPABILITY_VALIDATED)
349 | (1 << NET_CAPABILITY_CAPTIVE_PORTAL)
350 | (1 << NET_CAPABILITY_NOT_ROAMING)
351 | (1 << NET_CAPABILITY_FOREGROUND)
352 | (1 << NET_CAPABILITY_NOT_CONGESTED)
lucasline252a742019-03-12 13:08:03 +0800353 | (1 << NET_CAPABILITY_NOT_SUSPENDED)
354 | (1 << NET_CAPABILITY_PARTIAL_CONNECTIVITY);
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900355
356 /**
357 * Network capabilities that are not allowed in NetworkRequests. This exists because the
358 * NetworkFactory / NetworkAgent model does not deal well with the situation where a
359 * capability's presence cannot be known in advance. If such a capability is requested, then we
360 * can get into a cycle where the NetworkFactory endlessly churns out NetworkAgents that then
361 * get immediately torn down because they do not have the requested capability.
362 */
363 private static final long NON_REQUESTABLE_CAPABILITIES =
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900364 MUTABLE_CAPABILITIES & ~(1 << NET_CAPABILITY_TRUSTED);
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900365
366 /**
367 * Capabilities that are set by default when the object is constructed.
368 */
369 private static final long DEFAULT_CAPABILITIES =
370 (1 << NET_CAPABILITY_NOT_RESTRICTED) |
371 (1 << NET_CAPABILITY_TRUSTED) |
372 (1 << NET_CAPABILITY_NOT_VPN);
373
374 /**
Paul Jensen487ffe72015-07-24 15:57:11 -0400375 * Capabilities that suggest that a network is restricted.
Pavel Maltsev4af91072018-03-07 14:33:22 -0800376 * {@see #maybeMarkCapabilitiesRestricted}, {@see #FORCE_RESTRICTED_CAPABILITIES}
Paul Jensen487ffe72015-07-24 15:57:11 -0400377 */
Robert Greenwalta7e148a2017-04-10 14:32:23 -0700378 @VisibleForTesting
379 /* package */ static final long RESTRICTED_CAPABILITIES =
Paul Jensen487ffe72015-07-24 15:57:11 -0400380 (1 << NET_CAPABILITY_CBS) |
381 (1 << NET_CAPABILITY_DUN) |
382 (1 << NET_CAPABILITY_EIMS) |
383 (1 << NET_CAPABILITY_FOTA) |
384 (1 << NET_CAPABILITY_IA) |
385 (1 << NET_CAPABILITY_IMS) |
386 (1 << NET_CAPABILITY_RCS) |
Amit Mahajanfd3ee572019-02-20 15:04:30 -0800387 (1 << NET_CAPABILITY_XCAP) |
388 (1 << NET_CAPABILITY_MCX);
Pavel Maltsev4af91072018-03-07 14:33:22 -0800389
390 /**
391 * Capabilities that force network to be restricted.
392 * {@see #maybeMarkCapabilitiesRestricted}.
393 */
394 private static final long FORCE_RESTRICTED_CAPABILITIES =
Pavel Maltsev43403202018-01-30 17:19:44 -0800395 (1 << NET_CAPABILITY_OEM_PAID);
Paul Jensen487ffe72015-07-24 15:57:11 -0400396
397 /**
Robert Greenwalta7e148a2017-04-10 14:32:23 -0700398 * Capabilities that suggest that a network is unrestricted.
399 * {@see #maybeMarkCapabilitiesRestricted}.
400 */
401 @VisibleForTesting
402 /* package */ static final long UNRESTRICTED_CAPABILITIES =
403 (1 << NET_CAPABILITY_INTERNET) |
404 (1 << NET_CAPABILITY_MMS) |
405 (1 << NET_CAPABILITY_SUPL) |
406 (1 << NET_CAPABILITY_WIFI_P2P);
407
408 /**
lucasline252a742019-03-12 13:08:03 +0800409 * Capabilities that are managed by ConnectivityService.
410 */
411 private static final long CONNECTIVITY_MANAGED_CAPABILITIES =
412 (1 << NET_CAPABILITY_VALIDATED)
413 | (1 << NET_CAPABILITY_CAPTIVE_PORTAL)
414 | (1 << NET_CAPABILITY_FOREGROUND)
415 | (1 << NET_CAPABILITY_PARTIAL_CONNECTIVITY);
416
417 /**
Chalard Jean09c48e42020-03-25 10:33:55 +0000418 * Capabilities that are allowed for test networks. This list must be set so that it is safe
419 * for an unprivileged user to create a network with these capabilities via shell. As such,
420 * it must never contain capabilities that are generally useful to the system, such as
421 * INTERNET, IMS, SUPL, etc.
422 */
423 private static final long TEST_NETWORKS_ALLOWED_CAPABILITIES =
424 (1 << NET_CAPABILITY_NOT_METERED)
425 | (1 << NET_CAPABILITY_NOT_RESTRICTED)
426 | (1 << NET_CAPABILITY_NOT_VPN)
427 | (1 << NET_CAPABILITY_NOT_ROAMING)
428 | (1 << NET_CAPABILITY_NOT_CONGESTED)
429 | (1 << NET_CAPABILITY_NOT_SUSPENDED);
430
431 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700432 * Adds the given capability to this {@code NetworkCapability} instance.
Chalard Jeane5e38502020-03-18 15:58:50 +0900433 * Note that when searching for a network to satisfy a request, all capabilities
434 * requested must be satisfied.
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700435 *
Jeff Sharkeyde570312017-10-24 21:25:50 -0600436 * @param capability the capability to be added.
Pierre Imaic8419a82016-03-22 17:54:54 +0900437 * @return This NetworkCapabilities instance, to facilitate chaining.
Chalard Jeane5e38502020-03-18 15:58:50 +0900438 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700439 */
paulhud9736de2019-03-08 16:35:20 +0800440 public @NonNull NetworkCapabilities addCapability(@NetCapability int capability) {
Aaron Huange6b62392019-09-20 22:52:54 +0800441 // If the given capability was previously added to the list of unwanted capabilities
442 // then the capability will also be removed from the list of unwanted capabilities.
443 // TODO: Consider adding unwanted capabilities to the public API and mention this
444 // in the documentation.
Pavel Maltsev1cd48da2018-02-01 11:16:02 -0800445 checkValidCapability(capability);
Robert Greenwalt7569f182014-06-08 16:42:59 -0700446 mNetworkCapabilities |= 1 << capability;
Pavel Maltsev1cd48da2018-02-01 11:16:02 -0800447 mUnwantedNetworkCapabilities &= ~(1 << capability); // remove from unwanted capability list
Robert Greenwalt7569f182014-06-08 16:42:59 -0700448 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700449 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700450
451 /**
Pavel Maltsev1cd48da2018-02-01 11:16:02 -0800452 * Adds the given capability to the list of unwanted capabilities of this
Chalard Jeane5e38502020-03-18 15:58:50 +0900453 * {@code NetworkCapability} instance. Note that when searching for a network to
454 * satisfy a request, the network must not contain any capability from unwanted capability
455 * list.
Pavel Maltsev1cd48da2018-02-01 11:16:02 -0800456 * <p>
457 * If the capability was previously added to the list of required capabilities (for
458 * example, it was there by default or added using {@link #addCapability(int)} method), then
459 * it will be removed from the list of required capabilities as well.
460 *
461 * @see #addCapability(int)
462 * @hide
463 */
464 public void addUnwantedCapability(@NetCapability int capability) {
465 checkValidCapability(capability);
466 mUnwantedNetworkCapabilities |= 1 << capability;
467 mNetworkCapabilities &= ~(1 << capability); // remove from requested capabilities
468 }
469
470 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700471 * Removes (if found) the given capability from this {@code NetworkCapability} instance.
472 *
Jeff Sharkeyde570312017-10-24 21:25:50 -0600473 * @param capability the capability to be removed.
Pierre Imaic8419a82016-03-22 17:54:54 +0900474 * @return This NetworkCapabilities instance, to facilitate chaining.
Chalard Jeane5e38502020-03-18 15:58:50 +0900475 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700476 */
paulhud9736de2019-03-08 16:35:20 +0800477 public @NonNull NetworkCapabilities removeCapability(@NetCapability int capability) {
Aaron Huange6b62392019-09-20 22:52:54 +0800478 // Note that this method removes capabilities that were added via addCapability(int),
479 // addUnwantedCapability(int) or setCapabilities(int[], int[]).
Pavel Maltsev1cd48da2018-02-01 11:16:02 -0800480 checkValidCapability(capability);
481 final long mask = ~(1 << capability);
482 mNetworkCapabilities &= mask;
483 mUnwantedNetworkCapabilities &= mask;
Robert Greenwalt7569f182014-06-08 16:42:59 -0700484 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700485 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700486
487 /**
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600488 * Sets (or clears) the given capability on this {@link NetworkCapabilities}
489 * instance.
Chalard Jeane5e38502020-03-18 15:58:50 +0900490 * @hide
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600491 */
paulhud9736de2019-03-08 16:35:20 +0800492 public @NonNull NetworkCapabilities setCapability(@NetCapability int capability,
493 boolean value) {
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600494 if (value) {
495 addCapability(capability);
496 } else {
497 removeCapability(capability);
498 }
499 return this;
500 }
501
502 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700503 * Gets all the capabilities set on this {@code NetworkCapability} instance.
504 *
Jeff Sharkeyde570312017-10-24 21:25:50 -0600505 * @return an array of capability values for this instance.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700506 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700507 */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000508 @UnsupportedAppUsage
Jeff Sharkeya5ee62f2018-05-14 13:49:07 -0600509 @TestApi
Jeff Sharkeyde570312017-10-24 21:25:50 -0600510 public @NetCapability int[] getCapabilities() {
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900511 return BitUtils.unpackBits(mNetworkCapabilities);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700512 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700513
514 /**
Pavel Maltsev1cd48da2018-02-01 11:16:02 -0800515 * Gets all the unwanted capabilities set on this {@code NetworkCapability} instance.
516 *
517 * @return an array of unwanted capability values for this instance.
518 * @hide
519 */
520 public @NetCapability int[] getUnwantedCapabilities() {
521 return BitUtils.unpackBits(mUnwantedNetworkCapabilities);
522 }
523
524
525 /**
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600526 * Sets all the capabilities set on this {@code NetworkCapability} instance.
Jeff Sharkey49bcd602017-11-09 13:11:50 -0700527 * This overwrites any existing capabilities.
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600528 *
529 * @hide
530 */
Pavel Maltsev1cd48da2018-02-01 11:16:02 -0800531 public void setCapabilities(@NetCapability int[] capabilities,
532 @NetCapability int[] unwantedCapabilities) {
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600533 mNetworkCapabilities = BitUtils.packBits(capabilities);
Pavel Maltsev1cd48da2018-02-01 11:16:02 -0800534 mUnwantedNetworkCapabilities = BitUtils.packBits(unwantedCapabilities);
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600535 }
536
537 /**
Pavel Maltsev1cd48da2018-02-01 11:16:02 -0800538 * @deprecated use {@link #setCapabilities(int[], int[])}
539 * @hide
540 */
541 @Deprecated
542 public void setCapabilities(@NetCapability int[] capabilities) {
543 setCapabilities(capabilities, new int[] {});
544 }
545
546 /**
547 * Tests for the presence of a capability on this instance.
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700548 *
Jeff Sharkeyde570312017-10-24 21:25:50 -0600549 * @param capability the capabilities to be tested for.
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700550 * @return {@code true} if set on this instance.
551 */
Jeff Sharkeyde570312017-10-24 21:25:50 -0600552 public boolean hasCapability(@NetCapability int capability) {
Pavel Maltsev1cd48da2018-02-01 11:16:02 -0800553 return isValidCapability(capability)
554 && ((mNetworkCapabilities & (1 << capability)) != 0);
555 }
556
557 /** @hide */
558 public boolean hasUnwantedCapability(@NetCapability int capability) {
559 return isValidCapability(capability)
560 && ((mUnwantedNetworkCapabilities & (1 << capability)) != 0);
Robert Greenwalt5c55e332014-05-08 00:02:04 -0700561 }
Robert Greenwalt1448f052014-04-08 13:41:39 -0700562
lucasline252a742019-03-12 13:08:03 +0800563 /**
564 * Check if this NetworkCapabilities has system managed capabilities or not.
565 * @hide
566 */
567 public boolean hasConnectivityManagedCapability() {
568 return ((mNetworkCapabilities & CONNECTIVITY_MANAGED_CAPABILITIES) != 0);
569 }
570
Pavel Maltseve18ef262018-03-07 11:13:04 -0800571 /** Note this method may result in having the same capability in wanted and unwanted lists. */
paulhud9736de2019-03-08 16:35:20 +0800572 private void combineNetCapabilities(@NonNull NetworkCapabilities nc) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700573 this.mNetworkCapabilities |= nc.mNetworkCapabilities;
Pavel Maltsev1cd48da2018-02-01 11:16:02 -0800574 this.mUnwantedNetworkCapabilities |= nc.mUnwantedNetworkCapabilities;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700575 }
576
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900577 /**
578 * Convenience function that returns a human-readable description of the first mutable
579 * capability we find. Used to present an error message to apps that request mutable
580 * capabilities.
581 *
582 * @hide
583 */
paulhud9736de2019-03-08 16:35:20 +0800584 public @Nullable String describeFirstNonRequestableCapability() {
Pavel Maltsev1cd48da2018-02-01 11:16:02 -0800585 final long nonRequestable = (mNetworkCapabilities | mUnwantedNetworkCapabilities)
586 & NON_REQUESTABLE_CAPABILITIES;
587
Jeff Sharkey9b2a10f2018-01-17 13:27:03 +0900588 if (nonRequestable != 0) {
589 return capabilityNameOf(BitUtils.unpackBits(nonRequestable)[0]);
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900590 }
591 if (mLinkUpBandwidthKbps != 0 || mLinkDownBandwidthKbps != 0) return "link bandwidth";
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900592 if (hasSignalStrength()) return "signalStrength";
lucaslin783f2212019-10-22 18:27:33 +0800593 if (isPrivateDnsBroken()) {
594 return "privateDnsBroken";
595 }
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900596 return null;
597 }
598
paulhud9736de2019-03-08 16:35:20 +0800599 private boolean satisfiedByNetCapabilities(@NonNull NetworkCapabilities nc,
600 boolean onlyImmutable) {
Pavel Maltsev1cd48da2018-02-01 11:16:02 -0800601 long requestedCapabilities = mNetworkCapabilities;
602 long requestedUnwantedCapabilities = mUnwantedNetworkCapabilities;
603 long providedCapabilities = nc.mNetworkCapabilities;
604
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900605 if (onlyImmutable) {
Pavel Maltsev1cd48da2018-02-01 11:16:02 -0800606 requestedCapabilities &= ~MUTABLE_CAPABILITIES;
607 requestedUnwantedCapabilities &= ~MUTABLE_CAPABILITIES;
Lorenzo Colitti260a36d2015-07-08 12:49:04 +0900608 }
Pavel Maltsev1cd48da2018-02-01 11:16:02 -0800609 return ((providedCapabilities & requestedCapabilities) == requestedCapabilities)
610 && ((requestedUnwantedCapabilities & providedCapabilities) == 0);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700611 }
612
Robert Greenwalt06314e42014-10-29 14:04:06 -0700613 /** @hide */
paulhud9736de2019-03-08 16:35:20 +0800614 public boolean equalsNetCapabilities(@NonNull NetworkCapabilities nc) {
Pavel Maltsev1cd48da2018-02-01 11:16:02 -0800615 return (nc.mNetworkCapabilities == this.mNetworkCapabilities)
616 && (nc.mUnwantedNetworkCapabilities == this.mUnwantedNetworkCapabilities);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700617 }
618
paulhud9736de2019-03-08 16:35:20 +0800619 private boolean equalsNetCapabilitiesRequestable(@NonNull NetworkCapabilities that) {
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900620 return ((this.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) ==
Pavel Maltsev1cd48da2018-02-01 11:16:02 -0800621 (that.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES))
622 && ((this.mUnwantedNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) ==
623 (that.mUnwantedNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES));
Lorenzo Colittif0e9a332016-07-18 18:40:42 +0900624 }
625
Robert Greenwalt1448f052014-04-08 13:41:39 -0700626 /**
paulhu18354322020-01-09 17:08:11 +0800627 * Deduces that all the capabilities it provides are typically provided by restricted networks
628 * or not.
Paul Jensen487ffe72015-07-24 15:57:11 -0400629 *
paulhu18354322020-01-09 17:08:11 +0800630 * @return {@code true} if the network should be restricted.
Paul Jensen487ffe72015-07-24 15:57:11 -0400631 * @hide
632 */
paulhu18354322020-01-09 17:08:11 +0800633 public boolean deduceRestrictedCapability() {
Pavel Maltsev4af91072018-03-07 14:33:22 -0800634 // Check if we have any capability that forces the network to be restricted.
635 final boolean forceRestrictedCapability =
636 (mNetworkCapabilities & FORCE_RESTRICTED_CAPABILITIES) != 0;
637
Robert Greenwalta7e148a2017-04-10 14:32:23 -0700638 // Verify there aren't any unrestricted capabilities. If there are we say
Pavel Maltsev4af91072018-03-07 14:33:22 -0800639 // the whole thing is unrestricted unless it is forced to be restricted.
Robert Greenwalta7e148a2017-04-10 14:32:23 -0700640 final boolean hasUnrestrictedCapabilities =
Pavel Maltsev4af91072018-03-07 14:33:22 -0800641 (mNetworkCapabilities & UNRESTRICTED_CAPABILITIES) != 0;
Robert Greenwalta7e148a2017-04-10 14:32:23 -0700642
643 // Must have at least some restricted capabilities.
644 final boolean hasRestrictedCapabilities =
Pavel Maltsev4af91072018-03-07 14:33:22 -0800645 (mNetworkCapabilities & RESTRICTED_CAPABILITIES) != 0;
Robert Greenwalta7e148a2017-04-10 14:32:23 -0700646
paulhu18354322020-01-09 17:08:11 +0800647 return forceRestrictedCapability
648 || (hasRestrictedCapabilities && !hasUnrestrictedCapabilities);
649 }
650
651 /**
652 * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if deducing the network is restricted.
653 *
654 * @hide
655 */
656 public void maybeMarkCapabilitiesRestricted() {
657 if (deduceRestrictedCapability()) {
Paul Jensen487ffe72015-07-24 15:57:11 -0400658 removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
Paul Jensenaae613d2015-08-19 11:06:15 -0400659 }
Paul Jensen487ffe72015-07-24 15:57:11 -0400660 }
661
662 /**
Chalard Jean09c48e42020-03-25 10:33:55 +0000663 * Test networks have strong restrictions on what capabilities they can have. Enforce these
664 * restrictions.
665 * @hide
666 */
667 public void restrictCapabilitesForTestNetwork() {
668 final long originalCapabilities = mNetworkCapabilities;
669 final NetworkSpecifier originalSpecifier = mNetworkSpecifier;
670 clearAll();
671 // Reset the transports to only contain TRANSPORT_TEST.
672 mTransportTypes = (1 << TRANSPORT_TEST);
673 mNetworkCapabilities = originalCapabilities & TEST_NETWORKS_ALLOWED_CAPABILITIES;
674 mNetworkSpecifier = originalSpecifier;
675 }
676
677 /**
Robert Greenwalt1448f052014-04-08 13:41:39 -0700678 * Representing the transport type. Apps should generally not care about transport. A
679 * request for a fast internet connection could be satisfied by a number of different
680 * transports. If any are specified here it will be satisfied a Network that matches
681 * any of them. If a caller doesn't care about the transport it should not specify any.
682 */
683 private long mTransportTypes;
684
Jeff Sharkeyde570312017-10-24 21:25:50 -0600685 /** @hide */
686 @Retention(RetentionPolicy.SOURCE)
687 @IntDef(prefix = { "TRANSPORT_" }, value = {
688 TRANSPORT_CELLULAR,
689 TRANSPORT_WIFI,
690 TRANSPORT_BLUETOOTH,
691 TRANSPORT_ETHERNET,
692 TRANSPORT_VPN,
693 TRANSPORT_WIFI_AWARE,
694 TRANSPORT_LOWPAN,
Benedict Wong89ce5e32018-11-14 17:40:55 -0800695 TRANSPORT_TEST,
Jeff Sharkeyde570312017-10-24 21:25:50 -0600696 })
697 public @interface Transport { }
698
Robert Greenwalt1448f052014-04-08 13:41:39 -0700699 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700700 * Indicates this network uses a Cellular transport.
Robert Greenwalt1448f052014-04-08 13:41:39 -0700701 */
702 public static final int TRANSPORT_CELLULAR = 0;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700703
704 /**
705 * Indicates this network uses a Wi-Fi transport.
706 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700707 public static final int TRANSPORT_WIFI = 1;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700708
709 /**
710 * Indicates this network uses a Bluetooth transport.
711 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700712 public static final int TRANSPORT_BLUETOOTH = 2;
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700713
714 /**
715 * Indicates this network uses an Ethernet transport.
716 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700717 public static final int TRANSPORT_ETHERNET = 3;
718
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400719 /**
720 * Indicates this network uses a VPN transport.
721 */
722 public static final int TRANSPORT_VPN = 4;
723
Etan Cohen305ea282016-06-20 09:27:12 -0700724 /**
Etan Cohen0849ded2016-10-26 11:22:06 -0700725 * Indicates this network uses a Wi-Fi Aware transport.
Etan Cohen305ea282016-06-20 09:27:12 -0700726 */
Etan Cohen0849ded2016-10-26 11:22:06 -0700727 public static final int TRANSPORT_WIFI_AWARE = 5;
Etan Cohen305ea282016-06-20 09:27:12 -0700728
Robert Quattlebaum5f915762017-05-15 15:53:29 -0700729 /**
730 * Indicates this network uses a LoWPAN transport.
Robert Quattlebaum5f915762017-05-15 15:53:29 -0700731 */
732 public static final int TRANSPORT_LOWPAN = 6;
733
Benedict Wong89ce5e32018-11-14 17:40:55 -0800734 /**
735 * Indicates this network uses a Test-only virtual interface as a transport.
736 *
737 * @hide
738 */
739 @TestApi
740 public static final int TRANSPORT_TEST = 7;
741
Hugo Benichi6a9bb8e2017-03-15 23:05:01 +0900742 /** @hide */
743 public static final int MIN_TRANSPORT = TRANSPORT_CELLULAR;
744 /** @hide */
Benedict Wong89ce5e32018-11-14 17:40:55 -0800745 public static final int MAX_TRANSPORT = TRANSPORT_TEST;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700746
Hugo Benichi16f0a942017-06-20 14:07:59 +0900747 /** @hide */
Jeff Sharkeyde570312017-10-24 21:25:50 -0600748 public static boolean isValidTransport(@Transport int transportType) {
Hugo Benichi16f0a942017-06-20 14:07:59 +0900749 return (MIN_TRANSPORT <= transportType) && (transportType <= MAX_TRANSPORT);
750 }
751
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900752 private static final String[] TRANSPORT_NAMES = {
753 "CELLULAR",
754 "WIFI",
755 "BLUETOOTH",
756 "ETHERNET",
757 "VPN",
Robert Quattlebaum5f915762017-05-15 15:53:29 -0700758 "WIFI_AWARE",
Benedict Wong89ce5e32018-11-14 17:40:55 -0800759 "LOWPAN",
760 "TEST"
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900761 };
762
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700763 /**
764 * Adds the given transport type to this {@code NetworkCapability} instance.
Chalard Jeane5e38502020-03-18 15:58:50 +0900765 * Multiple transports may be applied. Note that when searching
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700766 * for a network to satisfy a request, any listed in the request will satisfy the request.
767 * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a
768 * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network
769 * to be selected. This is logically different than
770 * {@code NetworkCapabilities.NET_CAPABILITY_*} listed above.
771 *
Jeff Sharkeyde570312017-10-24 21:25:50 -0600772 * @param transportType the transport type to be added.
Pierre Imaic8419a82016-03-22 17:54:54 +0900773 * @return This NetworkCapabilities instance, to facilitate chaining.
Chalard Jeane5e38502020-03-18 15:58:50 +0900774 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700775 */
paulhud9736de2019-03-08 16:35:20 +0800776 public @NonNull NetworkCapabilities addTransportType(@Transport int transportType) {
Hugo Benichi16f0a942017-06-20 14:07:59 +0900777 checkValidTransportType(transportType);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700778 mTransportTypes |= 1 << transportType;
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700779 setNetworkSpecifier(mNetworkSpecifier); // used for exception checking
Robert Greenwalt7569f182014-06-08 16:42:59 -0700780 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700781 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700782
783 /**
784 * Removes (if found) the given transport from this {@code NetworkCapability} instance.
785 *
Jeff Sharkeyde570312017-10-24 21:25:50 -0600786 * @param transportType the transport type to be removed.
Pierre Imaic8419a82016-03-22 17:54:54 +0900787 * @return This NetworkCapabilities instance, to facilitate chaining.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700788 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700789 */
paulhud9736de2019-03-08 16:35:20 +0800790 public @NonNull NetworkCapabilities removeTransportType(@Transport int transportType) {
Hugo Benichi16f0a942017-06-20 14:07:59 +0900791 checkValidTransportType(transportType);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700792 mTransportTypes &= ~(1 << transportType);
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -0700793 setNetworkSpecifier(mNetworkSpecifier); // used for exception checking
Robert Greenwalt7569f182014-06-08 16:42:59 -0700794 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700795 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700796
797 /**
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600798 * Sets (or clears) the given transport on this {@link NetworkCapabilities}
799 * instance.
800 *
801 * @hide
802 */
paulhud9736de2019-03-08 16:35:20 +0800803 public @NonNull NetworkCapabilities setTransportType(@Transport int transportType,
804 boolean value) {
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600805 if (value) {
806 addTransportType(transportType);
807 } else {
808 removeTransportType(transportType);
809 }
810 return this;
811 }
812
813 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700814 * Gets all the transports set on this {@code NetworkCapability} instance.
815 *
Jeff Sharkeyde570312017-10-24 21:25:50 -0600816 * @return an array of transport type values for this instance.
Robert Greenwalt7569f182014-06-08 16:42:59 -0700817 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700818 */
Jeff Sharkeya5ee62f2018-05-14 13:49:07 -0600819 @TestApi
Remi NGUYEN VAN94a05572019-01-20 12:38:10 +0900820 @SystemApi
paulhud9736de2019-03-08 16:35:20 +0800821 @NonNull public @Transport int[] getTransportTypes() {
Hugo Benichi9910dbc2017-03-22 18:29:58 +0900822 return BitUtils.unpackBits(mTransportTypes);
Robert Greenwalt1448f052014-04-08 13:41:39 -0700823 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700824
825 /**
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600826 * Sets all the transports set on this {@code NetworkCapability} instance.
Jeff Sharkey49bcd602017-11-09 13:11:50 -0700827 * This overwrites any existing transports.
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600828 *
829 * @hide
830 */
831 public void setTransportTypes(@Transport int[] transportTypes) {
832 mTransportTypes = BitUtils.packBits(transportTypes);
833 }
834
835 /**
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700836 * Tests for the presence of a transport on this instance.
837 *
Jeff Sharkeyde570312017-10-24 21:25:50 -0600838 * @param transportType the transport type to be tested for.
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700839 * @return {@code true} if set on this instance.
840 */
Jeff Sharkeyde570312017-10-24 21:25:50 -0600841 public boolean hasTransport(@Transport int transportType) {
Hugo Benichi16f0a942017-06-20 14:07:59 +0900842 return isValidTransport(transportType) && ((mTransportTypes & (1 << transportType)) != 0);
Robert Greenwalt5c55e332014-05-08 00:02:04 -0700843 }
Robert Greenwalt1448f052014-04-08 13:41:39 -0700844
845 private void combineTransportTypes(NetworkCapabilities nc) {
846 this.mTransportTypes |= nc.mTransportTypes;
847 }
Hugo Benichieae7a222017-07-25 11:40:56 +0900848
Robert Greenwalt1448f052014-04-08 13:41:39 -0700849 private boolean satisfiedByTransportTypes(NetworkCapabilities nc) {
850 return ((this.mTransportTypes == 0) ||
851 ((this.mTransportTypes & nc.mTransportTypes) != 0));
852 }
Hugo Benichieae7a222017-07-25 11:40:56 +0900853
Robert Greenwalt06314e42014-10-29 14:04:06 -0700854 /** @hide */
855 public boolean equalsTransportTypes(NetworkCapabilities nc) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700856 return (nc.mTransportTypes == this.mTransportTypes);
857 }
858
859 /**
Roshan Piuse38acab2020-01-16 12:17:17 -0800860 * UID of the app that owns this network, or Process#INVALID_UID if none/unknown.
Chalard Jeanf474fc32018-01-17 15:10:05 +0900861 *
Qingxi Li7cf06622020-01-17 17:54:27 -0800862 * <p>This field keeps track of the UID of the app that created this network and is in charge of
863 * its lifecycle. This could be the UID of apps such as the Wifi network suggestor, the running
864 * VPN, or Carrier Service app managing a cellular data connection.
Qingxi Li9c5d8b92020-01-08 12:51:49 -0800865 *
866 * <p>For NetworkCapability instances being sent from ConnectivityService, this value MUST be
867 * reset to Process.INVALID_UID unless all the following conditions are met:
868 *
869 * <ol>
870 * <li>The destination app is the network owner
871 * <li>The destination app has the ACCESS_FINE_LOCATION permission granted
872 * <li>The user's location toggle is on
873 * </ol>
874 *
875 * This is because the owner UID is location-sensitive. The apps that request a network could
876 * know where the device is if they can tell for sure the system has connected to the network
877 * they requested.
878 *
879 * <p>This is populated by the network agents and for the NetworkCapabilities instance sent by
880 * an app to the System Server, the value MUST be reset to Process.INVALID_UID by the system
881 * server.
Chalard Jeanf474fc32018-01-17 15:10:05 +0900882 */
Qingxi Li7cf06622020-01-17 17:54:27 -0800883 private int mOwnerUid = Process.INVALID_UID;
Chalard Jeanf474fc32018-01-17 15:10:05 +0900884
885 /**
Qingxi Li7cf06622020-01-17 17:54:27 -0800886 * Set the UID of the owner app.
Chalard Jeane5e38502020-03-18 15:58:50 +0900887 * @hide
Chalard Jeanf474fc32018-01-17 15:10:05 +0900888 */
Roshan Piuse38acab2020-01-16 12:17:17 -0800889 public @NonNull NetworkCapabilities setOwnerUid(final int uid) {
Qingxi Li7cf06622020-01-17 17:54:27 -0800890 mOwnerUid = uid;
Roshan Piuse38acab2020-01-16 12:17:17 -0800891 return this;
Chalard Jeanf474fc32018-01-17 15:10:05 +0900892 }
893
Qingxi Li7cf06622020-01-17 17:54:27 -0800894 /**
Qingxi Li9c5d8b92020-01-08 12:51:49 -0800895 * Retrieves the UID of the app that owns this network.
896 *
897 * <p>For user privacy reasons, this field will only be populated if:
898 *
899 * <ol>
900 * <li>The calling app is the network owner
901 * <li>The calling app has the ACCESS_FINE_LOCATION permission granted
902 * <li>The user's location toggle is on
903 * </ol>
904 *
Chalard Jeane5e38502020-03-18 15:58:50 +0900905 * Instances of NetworkCapabilities sent to apps without the appropriate permissions will
906 * have this field cleared out.
Qingxi Li7cf06622020-01-17 17:54:27 -0800907 */
908 public int getOwnerUid() {
909 return mOwnerUid;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000910 }
911
Chalard Jeanf474fc32018-01-17 15:10:05 +0900912 /**
Cody Kesting201fc132020-01-17 11:58:36 -0800913 * UIDs of packages that are administrators of this network, or empty if none.
914 *
915 * <p>This field tracks the UIDs of packages that have permission to manage this network.
916 *
917 * <p>Network owners will also be listed as administrators.
918 *
919 * <p>For NetworkCapability instances being sent from the System Server, this value MUST be
920 * empty unless the destination is 1) the System Server, or 2) Telephony. In either case, the
921 * receiving entity must have the ACCESS_FINE_LOCATION permission and target R+.
922 */
Cody Kestingf7ac9962020-03-16 18:15:28 -0700923 private int[] mAdministratorUids = new int[0];
Cody Kesting201fc132020-01-17 11:58:36 -0800924
925 /**
Cody Kestingf7ac9962020-03-16 18:15:28 -0700926 * Sets the int[] of UIDs that are administrators of this network.
Cody Kesting201fc132020-01-17 11:58:36 -0800927 *
928 * <p>UIDs included in administratorUids gain administrator privileges over this Network.
929 * Examples of UIDs that should be included in administratorUids are:
930 * <ul>
931 * <li>Carrier apps with privileges for the relevant subscription
932 * <li>Active VPN apps
933 * <li>Other application groups with a particular Network-related role
934 * </ul>
935 *
936 * <p>In general, user-supplied networks (such as WiFi networks) do not have an administrator.
937 *
Cody Kestinga75e26b2020-01-05 14:06:39 -0800938 * <p>An app is granted owner privileges over Networks that it supplies. The owner UID MUST
939 * always be included in administratorUids.
Cody Kesting201fc132020-01-17 11:58:36 -0800940 *
941 * @param administratorUids the UIDs to be set as administrators of this Network.
942 * @hide
943 */
Qingxi Li9c5d8b92020-01-08 12:51:49 -0800944 @NonNull
Cody Kestingf7ac9962020-03-16 18:15:28 -0700945 public NetworkCapabilities setAdministratorUids(@NonNull final int[] administratorUids) {
946 mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length);
Roshan Piuse38acab2020-01-16 12:17:17 -0800947 return this;
Cody Kesting201fc132020-01-17 11:58:36 -0800948 }
949
950 /**
Cody Kestingf7ac9962020-03-16 18:15:28 -0700951 * Retrieves the UIDs that are administrators of this Network.
Cody Kesting201fc132020-01-17 11:58:36 -0800952 *
Cody Kestingf7ac9962020-03-16 18:15:28 -0700953 * @return the int[] of UIDs that are administrators of this Network
Cody Kesting201fc132020-01-17 11:58:36 -0800954 * @hide
955 */
956 @NonNull
957 @SystemApi
Chalard Jeane5e38502020-03-18 15:58:50 +0900958 @TestApi
Cody Kestingf7ac9962020-03-16 18:15:28 -0700959 public int[] getAdministratorUids() {
960 return Arrays.copyOf(mAdministratorUids, mAdministratorUids.length);
Cody Kesting201fc132020-01-17 11:58:36 -0800961 }
962
963 /**
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600964 * Value indicating that link bandwidth is unspecified.
965 * @hide
966 */
967 public static final int LINK_BANDWIDTH_UNSPECIFIED = 0;
968
969 /**
Robert Greenwalt1448f052014-04-08 13:41:39 -0700970 * Passive link bandwidth. This is a rough guide of the expected peak bandwidth
971 * for the first hop on the given transport. It is not measured, but may take into account
972 * link parameters (Radio technology, allocated channels, etc).
973 */
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600974 private int mLinkUpBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
975 private int mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700976
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700977 /**
978 * Sets the upstream bandwidth for this network in Kbps. This always only refers to
979 * the estimated first hop transport bandwidth.
980 * <p>
Chalard Jeane5e38502020-03-18 15:58:50 +0900981 * {@see Builder#setLinkUpstreamBandwidthKbps}
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700982 *
983 * @param upKbps the estimated first hop upstream (device to network) bandwidth.
Chalard Jeane5e38502020-03-18 15:58:50 +0900984 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700985 */
paulhud9736de2019-03-08 16:35:20 +0800986 public @NonNull NetworkCapabilities setLinkUpstreamBandwidthKbps(int upKbps) {
Robert Greenwalt1448f052014-04-08 13:41:39 -0700987 mLinkUpBandwidthKbps = upKbps;
Jeff Sharkey72f9c422017-10-27 17:22:59 -0600988 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -0700989 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -0700990
991 /**
992 * Retrieves the upstream bandwidth for this network in Kbps. This always only refers to
993 * the estimated first hop transport bandwidth.
994 *
995 * @return The estimated first hop upstream (device to network) bandwidth.
996 */
Robert Greenwalt1448f052014-04-08 13:41:39 -0700997 public int getLinkUpstreamBandwidthKbps() {
998 return mLinkUpBandwidthKbps;
999 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -07001000
1001 /**
1002 * Sets the downstream bandwidth for this network in Kbps. This always only refers to
1003 * the estimated first hop transport bandwidth.
1004 * <p>
Chalard Jeane5e38502020-03-18 15:58:50 +09001005 * {@see Builder#setLinkUpstreamBandwidthKbps}
Robert Greenwalt01d004e2014-05-18 15:24:21 -07001006 *
1007 * @param downKbps the estimated first hop downstream (network to device) bandwidth.
Chalard Jeane5e38502020-03-18 15:58:50 +09001008 * @hide
Robert Greenwalt01d004e2014-05-18 15:24:21 -07001009 */
paulhud9736de2019-03-08 16:35:20 +08001010 public @NonNull NetworkCapabilities setLinkDownstreamBandwidthKbps(int downKbps) {
Robert Greenwalt1448f052014-04-08 13:41:39 -07001011 mLinkDownBandwidthKbps = downKbps;
Jeff Sharkey72f9c422017-10-27 17:22:59 -06001012 return this;
Robert Greenwalt1448f052014-04-08 13:41:39 -07001013 }
Robert Greenwalt01d004e2014-05-18 15:24:21 -07001014
1015 /**
1016 * Retrieves the downstream bandwidth for this network in Kbps. This always only refers to
1017 * the estimated first hop transport bandwidth.
1018 *
1019 * @return The estimated first hop downstream (network to device) bandwidth.
1020 */
Robert Greenwalt1448f052014-04-08 13:41:39 -07001021 public int getLinkDownstreamBandwidthKbps() {
1022 return mLinkDownBandwidthKbps;
1023 }
1024
1025 private void combineLinkBandwidths(NetworkCapabilities nc) {
1026 this.mLinkUpBandwidthKbps =
1027 Math.max(this.mLinkUpBandwidthKbps, nc.mLinkUpBandwidthKbps);
1028 this.mLinkDownBandwidthKbps =
1029 Math.max(this.mLinkDownBandwidthKbps, nc.mLinkDownBandwidthKbps);
1030 }
1031 private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) {
1032 return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps ||
1033 this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps);
1034 }
1035 private boolean equalsLinkBandwidths(NetworkCapabilities nc) {
1036 return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps &&
1037 this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
1038 }
Jeff Sharkey72f9c422017-10-27 17:22:59 -06001039 /** @hide */
1040 public static int minBandwidth(int a, int b) {
1041 if (a == LINK_BANDWIDTH_UNSPECIFIED) {
1042 return b;
1043 } else if (b == LINK_BANDWIDTH_UNSPECIFIED) {
1044 return a;
1045 } else {
1046 return Math.min(a, b);
1047 }
1048 }
1049 /** @hide */
1050 public static int maxBandwidth(int a, int b) {
1051 return Math.max(a, b);
1052 }
Robert Greenwalt1448f052014-04-08 13:41:39 -07001053
Etan Cohena7434272017-04-03 12:17:51 -07001054 private NetworkSpecifier mNetworkSpecifier = null;
Etan Cohenca9fb562018-11-27 07:32:39 -08001055 private TransportInfo mTransportInfo = null;
Etan Cohena7434272017-04-03 12:17:51 -07001056
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -07001057 /**
1058 * Sets the optional bearer specific network specifier.
1059 * This has no meaning if a single transport is also not specified, so calling
1060 * this without a single transport set will generate an exception, as will
1061 * subsequently adding or removing transports after this is set.
1062 * </p>
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -07001063 *
Etan Cohena7434272017-04-03 12:17:51 -07001064 * @param networkSpecifier A concrete, parcelable framework class that extends
1065 * NetworkSpecifier.
Pierre Imaic8419a82016-03-22 17:54:54 +09001066 * @return This NetworkCapabilities instance, to facilitate chaining.
Chalard Jeane5e38502020-03-18 15:58:50 +09001067 * @hide
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -07001068 */
Aaron Huange6b62392019-09-20 22:52:54 +08001069 public @NonNull NetworkCapabilities setNetworkSpecifier(
1070 @NonNull NetworkSpecifier networkSpecifier) {
Etan Cohena7434272017-04-03 12:17:51 -07001071 if (networkSpecifier != null && Long.bitCount(mTransportTypes) != 1) {
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -07001072 throw new IllegalStateException("Must have a single transport specified to use " +
1073 "setNetworkSpecifier");
1074 }
Etan Cohena7434272017-04-03 12:17:51 -07001075
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -07001076 mNetworkSpecifier = networkSpecifier;
Etan Cohena7434272017-04-03 12:17:51 -07001077
Pierre Imaic8419a82016-03-22 17:54:54 +09001078 return this;
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -07001079 }
1080
1081 /**
Etan Cohenca9fb562018-11-27 07:32:39 -08001082 * Sets the optional transport specific information.
1083 *
1084 * @param transportInfo A concrete, parcelable framework class that extends
1085 * {@link TransportInfo}.
1086 * @return This NetworkCapabilities instance, to facilitate chaining.
1087 * @hide
1088 */
Aaron Huange6b62392019-09-20 22:52:54 +08001089 public @NonNull NetworkCapabilities setTransportInfo(@NonNull TransportInfo transportInfo) {
Etan Cohenca9fb562018-11-27 07:32:39 -08001090 mTransportInfo = transportInfo;
1091 return this;
1092 }
1093
1094 /**
paulhud9736de2019-03-08 16:35:20 +08001095 * Gets the optional bearer specific network specifier. May be {@code null} if not set.
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -07001096 *
Etan Cohena7434272017-04-03 12:17:51 -07001097 * @return The optional {@link NetworkSpecifier} specifying the bearer specific network
Chalard Jeane5e38502020-03-18 15:58:50 +09001098 * specifier or {@code null}.
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -07001099 */
paulhud9736de2019-03-08 16:35:20 +08001100 public @Nullable NetworkSpecifier getNetworkSpecifier() {
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -07001101 return mNetworkSpecifier;
1102 }
1103
Etan Cohenca9fb562018-11-27 07:32:39 -08001104 /**
1105 * Returns a transport-specific information container. The application may cast this
1106 * container to a concrete sub-class based on its knowledge of the network request. The
1107 * application should be able to deal with a {@code null} return value or an invalid case,
Etan Cohenbd648ce2018-12-10 14:07:15 -08001108 * e.g. use {@code instanceof} operator to verify expected type.
Etan Cohenca9fb562018-11-27 07:32:39 -08001109 *
1110 * @return A concrete implementation of the {@link TransportInfo} class or null if not
1111 * available for the network.
1112 */
1113 @Nullable public TransportInfo getTransportInfo() {
1114 return mTransportInfo;
1115 }
1116
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -07001117 private void combineSpecifiers(NetworkCapabilities nc) {
Etan Cohena7434272017-04-03 12:17:51 -07001118 if (mNetworkSpecifier != null && !mNetworkSpecifier.equals(nc.mNetworkSpecifier)) {
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -07001119 throw new IllegalStateException("Can't combine two networkSpecifiers");
1120 }
Etan Cohena7434272017-04-03 12:17:51 -07001121 setNetworkSpecifier(nc.mNetworkSpecifier);
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -07001122 }
Etan Cohena7434272017-04-03 12:17:51 -07001123
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -07001124 private boolean satisfiedBySpecifier(NetworkCapabilities nc) {
Etan Cohena7434272017-04-03 12:17:51 -07001125 return mNetworkSpecifier == null || mNetworkSpecifier.satisfiedBy(nc.mNetworkSpecifier)
1126 || nc.mNetworkSpecifier instanceof MatchAllNetworkSpecifier;
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -07001127 }
Etan Cohena7434272017-04-03 12:17:51 -07001128
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -07001129 private boolean equalsSpecifier(NetworkCapabilities nc) {
Etan Cohena7434272017-04-03 12:17:51 -07001130 return Objects.equals(mNetworkSpecifier, nc.mNetworkSpecifier);
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -07001131 }
1132
Etan Cohenca9fb562018-11-27 07:32:39 -08001133 private void combineTransportInfos(NetworkCapabilities nc) {
1134 if (mTransportInfo != null && !mTransportInfo.equals(nc.mTransportInfo)) {
1135 throw new IllegalStateException("Can't combine two TransportInfos");
1136 }
1137 setTransportInfo(nc.mTransportInfo);
1138 }
1139
1140 private boolean equalsTransportInfo(NetworkCapabilities nc) {
1141 return Objects.equals(mTransportInfo, nc.mTransportInfo);
1142 }
1143
Robert Greenwalt1448f052014-04-08 13:41:39 -07001144 /**
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09001145 * Magic value that indicates no signal strength provided. A request specifying this value is
1146 * always satisfied.
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09001147 */
1148 public static final int SIGNAL_STRENGTH_UNSPECIFIED = Integer.MIN_VALUE;
1149
1150 /**
1151 * Signal strength. This is a signed integer, and higher values indicate better signal.
1152 * The exact units are bearer-dependent. For example, Wi-Fi uses RSSI.
1153 */
paulhud9736de2019-03-08 16:35:20 +08001154 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
Jeff Sharkey49bcd602017-11-09 13:11:50 -07001155 private int mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09001156
1157 /**
1158 * Sets the signal strength. This is a signed integer, with higher values indicating a stronger
1159 * signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same RSSI units
Chalard Jeanb03a6222018-04-11 21:09:10 +09001160 * reported by wifi code.
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09001161 * <p>
1162 * Note that when used to register a network callback, this specifies the minimum acceptable
1163 * signal strength. When received as the state of an existing network it specifies the current
1164 * value. A value of code SIGNAL_STRENGTH_UNSPECIFIED} means no value when received and has no
1165 * effect when requesting a callback.
1166 *
1167 * @param signalStrength the bearer-specific signal strength.
Chalard Jeane5e38502020-03-18 15:58:50 +09001168 * @hide
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09001169 */
paulhud9736de2019-03-08 16:35:20 +08001170 public @NonNull NetworkCapabilities setSignalStrength(int signalStrength) {
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09001171 mSignalStrength = signalStrength;
Jeff Sharkey72f9c422017-10-27 17:22:59 -06001172 return this;
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09001173 }
1174
1175 /**
1176 * Returns {@code true} if this object specifies a signal strength.
1177 *
1178 * @hide
1179 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +01001180 @UnsupportedAppUsage
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09001181 public boolean hasSignalStrength() {
1182 return mSignalStrength > SIGNAL_STRENGTH_UNSPECIFIED;
1183 }
1184
1185 /**
1186 * Retrieves the signal strength.
1187 *
1188 * @return The bearer-specific signal strength.
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09001189 */
1190 public int getSignalStrength() {
1191 return mSignalStrength;
1192 }
1193
1194 private void combineSignalStrength(NetworkCapabilities nc) {
1195 this.mSignalStrength = Math.max(this.mSignalStrength, nc.mSignalStrength);
1196 }
1197
1198 private boolean satisfiedBySignalStrength(NetworkCapabilities nc) {
1199 return this.mSignalStrength <= nc.mSignalStrength;
1200 }
1201
1202 private boolean equalsSignalStrength(NetworkCapabilities nc) {
1203 return this.mSignalStrength == nc.mSignalStrength;
1204 }
1205
1206 /**
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001207 * List of UIDs this network applies to. No restriction if null.
1208 * <p>
Chalard Jeanb552c462018-02-21 18:43:54 +09001209 * For networks, mUids represent the list of network this applies to, and null means this
1210 * network applies to all UIDs.
1211 * For requests, mUids is the list of UIDs this network MUST apply to to match ; ALL UIDs
1212 * must be included in a network so that they match. As an exception to the general rule,
1213 * a null mUids field for requests mean "no requirements" rather than what the general rule
1214 * would suggest ("must apply to all UIDs") : this is because this has shown to be what users
1215 * of this API expect in practice. A network that must match all UIDs can still be
1216 * expressed with a set ranging the entire set of possible UIDs.
1217 * <p>
1218 * mUids is typically (and at this time, only) used by VPN. This network is only available to
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001219 * the UIDs in this list, and it is their default network. Apps in this list that wish to
1220 * bypass the VPN can do so iff the VPN app allows them to or if they are privileged. If this
1221 * member is null, then the network is not restricted by app UID. If it's an empty list, then
1222 * it means nobody can use it.
Chalard Jeanf474fc32018-01-17 15:10:05 +09001223 * As a special exception, the app managing this network (as identified by its UID stored in
Qingxi Li7cf06622020-01-17 17:54:27 -08001224 * mOwnerUid) can always see this network. This is embodied by a special check in
Chalard Jeanf474fc32018-01-17 15:10:05 +09001225 * satisfiedByUids. That still does not mean the network necessarily <strong>applies</strong>
1226 * to the app that manages it as determined by #appliesToUid.
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001227 * <p>
1228 * Please note that in principle a single app can be associated with multiple UIDs because
1229 * each app will have a different UID when it's run as a different (macro-)user. A single
1230 * macro user can only have a single active VPN app at any given time however.
1231 * <p>
1232 * Also please be aware this class does not try to enforce any normalization on this. Callers
1233 * can only alter the UIDs by setting them wholesale : this class does not provide any utility
1234 * to add or remove individual UIDs or ranges. If callers have any normalization needs on
1235 * their own (like requiring sortedness or no overlap) they need to enforce it
1236 * themselves. Some of the internal methods also assume this is normalized as in no adjacent
1237 * or overlapping ranges are present.
1238 *
1239 * @hide
1240 */
Chalard Jean477e36c2018-01-25 09:41:51 +09001241 private ArraySet<UidRange> mUids = null;
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001242
1243 /**
Chalard Jeandda156a2018-01-10 21:19:32 +09001244 * Convenience method to set the UIDs this network applies to to a single UID.
1245 * @hide
1246 */
paulhud9736de2019-03-08 16:35:20 +08001247 public @NonNull NetworkCapabilities setSingleUid(int uid) {
Chalard Jeandda156a2018-01-10 21:19:32 +09001248 final ArraySet<UidRange> identity = new ArraySet<>(1);
1249 identity.add(new UidRange(uid, uid));
1250 setUids(identity);
1251 return this;
1252 }
1253
1254 /**
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001255 * Set the list of UIDs this network applies to.
1256 * This makes a copy of the set so that callers can't modify it after the call.
1257 * @hide
1258 */
paulhud9736de2019-03-08 16:35:20 +08001259 public @NonNull NetworkCapabilities setUids(Set<UidRange> uids) {
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001260 if (null == uids) {
1261 mUids = null;
1262 } else {
1263 mUids = new ArraySet<>(uids);
1264 }
1265 return this;
1266 }
1267
1268 /**
1269 * Get the list of UIDs this network applies to.
1270 * This returns a copy of the set so that callers can't modify the original object.
1271 * @hide
1272 */
paulhud9736de2019-03-08 16:35:20 +08001273 public @Nullable Set<UidRange> getUids() {
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001274 return null == mUids ? null : new ArraySet<>(mUids);
1275 }
1276
1277 /**
1278 * Test whether this network applies to this UID.
1279 * @hide
1280 */
1281 public boolean appliesToUid(int uid) {
1282 if (null == mUids) return true;
1283 for (UidRange range : mUids) {
1284 if (range.contains(uid)) {
1285 return true;
1286 }
1287 }
1288 return false;
1289 }
1290
1291 /**
Chalard Jeanb03a6222018-04-11 21:09:10 +09001292 * Tests if the set of UIDs that this network applies to is the same as the passed network.
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001293 * <p>
1294 * This test only checks whether equal range objects are in both sets. It will
1295 * return false if the ranges are not exactly the same, even if the covered UIDs
1296 * are for an equivalent result.
1297 * <p>
1298 * Note that this method is not very optimized, which is fine as long as it's not used very
1299 * often.
1300 * <p>
1301 * nc is assumed nonnull.
1302 *
1303 * @hide
1304 */
1305 @VisibleForTesting
paulhud9736de2019-03-08 16:35:20 +08001306 public boolean equalsUids(@NonNull NetworkCapabilities nc) {
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001307 Set<UidRange> comparedUids = nc.mUids;
1308 if (null == comparedUids) return null == mUids;
1309 if (null == mUids) return false;
1310 // Make a copy so it can be mutated to check that all ranges in mUids
1311 // also are in uids.
1312 final Set<UidRange> uids = new ArraySet<>(mUids);
1313 for (UidRange range : comparedUids) {
1314 if (!uids.contains(range)) {
1315 return false;
1316 }
1317 uids.remove(range);
1318 }
1319 return uids.isEmpty();
1320 }
1321
1322 /**
1323 * Test whether the passed NetworkCapabilities satisfies the UIDs this capabilities require.
1324 *
Chalard Jeanf474fc32018-01-17 15:10:05 +09001325 * This method is called on the NetworkCapabilities embedded in a request with the
1326 * capabilities of an available network. It checks whether all the UIDs from this listen
1327 * (representing the UIDs that must have access to the network) are satisfied by the UIDs
1328 * in the passed nc (representing the UIDs that this network is available to).
1329 * <p>
1330 * As a special exception, the UID that created the passed network (as represented by its
Qingxi Li7cf06622020-01-17 17:54:27 -08001331 * mOwnerUid field) always satisfies a NetworkRequest requiring it (of LISTEN
Chalard Jeanf474fc32018-01-17 15:10:05 +09001332 * or REQUEST types alike), even if the network does not apply to it. That is so a VPN app
1333 * can see its own network when it listens for it.
1334 * <p>
1335 * nc is assumed nonnull. Else, NPE.
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001336 * @see #appliesToUid
1337 * @hide
1338 */
paulhud9736de2019-03-08 16:35:20 +08001339 public boolean satisfiedByUids(@NonNull NetworkCapabilities nc) {
Chalard Jeanb552c462018-02-21 18:43:54 +09001340 if (null == nc.mUids || null == mUids) return true; // The network satisfies everything.
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001341 for (UidRange requiredRange : mUids) {
Qingxi Li7cf06622020-01-17 17:54:27 -08001342 if (requiredRange.contains(nc.mOwnerUid)) return true;
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001343 if (!nc.appliesToUidRange(requiredRange)) {
1344 return false;
1345 }
1346 }
1347 return true;
1348 }
1349
1350 /**
1351 * Returns whether this network applies to the passed ranges.
1352 * This assumes that to apply, the passed range has to be entirely contained
1353 * within one of the ranges this network applies to. If the ranges are not normalized,
1354 * this method may return false even though all required UIDs are covered because no
1355 * single range contained them all.
1356 * @hide
1357 */
1358 @VisibleForTesting
paulhud9736de2019-03-08 16:35:20 +08001359 public boolean appliesToUidRange(@Nullable UidRange requiredRange) {
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001360 if (null == mUids) return true;
1361 for (UidRange uidRange : mUids) {
1362 if (uidRange.containsRange(requiredRange)) {
1363 return true;
1364 }
1365 }
1366 return false;
1367 }
1368
1369 /**
1370 * Combine the UIDs this network currently applies to with the UIDs the passed
1371 * NetworkCapabilities apply to.
1372 * nc is assumed nonnull.
1373 */
paulhud9736de2019-03-08 16:35:20 +08001374 private void combineUids(@NonNull NetworkCapabilities nc) {
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001375 if (null == nc.mUids || null == mUids) {
1376 mUids = null;
1377 return;
1378 }
1379 mUids.addAll(nc.mUids);
1380 }
1381
Chalard Jeanb03a6222018-04-11 21:09:10 +09001382
1383 /**
1384 * The SSID of the network, or null if not applicable or unknown.
1385 * <p>
1386 * This is filled in by wifi code.
1387 * @hide
1388 */
1389 private String mSSID;
1390
1391 /**
1392 * Sets the SSID of this network.
1393 * @hide
1394 */
paulhud9736de2019-03-08 16:35:20 +08001395 public @NonNull NetworkCapabilities setSSID(@Nullable String ssid) {
Chalard Jeanb03a6222018-04-11 21:09:10 +09001396 mSSID = ssid;
1397 return this;
1398 }
1399
1400 /**
1401 * Gets the SSID of this network, or null if none or unknown.
1402 * @hide
1403 */
Remi NGUYEN VANaa4c5112020-01-22 22:52:53 +09001404 @SystemApi
Chalard Jeane5e38502020-03-18 15:58:50 +09001405 @TestApi
1406 public @Nullable String getSsid() {
Chalard Jeanb03a6222018-04-11 21:09:10 +09001407 return mSSID;
1408 }
1409
1410 /**
1411 * Tests if the SSID of this network is the same as the SSID of the passed network.
1412 * @hide
1413 */
paulhud9736de2019-03-08 16:35:20 +08001414 public boolean equalsSSID(@NonNull NetworkCapabilities nc) {
Chalard Jeanb03a6222018-04-11 21:09:10 +09001415 return Objects.equals(mSSID, nc.mSSID);
1416 }
1417
1418 /**
1419 * Check if the SSID requirements of this object are matched by the passed object.
1420 * @hide
1421 */
paulhud9736de2019-03-08 16:35:20 +08001422 public boolean satisfiedBySSID(@NonNull NetworkCapabilities nc) {
Chalard Jeanb03a6222018-04-11 21:09:10 +09001423 return mSSID == null || mSSID.equals(nc.mSSID);
1424 }
1425
1426 /**
1427 * Combine SSIDs of the capabilities.
1428 * <p>
1429 * This is only legal if either the SSID of this object is null, or both SSIDs are
1430 * equal.
1431 * @hide
1432 */
paulhud9736de2019-03-08 16:35:20 +08001433 private void combineSSIDs(@NonNull NetworkCapabilities nc) {
Chalard Jeanb03a6222018-04-11 21:09:10 +09001434 if (mSSID != null && !mSSID.equals(nc.mSSID)) {
1435 throw new IllegalStateException("Can't combine two SSIDs");
1436 }
1437 setSSID(nc.mSSID);
1438 }
1439
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001440 /**
Pavel Maltseve18ef262018-03-07 11:13:04 -08001441 * Combine a set of Capabilities to this one. Useful for coming up with the complete set.
1442 * <p>
1443 * Note that this method may break an invariant of having a particular capability in either
1444 * wanted or unwanted lists but never in both. Requests that have the same capability in
1445 * both lists will never be satisfied.
Lorenzo Colitti260a36d2015-07-08 12:49:04 +09001446 * @hide
Robert Greenwalt1448f052014-04-08 13:41:39 -07001447 */
paulhud9736de2019-03-08 16:35:20 +08001448 public void combineCapabilities(@NonNull NetworkCapabilities nc) {
Robert Greenwalt1448f052014-04-08 13:41:39 -07001449 combineNetCapabilities(nc);
1450 combineTransportTypes(nc);
1451 combineLinkBandwidths(nc);
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -07001452 combineSpecifiers(nc);
Etan Cohenca9fb562018-11-27 07:32:39 -08001453 combineTransportInfos(nc);
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09001454 combineSignalStrength(nc);
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001455 combineUids(nc);
Chalard Jeanb03a6222018-04-11 21:09:10 +09001456 combineSSIDs(nc);
Roshan Piuse38acab2020-01-16 12:17:17 -08001457 combineRequestor(nc);
Robert Greenwalt1448f052014-04-08 13:41:39 -07001458 }
1459
1460 /**
Lorenzo Colitti260a36d2015-07-08 12:49:04 +09001461 * Check if our requirements are satisfied by the given {@code NetworkCapabilities}.
1462 *
1463 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
1464 * @param onlyImmutable if {@code true}, do not consider mutable requirements such as link
1465 * bandwidth, signal strength, or validation / captive portal status.
1466 *
1467 * @hide
1468 */
1469 private boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc, boolean onlyImmutable) {
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001470 return (nc != null
1471 && satisfiedByNetCapabilities(nc, onlyImmutable)
1472 && satisfiedByTransportTypes(nc)
1473 && (onlyImmutable || satisfiedByLinkBandwidths(nc))
1474 && satisfiedBySpecifier(nc)
1475 && (onlyImmutable || satisfiedBySignalStrength(nc))
Chalard Jeanb03a6222018-04-11 21:09:10 +09001476 && (onlyImmutable || satisfiedByUids(nc))
Roshan Piuse38acab2020-01-16 12:17:17 -08001477 && (onlyImmutable || satisfiedBySSID(nc)))
1478 && (onlyImmutable || satisfiedByRequestor(nc));
Lorenzo Colitti260a36d2015-07-08 12:49:04 +09001479 }
1480
1481 /**
1482 * Check if our requirements are satisfied by the given {@code NetworkCapabilities}.
1483 *
1484 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
1485 *
1486 * @hide
Robert Greenwalt1448f052014-04-08 13:41:39 -07001487 */
Remi NGUYEN VAN94a05572019-01-20 12:38:10 +09001488 @TestApi
1489 @SystemApi
paulhud9736de2019-03-08 16:35:20 +08001490 public boolean satisfiedByNetworkCapabilities(@Nullable NetworkCapabilities nc) {
Lorenzo Colitti260a36d2015-07-08 12:49:04 +09001491 return satisfiedByNetworkCapabilities(nc, false);
1492 }
1493
1494 /**
1495 * Check if our immutable requirements are satisfied by the given {@code NetworkCapabilities}.
1496 *
1497 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements.
1498 *
1499 * @hide
1500 */
paulhud9736de2019-03-08 16:35:20 +08001501 public boolean satisfiedByImmutableNetworkCapabilities(@Nullable NetworkCapabilities nc) {
Lorenzo Colitti260a36d2015-07-08 12:49:04 +09001502 return satisfiedByNetworkCapabilities(nc, true);
1503 }
1504
1505 /**
1506 * Checks that our immutable capabilities are the same as those of the given
Hugo Benichieae7a222017-07-25 11:40:56 +09001507 * {@code NetworkCapabilities} and return a String describing any difference.
1508 * The returned String is empty if there is no difference.
Lorenzo Colitti260a36d2015-07-08 12:49:04 +09001509 *
1510 * @hide
1511 */
paulhud9736de2019-03-08 16:35:20 +08001512 public String describeImmutableDifferences(@Nullable NetworkCapabilities that) {
Hugo Benichieae7a222017-07-25 11:40:56 +09001513 if (that == null) {
1514 return "other NetworkCapabilities was null";
1515 }
1516
1517 StringJoiner joiner = new StringJoiner(", ");
1518
Hugo Benichieae7a222017-07-25 11:40:56 +09001519 // Ignore NOT_METERED being added or removed as it is effectively dynamic. http://b/63326103
1520 // TODO: properly support NOT_METERED as a mutable and requestable capability.
Hugo Benichi2ecb9402017-08-04 13:18:40 +09001521 final long mask = ~MUTABLE_CAPABILITIES & ~(1 << NET_CAPABILITY_NOT_METERED);
Hugo Benichieae7a222017-07-25 11:40:56 +09001522 long oldImmutableCapabilities = this.mNetworkCapabilities & mask;
1523 long newImmutableCapabilities = that.mNetworkCapabilities & mask;
1524 if (oldImmutableCapabilities != newImmutableCapabilities) {
1525 String before = capabilityNamesOf(BitUtils.unpackBits(oldImmutableCapabilities));
1526 String after = capabilityNamesOf(BitUtils.unpackBits(newImmutableCapabilities));
1527 joiner.add(String.format("immutable capabilities changed: %s -> %s", before, after));
1528 }
1529
1530 if (!equalsSpecifier(that)) {
1531 NetworkSpecifier before = this.getNetworkSpecifier();
1532 NetworkSpecifier after = that.getNetworkSpecifier();
1533 joiner.add(String.format("specifier changed: %s -> %s", before, after));
1534 }
1535
1536 if (!equalsTransportTypes(that)) {
1537 String before = transportNamesOf(this.getTransportTypes());
1538 String after = transportNamesOf(that.getTransportTypes());
1539 joiner.add(String.format("transports changed: %s -> %s", before, after));
1540 }
1541
1542 return joiner.toString();
Robert Greenwalt1448f052014-04-08 13:41:39 -07001543 }
1544
Lorenzo Colittif0e9a332016-07-18 18:40:42 +09001545 /**
1546 * Checks that our requestable capabilities are the same as those of the given
1547 * {@code NetworkCapabilities}.
1548 *
1549 * @hide
1550 */
paulhud9736de2019-03-08 16:35:20 +08001551 public boolean equalRequestableCapabilities(@Nullable NetworkCapabilities nc) {
Lorenzo Colittif0e9a332016-07-18 18:40:42 +09001552 if (nc == null) return false;
1553 return (equalsNetCapabilitiesRequestable(nc) &&
1554 equalsTransportTypes(nc) &&
1555 equalsSpecifier(nc));
1556 }
1557
Robert Greenwalt1448f052014-04-08 13:41:39 -07001558 @Override
paulhud9736de2019-03-08 16:35:20 +08001559 public boolean equals(@Nullable Object obj) {
Robert Greenwalt1448f052014-04-08 13:41:39 -07001560 if (obj == null || (obj instanceof NetworkCapabilities == false)) return false;
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001561 NetworkCapabilities that = (NetworkCapabilities) obj;
Roshan Piuse38acab2020-01-16 12:17:17 -08001562 return equalsNetCapabilities(that)
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001563 && equalsTransportTypes(that)
1564 && equalsLinkBandwidths(that)
1565 && equalsSignalStrength(that)
1566 && equalsSpecifier(that)
Etan Cohenca9fb562018-11-27 07:32:39 -08001567 && equalsTransportInfo(that)
Chalard Jeanb03a6222018-04-11 21:09:10 +09001568 && equalsUids(that)
lucaslin783f2212019-10-22 18:27:33 +08001569 && equalsSSID(that)
Roshan Piuse38acab2020-01-16 12:17:17 -08001570 && equalsPrivateDnsBroken(that)
1571 && equalsRequestor(that);
Robert Greenwalt1448f052014-04-08 13:41:39 -07001572 }
1573
1574 @Override
1575 public int hashCode() {
Pavel Maltsev1cd48da2018-02-01 11:16:02 -08001576 return (int) (mNetworkCapabilities & 0xFFFFFFFF)
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001577 + ((int) (mNetworkCapabilities >> 32) * 3)
Pavel Maltsev1cd48da2018-02-01 11:16:02 -08001578 + ((int) (mUnwantedNetworkCapabilities & 0xFFFFFFFF) * 5)
1579 + ((int) (mUnwantedNetworkCapabilities >> 32) * 7)
1580 + ((int) (mTransportTypes & 0xFFFFFFFF) * 11)
1581 + ((int) (mTransportTypes >> 32) * 13)
1582 + (mLinkUpBandwidthKbps * 17)
1583 + (mLinkDownBandwidthKbps * 19)
1584 + Objects.hashCode(mNetworkSpecifier) * 23
1585 + (mSignalStrength * 29)
Chalard Jeanb03a6222018-04-11 21:09:10 +09001586 + Objects.hashCode(mUids) * 31
Etan Cohenca9fb562018-11-27 07:32:39 -08001587 + Objects.hashCode(mSSID) * 37
lucaslin783f2212019-10-22 18:27:33 +08001588 + Objects.hashCode(mTransportInfo) * 41
Roshan Piuse38acab2020-01-16 12:17:17 -08001589 + Objects.hashCode(mPrivateDnsBroken) * 43
1590 + Objects.hashCode(mRequestorUid) * 47
1591 + Objects.hashCode(mRequestorPackageName) * 53;
Robert Greenwalt1448f052014-04-08 13:41:39 -07001592 }
1593
Wink Saville4e2dea72014-09-20 11:04:03 -07001594 @Override
Robert Greenwalt1448f052014-04-08 13:41:39 -07001595 public int describeContents() {
1596 return 0;
1597 }
Cody Kesting201fc132020-01-17 11:58:36 -08001598
Wink Saville4e2dea72014-09-20 11:04:03 -07001599 @Override
Robert Greenwalt1448f052014-04-08 13:41:39 -07001600 public void writeToParcel(Parcel dest, int flags) {
1601 dest.writeLong(mNetworkCapabilities);
Pavel Maltsev1cd48da2018-02-01 11:16:02 -08001602 dest.writeLong(mUnwantedNetworkCapabilities);
Robert Greenwalt1448f052014-04-08 13:41:39 -07001603 dest.writeLong(mTransportTypes);
1604 dest.writeInt(mLinkUpBandwidthKbps);
1605 dest.writeInt(mLinkDownBandwidthKbps);
Etan Cohena7434272017-04-03 12:17:51 -07001606 dest.writeParcelable((Parcelable) mNetworkSpecifier, flags);
Etan Cohenca9fb562018-11-27 07:32:39 -08001607 dest.writeParcelable((Parcelable) mTransportInfo, flags);
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09001608 dest.writeInt(mSignalStrength);
Chalard Jean477e36c2018-01-25 09:41:51 +09001609 dest.writeArraySet(mUids);
Chalard Jeanb03a6222018-04-11 21:09:10 +09001610 dest.writeString(mSSID);
lucaslin783f2212019-10-22 18:27:33 +08001611 dest.writeBoolean(mPrivateDnsBroken);
Cody Kestingf7ac9962020-03-16 18:15:28 -07001612 dest.writeIntArray(mAdministratorUids);
Qingxi Li7cf06622020-01-17 17:54:27 -08001613 dest.writeInt(mOwnerUid);
Roshan Piuse38acab2020-01-16 12:17:17 -08001614 dest.writeInt(mRequestorUid);
1615 dest.writeString(mRequestorPackageName);
Robert Greenwalt1448f052014-04-08 13:41:39 -07001616 }
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09001617
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07001618 public static final @android.annotation.NonNull Creator<NetworkCapabilities> CREATOR =
Robert Greenwalt1448f052014-04-08 13:41:39 -07001619 new Creator<NetworkCapabilities>() {
Wink Saville4e2dea72014-09-20 11:04:03 -07001620 @Override
Robert Greenwalt1448f052014-04-08 13:41:39 -07001621 public NetworkCapabilities createFromParcel(Parcel in) {
1622 NetworkCapabilities netCap = new NetworkCapabilities();
1623
1624 netCap.mNetworkCapabilities = in.readLong();
Pavel Maltsev1cd48da2018-02-01 11:16:02 -08001625 netCap.mUnwantedNetworkCapabilities = in.readLong();
Robert Greenwalt1448f052014-04-08 13:41:39 -07001626 netCap.mTransportTypes = in.readLong();
1627 netCap.mLinkUpBandwidthKbps = in.readInt();
1628 netCap.mLinkDownBandwidthKbps = in.readInt();
Etan Cohena7434272017-04-03 12:17:51 -07001629 netCap.mNetworkSpecifier = in.readParcelable(null);
Etan Cohenca9fb562018-11-27 07:32:39 -08001630 netCap.mTransportInfo = in.readParcelable(null);
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09001631 netCap.mSignalStrength = in.readInt();
Chalard Jeanecacd5e2017-12-27 14:23:31 +09001632 netCap.mUids = (ArraySet<UidRange>) in.readArraySet(
1633 null /* ClassLoader, null for default */);
Chalard Jeanb03a6222018-04-11 21:09:10 +09001634 netCap.mSSID = in.readString();
lucaslin783f2212019-10-22 18:27:33 +08001635 netCap.mPrivateDnsBroken = in.readBoolean();
Cody Kestingf7ac9962020-03-16 18:15:28 -07001636 netCap.setAdministratorUids(in.createIntArray());
Qingxi Li7cf06622020-01-17 17:54:27 -08001637 netCap.mOwnerUid = in.readInt();
Roshan Piuse38acab2020-01-16 12:17:17 -08001638 netCap.mRequestorUid = in.readInt();
1639 netCap.mRequestorPackageName = in.readString();
Robert Greenwalt1448f052014-04-08 13:41:39 -07001640 return netCap;
1641 }
Wink Saville4e2dea72014-09-20 11:04:03 -07001642 @Override
Robert Greenwalt1448f052014-04-08 13:41:39 -07001643 public NetworkCapabilities[] newArray(int size) {
1644 return new NetworkCapabilities[size];
1645 }
1646 };
1647
Wink Saville4e2dea72014-09-20 11:04:03 -07001648 @Override
paulhud9736de2019-03-08 16:35:20 +08001649 public @NonNull String toString() {
Chalard Jean07ace0f2018-02-26 19:00:45 +09001650 final StringBuilder sb = new StringBuilder("[");
1651 if (0 != mTransportTypes) {
1652 sb.append(" Transports: ");
1653 appendStringRepresentationOfBitMaskToStringBuilder(sb, mTransportTypes,
1654 NetworkCapabilities::transportNameOf, "|");
1655 }
1656 if (0 != mNetworkCapabilities) {
1657 sb.append(" Capabilities: ");
1658 appendStringRepresentationOfBitMaskToStringBuilder(sb, mNetworkCapabilities,
1659 NetworkCapabilities::capabilityNameOf, "&");
1660 }
jiayanhonge20a4fe2018-11-23 14:23:04 +08001661 if (0 != mUnwantedNetworkCapabilities) {
Pavel Maltsev1cd48da2018-02-01 11:16:02 -08001662 sb.append(" Unwanted: ");
1663 appendStringRepresentationOfBitMaskToStringBuilder(sb, mUnwantedNetworkCapabilities,
1664 NetworkCapabilities::capabilityNameOf, "&");
1665 }
Chalard Jean07ace0f2018-02-26 19:00:45 +09001666 if (mLinkUpBandwidthKbps > 0) {
1667 sb.append(" LinkUpBandwidth>=").append(mLinkUpBandwidthKbps).append("Kbps");
1668 }
1669 if (mLinkDownBandwidthKbps > 0) {
1670 sb.append(" LinkDnBandwidth>=").append(mLinkDownBandwidthKbps).append("Kbps");
1671 }
1672 if (mNetworkSpecifier != null) {
1673 sb.append(" Specifier: <").append(mNetworkSpecifier).append(">");
1674 }
Etan Cohenca9fb562018-11-27 07:32:39 -08001675 if (mTransportInfo != null) {
1676 sb.append(" TransportInfo: <").append(mTransportInfo).append(">");
1677 }
Chalard Jean07ace0f2018-02-26 19:00:45 +09001678 if (hasSignalStrength()) {
1679 sb.append(" SignalStrength: ").append(mSignalStrength);
Robert Greenwalt1448f052014-04-08 13:41:39 -07001680 }
1681
Chalard Jean07ace0f2018-02-26 19:00:45 +09001682 if (null != mUids) {
1683 if ((1 == mUids.size()) && (mUids.valueAt(0).count() == 1)) {
1684 sb.append(" Uid: ").append(mUids.valueAt(0).start);
1685 } else {
1686 sb.append(" Uids: <").append(mUids).append(">");
1687 }
1688 }
Qingxi Li7cf06622020-01-17 17:54:27 -08001689 if (mOwnerUid != Process.INVALID_UID) {
1690 sb.append(" OwnerUid: ").append(mOwnerUid);
Chalard Jean07ace0f2018-02-26 19:00:45 +09001691 }
Robert Greenwalt1448f052014-04-08 13:41:39 -07001692
Cody Kestingf7ac9962020-03-16 18:15:28 -07001693 if (mAdministratorUids.length == 0) {
1694 sb.append(" AdministratorUids: ").append(Arrays.toString(mAdministratorUids));
Cody Kesting201fc132020-01-17 11:58:36 -08001695 }
1696
Chalard Jeanb03a6222018-04-11 21:09:10 +09001697 if (null != mSSID) {
1698 sb.append(" SSID: ").append(mSSID);
1699 }
1700
lucaslin783f2212019-10-22 18:27:33 +08001701 if (mPrivateDnsBroken) {
1702 sb.append(" Private DNS is broken");
1703 }
1704
Roshan Piuse38acab2020-01-16 12:17:17 -08001705 sb.append(" RequestorUid: ").append(mRequestorUid);
1706 sb.append(" RequestorPackageName: ").append(mRequestorPackageName);
1707
Chalard Jean07ace0f2018-02-26 19:00:45 +09001708 sb.append("]");
1709 return sb.toString();
1710 }
Robert Greenwalt5f90bcc2014-07-09 17:25:41 -07001711
Lorenzo Colittic3f21f32015-07-06 23:50:27 +09001712
Chalard Jean07ace0f2018-02-26 19:00:45 +09001713 private interface NameOf {
1714 String nameOf(int value);
1715 }
Roshan Piuse38acab2020-01-16 12:17:17 -08001716
Chalard Jean07ace0f2018-02-26 19:00:45 +09001717 /**
1718 * @hide
1719 */
paulhud9736de2019-03-08 16:35:20 +08001720 public static void appendStringRepresentationOfBitMaskToStringBuilder(@NonNull StringBuilder sb,
1721 long bitMask, @NonNull NameOf nameFetcher, @NonNull String separator) {
Chalard Jean07ace0f2018-02-26 19:00:45 +09001722 int bitPos = 0;
1723 boolean firstElementAdded = false;
1724 while (bitMask != 0) {
1725 if ((bitMask & 1) != 0) {
1726 if (firstElementAdded) {
1727 sb.append(separator);
1728 } else {
1729 firstElementAdded = true;
1730 }
1731 sb.append(nameFetcher.nameOf(bitPos));
1732 }
1733 bitMask >>= 1;
1734 ++bitPos;
1735 }
Robert Greenwalt1448f052014-04-08 13:41:39 -07001736 }
Hugo Benichi5df9d722016-04-25 17:16:35 +09001737
Kweku Adams85f2fbc2017-12-18 12:04:12 -08001738 /** @hide */
Jeffrey Huangcb782852019-12-05 11:28:11 -08001739 public void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) {
Kweku Adams85f2fbc2017-12-18 12:04:12 -08001740 final long token = proto.start(fieldId);
1741
1742 for (int transport : getTransportTypes()) {
1743 proto.write(NetworkCapabilitiesProto.TRANSPORTS, transport);
1744 }
1745
1746 for (int capability : getCapabilities()) {
1747 proto.write(NetworkCapabilitiesProto.CAPABILITIES, capability);
1748 }
1749
1750 proto.write(NetworkCapabilitiesProto.LINK_UP_BANDWIDTH_KBPS, mLinkUpBandwidthKbps);
1751 proto.write(NetworkCapabilitiesProto.LINK_DOWN_BANDWIDTH_KBPS, mLinkDownBandwidthKbps);
1752
1753 if (mNetworkSpecifier != null) {
1754 proto.write(NetworkCapabilitiesProto.NETWORK_SPECIFIER, mNetworkSpecifier.toString());
1755 }
Etan Cohenca9fb562018-11-27 07:32:39 -08001756 if (mTransportInfo != null) {
1757 // TODO b/120653863: write transport-specific info to proto?
1758 }
Kweku Adams85f2fbc2017-12-18 12:04:12 -08001759
1760 proto.write(NetworkCapabilitiesProto.CAN_REPORT_SIGNAL_STRENGTH, hasSignalStrength());
1761 proto.write(NetworkCapabilitiesProto.SIGNAL_STRENGTH, mSignalStrength);
1762
1763 proto.end(token);
1764 }
1765
Hugo Benichi5df9d722016-04-25 17:16:35 +09001766 /**
1767 * @hide
1768 */
paulhud9736de2019-03-08 16:35:20 +08001769 public static @NonNull String capabilityNamesOf(@Nullable @NetCapability int[] capabilities) {
Hugo Benichieae7a222017-07-25 11:40:56 +09001770 StringJoiner joiner = new StringJoiner("|");
1771 if (capabilities != null) {
1772 for (int c : capabilities) {
1773 joiner.add(capabilityNameOf(c));
1774 }
1775 }
1776 return joiner.toString();
1777 }
1778
1779 /**
1780 * @hide
1781 */
paulhud9736de2019-03-08 16:35:20 +08001782 public static @NonNull String capabilityNameOf(@NetCapability int capability) {
Hugo Benichieae7a222017-07-25 11:40:56 +09001783 switch (capability) {
lucasline252a742019-03-12 13:08:03 +08001784 case NET_CAPABILITY_MMS: return "MMS";
1785 case NET_CAPABILITY_SUPL: return "SUPL";
1786 case NET_CAPABILITY_DUN: return "DUN";
1787 case NET_CAPABILITY_FOTA: return "FOTA";
1788 case NET_CAPABILITY_IMS: return "IMS";
1789 case NET_CAPABILITY_CBS: return "CBS";
1790 case NET_CAPABILITY_WIFI_P2P: return "WIFI_P2P";
1791 case NET_CAPABILITY_IA: return "IA";
1792 case NET_CAPABILITY_RCS: return "RCS";
1793 case NET_CAPABILITY_XCAP: return "XCAP";
1794 case NET_CAPABILITY_EIMS: return "EIMS";
1795 case NET_CAPABILITY_NOT_METERED: return "NOT_METERED";
1796 case NET_CAPABILITY_INTERNET: return "INTERNET";
1797 case NET_CAPABILITY_NOT_RESTRICTED: return "NOT_RESTRICTED";
1798 case NET_CAPABILITY_TRUSTED: return "TRUSTED";
1799 case NET_CAPABILITY_NOT_VPN: return "NOT_VPN";
1800 case NET_CAPABILITY_VALIDATED: return "VALIDATED";
1801 case NET_CAPABILITY_CAPTIVE_PORTAL: return "CAPTIVE_PORTAL";
1802 case NET_CAPABILITY_NOT_ROAMING: return "NOT_ROAMING";
1803 case NET_CAPABILITY_FOREGROUND: return "FOREGROUND";
1804 case NET_CAPABILITY_NOT_CONGESTED: return "NOT_CONGESTED";
1805 case NET_CAPABILITY_NOT_SUSPENDED: return "NOT_SUSPENDED";
1806 case NET_CAPABILITY_OEM_PAID: return "OEM_PAID";
1807 case NET_CAPABILITY_MCX: return "MCX";
1808 case NET_CAPABILITY_PARTIAL_CONNECTIVITY: return "PARTIAL_CONNECTIVITY";
1809 default: return Integer.toString(capability);
Hugo Benichieae7a222017-07-25 11:40:56 +09001810 }
1811 }
1812
1813 /**
1814 * @hide
1815 */
Mathew Inwoodfa3a7462018-08-08 14:52:47 +01001816 @UnsupportedAppUsage
paulhud9736de2019-03-08 16:35:20 +08001817 public static @NonNull String transportNamesOf(@Nullable @Transport int[] types) {
Hugo Benichieae7a222017-07-25 11:40:56 +09001818 StringJoiner joiner = new StringJoiner("|");
1819 if (types != null) {
1820 for (int t : types) {
1821 joiner.add(transportNameOf(t));
1822 }
Hugo Benichi5df9d722016-04-25 17:16:35 +09001823 }
Hugo Benichieae7a222017-07-25 11:40:56 +09001824 return joiner.toString();
Hugo Benichi9910dbc2017-03-22 18:29:58 +09001825 }
1826
1827 /**
1828 * @hide
1829 */
paulhud9736de2019-03-08 16:35:20 +08001830 public static @NonNull String transportNameOf(@Transport int transport) {
Hugo Benichi16f0a942017-06-20 14:07:59 +09001831 if (!isValidTransport(transport)) {
Hugo Benichi9910dbc2017-03-22 18:29:58 +09001832 return "UNKNOWN";
1833 }
1834 return TRANSPORT_NAMES[transport];
Hugo Benichi5df9d722016-04-25 17:16:35 +09001835 }
Hugo Benichi16f0a942017-06-20 14:07:59 +09001836
Jeff Sharkeyde570312017-10-24 21:25:50 -06001837 private static void checkValidTransportType(@Transport int transport) {
Hugo Benichi16f0a942017-06-20 14:07:59 +09001838 Preconditions.checkArgument(
1839 isValidTransport(transport), "Invalid TransportType " + transport);
1840 }
Pavel Maltsev1cd48da2018-02-01 11:16:02 -08001841
1842 private static boolean isValidCapability(@NetworkCapabilities.NetCapability int capability) {
1843 return capability >= MIN_NET_CAPABILITY && capability <= MAX_NET_CAPABILITY;
1844 }
1845
1846 private static void checkValidCapability(@NetworkCapabilities.NetCapability int capability) {
1847 Preconditions.checkArgument(isValidCapability(capability),
1848 "NetworkCapability " + capability + "out of range");
1849 }
junyulai05986c62018-08-07 19:50:45 +08001850
1851 /**
1852 * Check if this {@code NetworkCapability} instance is metered.
1853 *
1854 * @return {@code true} if {@code NET_CAPABILITY_NOT_METERED} is not set on this instance.
1855 * @hide
1856 */
1857 public boolean isMetered() {
1858 return !hasCapability(NET_CAPABILITY_NOT_METERED);
1859 }
lucaslin783f2212019-10-22 18:27:33 +08001860
1861 /**
1862 * Check if private dns is broken.
1863 *
1864 * @return {@code true} if {@code mPrivateDnsBroken} is set when private DNS is broken.
1865 * @hide
1866 */
1867 public boolean isPrivateDnsBroken() {
1868 return mPrivateDnsBroken;
1869 }
1870
1871 /**
1872 * Set mPrivateDnsBroken to true when private dns is broken.
1873 *
1874 * @param broken the status of private DNS to be set.
1875 * @hide
1876 */
1877 public void setPrivateDnsBroken(boolean broken) {
1878 mPrivateDnsBroken = broken;
1879 }
1880
1881 private boolean equalsPrivateDnsBroken(NetworkCapabilities nc) {
1882 return mPrivateDnsBroken == nc.mPrivateDnsBroken;
1883 }
Roshan Piuse38acab2020-01-16 12:17:17 -08001884
1885 /**
Chalard Jeane5e38502020-03-18 15:58:50 +09001886 * Set the UID of the app making the request.
Roshan Piuse38acab2020-01-16 12:17:17 -08001887 *
Chalard Jeane5e38502020-03-18 15:58:50 +09001888 * For instances of NetworkCapabilities representing a request, sets the
1889 * UID of the app making the request. For a network created by the system,
1890 * sets the UID of the only app whose requests can match this network.
1891 * This can be set to {@link Process#INVALID_UID} if there is no such app,
1892 * or if this instance of NetworkCapabilities is about to be sent to a
1893 * party that should not learn about this.
Roshan Piuse38acab2020-01-16 12:17:17 -08001894 *
1895 * @param uid UID of the app.
1896 * @hide
1897 */
Roshan Piuse38acab2020-01-16 12:17:17 -08001898 public @NonNull NetworkCapabilities setRequestorUid(int uid) {
1899 mRequestorUid = uid;
1900 return this;
1901 }
1902
1903 /**
Chalard Jeane5e38502020-03-18 15:58:50 +09001904 * Returns the UID of the app making the request.
Roshan Piuse38acab2020-01-16 12:17:17 -08001905 *
Chalard Jeane5e38502020-03-18 15:58:50 +09001906 * For a NetworkRequest being made by an app, contains the app's UID. For a network
1907 * created by the system, contains the UID of the only app whose requests can match
1908 * this network, or {@link Process#INVALID_UID} if none or if the
1909 * caller does not have permission to learn about this.
1910 *
1911 * @return the uid of the app making the request.
Roshan Piuse38acab2020-01-16 12:17:17 -08001912 * @hide
1913 */
1914 public int getRequestorUid() {
1915 return mRequestorUid;
1916 }
1917
1918 /**
1919 * Set the package name of the app making the request.
1920 *
Chalard Jeane5e38502020-03-18 15:58:50 +09001921 * For instances of NetworkCapabilities representing a request, sets the
1922 * package name of the app making the request. For a network created by the system,
1923 * sets the package name of the only app whose requests can match this network.
1924 * This can be set to null if there is no such app, or if this instance of
1925 * NetworkCapabilities is about to be sent to a party that should not learn about this.
Roshan Piuse38acab2020-01-16 12:17:17 -08001926 *
1927 * @param packageName package name of the app.
1928 * @hide
1929 */
Roshan Piuse38acab2020-01-16 12:17:17 -08001930 public @NonNull NetworkCapabilities setRequestorPackageName(@NonNull String packageName) {
1931 mRequestorPackageName = packageName;
1932 return this;
1933 }
1934
1935 /**
Chalard Jeane5e38502020-03-18 15:58:50 +09001936 * Returns the package name of the app making the request.
Roshan Piuse38acab2020-01-16 12:17:17 -08001937 *
Chalard Jeane5e38502020-03-18 15:58:50 +09001938 * For a NetworkRequest being made by an app, contains the app's package name. For a
1939 * network created by the system, contains the package name of the only app whose
1940 * requests can match this network, or null if none or if the caller does not have
1941 * permission to learn about this.
1942 *
1943 * @return the package name of the app making the request.
Roshan Piuse38acab2020-01-16 12:17:17 -08001944 * @hide
1945 */
1946 @Nullable
1947 public String getRequestorPackageName() {
1948 return mRequestorPackageName;
1949 }
1950
1951 /**
Chalard Jeane5e38502020-03-18 15:58:50 +09001952 * Set the uid and package name of the app causing this network to exist.
Roshan Piuse38acab2020-01-16 12:17:17 -08001953 *
Chalard Jeane5e38502020-03-18 15:58:50 +09001954 * {@see #setRequestorUid} and {@link #setRequestorPackageName}
Roshan Piuse38acab2020-01-16 12:17:17 -08001955 *
1956 * @param uid UID of the app.
1957 * @param packageName package name of the app.
1958 * @hide
1959 */
1960 public @NonNull NetworkCapabilities setRequestorUidAndPackageName(
1961 int uid, @NonNull String packageName) {
1962 return setRequestorUid(uid).setRequestorPackageName(packageName);
1963 }
1964
1965 /**
1966 * Test whether the passed NetworkCapabilities satisfies the requestor restrictions of this
1967 * capabilities.
1968 *
1969 * This method is called on the NetworkCapabilities embedded in a request with the
1970 * capabilities of an available network. If the available network, sets a specific
1971 * requestor (by uid and optionally package name), then this will only match a request from the
1972 * same app. If either of the capabilities have an unset uid or package name, then it matches
1973 * everything.
1974 * <p>
1975 * nc is assumed nonnull. Else, NPE.
1976 */
1977 private boolean satisfiedByRequestor(NetworkCapabilities nc) {
1978 // No uid set, matches everything.
1979 if (mRequestorUid == Process.INVALID_UID || nc.mRequestorUid == Process.INVALID_UID) {
1980 return true;
1981 }
1982 // uids don't match.
1983 if (mRequestorUid != nc.mRequestorUid) return false;
1984 // No package names set, matches everything
1985 if (null == nc.mRequestorPackageName || null == mRequestorPackageName) return true;
1986 // check for package name match.
1987 return TextUtils.equals(mRequestorPackageName, nc.mRequestorPackageName);
1988 }
1989
1990 /**
1991 * Combine requestor info of the capabilities.
1992 * <p>
1993 * This is only legal if either the requestor info of this object is reset, or both info are
1994 * equal.
1995 * nc is assumed nonnull.
1996 */
1997 private void combineRequestor(@NonNull NetworkCapabilities nc) {
1998 if (mRequestorUid != Process.INVALID_UID && mRequestorUid != nc.mOwnerUid) {
1999 throw new IllegalStateException("Can't combine two uids");
2000 }
2001 if (mRequestorPackageName != null
2002 && !mRequestorPackageName.equals(nc.mRequestorPackageName)) {
2003 throw new IllegalStateException("Can't combine two package names");
2004 }
2005 setRequestorUid(nc.mRequestorUid);
2006 setRequestorPackageName(nc.mRequestorPackageName);
2007 }
2008
2009 private boolean equalsRequestor(NetworkCapabilities nc) {
2010 return mRequestorUid == nc.mRequestorUid
2011 && TextUtils.equals(mRequestorPackageName, nc.mRequestorPackageName);
2012 }
Chalard Jeane5e38502020-03-18 15:58:50 +09002013
2014 /**
2015 * Builder class for NetworkCapabilities.
2016 *
2017 * This class is mainly for for {@link NetworkAgent} instances to use. Many fields in
2018 * the built class require holding a signature permission to use - mostly
2019 * {@link android.Manifest.permission.NETWORK_FACTORY}, but refer to the specific
2020 * description of each setter. As this class lives entirely in app space it does not
2021 * enforce these restrictions itself but the system server clears out the relevant
2022 * fields when receiving a NetworkCapabilities object from a caller without the
2023 * appropriate permission.
2024 *
2025 * Apps don't use this builder directly. Instead, they use {@link NetworkRequest} via
2026 * its builder object.
2027 *
2028 * @hide
2029 */
2030 @SystemApi
2031 @TestApi
Aaron Huangfbb485a2020-03-25 13:36:38 +08002032 public static final class Builder {
Chalard Jeane5e38502020-03-18 15:58:50 +09002033 private final NetworkCapabilities mCaps;
2034
2035 /**
2036 * Creates a new Builder to construct NetworkCapabilities objects.
2037 */
2038 public Builder() {
2039 mCaps = new NetworkCapabilities();
2040 }
2041
2042 /**
2043 * Creates a new Builder of NetworkCapabilities from an existing instance.
2044 */
2045 public Builder(@NonNull final NetworkCapabilities nc) {
2046 Objects.requireNonNull(nc);
2047 mCaps = new NetworkCapabilities(nc);
2048 }
2049
2050 /**
2051 * Adds the given transport type.
2052 *
2053 * Multiple transports may be added. Note that when searching for a network to satisfy a
2054 * request, satisfying any of the transports listed in the request will satisfy the request.
2055 * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a
2056 * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network
2057 * to be selected. This is logically different than
2058 * {@code NetworkCapabilities.NET_CAPABILITY_*}.
2059 *
2060 * @param transportType the transport type to be added or removed.
2061 * @return this builder
2062 */
2063 @NonNull
2064 public Builder addTransportType(@Transport int transportType) {
2065 checkValidTransportType(transportType);
2066 mCaps.addTransportType(transportType);
2067 return this;
2068 }
2069
2070 /**
2071 * Removes the given transport type.
2072 *
2073 * {@see #addTransportType}.
2074 *
2075 * @param transportType the transport type to be added or removed.
2076 * @return this builder
2077 */
2078 @NonNull
2079 public Builder removeTransportType(@Transport int transportType) {
2080 checkValidTransportType(transportType);
2081 mCaps.removeTransportType(transportType);
2082 return this;
2083 }
2084
2085 /**
2086 * Adds the given capability.
2087 *
2088 * @param capability the capability
2089 * @return this builder
2090 */
2091 @NonNull
2092 public Builder addCapability(@NetCapability final int capability) {
2093 mCaps.setCapability(capability, true);
2094 return this;
2095 }
2096
2097 /**
2098 * Removes the given capability.
2099 *
2100 * @param capability the capability
2101 * @return this builder
2102 */
2103 @NonNull
2104 public Builder removeCapability(@NetCapability final int capability) {
2105 mCaps.setCapability(capability, false);
2106 return this;
2107 }
2108
2109 /**
2110 * Sets the owner UID.
2111 *
2112 * The default value is {@link Process#INVALID_UID}. Pass this value to reset.
2113 *
2114 * Note: for security the system will clear out this field when received from a
2115 * non-privileged source.
2116 *
2117 * @param ownerUid the owner UID
2118 * @return this builder
2119 */
2120 @NonNull
2121 @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
2122 public Builder setOwnerUid(final int ownerUid) {
2123 mCaps.setOwnerUid(ownerUid);
2124 return this;
2125 }
2126
2127 /**
2128 * Sets the list of UIDs that are administrators of this network.
2129 *
2130 * <p>UIDs included in administratorUids gain administrator privileges over this
2131 * Network. Examples of UIDs that should be included in administratorUids are:
2132 * <ul>
2133 * <li>Carrier apps with privileges for the relevant subscription
2134 * <li>Active VPN apps
2135 * <li>Other application groups with a particular Network-related role
2136 * </ul>
2137 *
2138 * <p>In general, user-supplied networks (such as WiFi networks) do not have
2139 * administrators.
2140 *
2141 * <p>An app is granted owner privileges over Networks that it supplies. The owner
2142 * UID MUST always be included in administratorUids.
2143 *
2144 * The default value is the empty array. Pass an empty array to reset.
2145 *
2146 * Note: for security the system will clear out this field when received from a
2147 * non-privileged source, such as an app using reflection to call this or
2148 * mutate the member in the built object.
2149 *
2150 * @param administratorUids the UIDs to be set as administrators of this Network.
2151 * @return this builder
2152 */
2153 @NonNull
2154 @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
2155 public Builder setAdministratorUids(@NonNull final int[] administratorUids) {
2156 Objects.requireNonNull(administratorUids);
2157 mCaps.setAdministratorUids(administratorUids);
2158 return this;
2159 }
2160
2161 /**
2162 * Sets the upstream bandwidth of the link.
2163 *
2164 * Sets the upstream bandwidth for this network in Kbps. This always only refers to
2165 * the estimated first hop transport bandwidth.
2166 * <p>
2167 * Note that when used to request a network, this specifies the minimum acceptable.
2168 * When received as the state of an existing network this specifies the typical
2169 * first hop bandwidth expected. This is never measured, but rather is inferred
2170 * from technology type and other link parameters. It could be used to differentiate
2171 * between very slow 1xRTT cellular links and other faster networks or even between
2172 * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
2173 * fast backhauls and slow backhauls.
2174 *
2175 * @param upKbps the estimated first hop upstream (device to network) bandwidth.
2176 * @return this builder
2177 */
2178 @NonNull
2179 public Builder setLinkUpstreamBandwidthKbps(final int upKbps) {
2180 mCaps.setLinkUpstreamBandwidthKbps(upKbps);
2181 return this;
2182 }
2183
2184 /**
2185 * Sets the downstream bandwidth for this network in Kbps. This always only refers to
2186 * the estimated first hop transport bandwidth.
2187 * <p>
2188 * Note that when used to request a network, this specifies the minimum acceptable.
2189 * When received as the state of an existing network this specifies the typical
2190 * first hop bandwidth expected. This is never measured, but rather is inferred
2191 * from technology type and other link parameters. It could be used to differentiate
2192 * between very slow 1xRTT cellular links and other faster networks or even between
2193 * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
2194 * fast backhauls and slow backhauls.
2195 *
2196 * @param downKbps the estimated first hop downstream (network to device) bandwidth.
2197 * @return this builder
2198 */
2199 @NonNull
2200 public Builder setLinkDownstreamBandwidthKbps(final int downKbps) {
2201 mCaps.setLinkDownstreamBandwidthKbps(downKbps);
2202 return this;
2203 }
2204
2205 /**
2206 * Sets the optional bearer specific network specifier.
2207 * This has no meaning if a single transport is also not specified, so calling
2208 * this without a single transport set will generate an exception, as will
2209 * subsequently adding or removing transports after this is set.
2210 * </p>
2211 *
2212 * @param specifier a concrete, parcelable framework class that extends NetworkSpecifier,
2213 * or null to clear it.
2214 * @return this builder
2215 */
2216 @NonNull
2217 public Builder setNetworkSpecifier(@Nullable final NetworkSpecifier specifier) {
2218 mCaps.setNetworkSpecifier(specifier);
2219 return this;
2220 }
2221
2222 /**
2223 * Sets the optional transport specific information.
2224 *
2225 * @param info A concrete, parcelable framework class that extends {@link TransportInfo},
2226 * or null to clear it.
2227 * @return this builder
2228 */
2229 @NonNull
2230 public Builder setTransportInfo(@Nullable final TransportInfo info) {
2231 mCaps.setTransportInfo(info);
2232 return this;
2233 }
2234
2235 /**
2236 * Sets the signal strength. This is a signed integer, with higher values indicating a
2237 * stronger signal. The exact units are bearer-dependent. For example, Wi-Fi uses the
2238 * same RSSI units reported by wifi code.
2239 * <p>
2240 * Note that when used to register a network callback, this specifies the minimum
2241 * acceptable signal strength. When received as the state of an existing network it
2242 * specifies the current value. A value of code SIGNAL_STRENGTH_UNSPECIFIED} means
2243 * no value when received and has no effect when requesting a callback.
2244 *
2245 * Note: for security the system will throw if it receives a NetworkRequest where
2246 * the underlying NetworkCapabilities has this member set from a source that does
2247 * not hold the {@link android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP}
2248 * permission. Apps with this permission can use this indirectly through
2249 * {@link android.net.NetworkRequest}.
2250 *
2251 * @param signalStrength the bearer-specific signal strength.
2252 * @return this builder
2253 */
2254 @NonNull
2255 @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP)
2256 public Builder setSignalStrength(final int signalStrength) {
2257 mCaps.setSignalStrength(signalStrength);
2258 return this;
2259 }
2260
2261 /**
2262 * Sets the SSID of this network.
2263 *
2264 * Note: for security the system will clear out this field when received from a
2265 * non-privileged source, like an app using reflection to set this.
2266 *
2267 * @param ssid the SSID, or null to clear it.
2268 * @return this builder
2269 */
2270 @NonNull
2271 @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
2272 public Builder setSsid(@Nullable final String ssid) {
2273 mCaps.setSSID(ssid);
2274 return this;
2275 }
2276
2277 /**
2278 * Set the uid of the app causing this network to exist.
2279 *
2280 * Note: for security the system will clear out this field when received from a
2281 * non-privileged source.
2282 *
2283 * @param uid UID of the app.
2284 * @return this builder
2285 */
2286 @NonNull
2287 @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
2288 public Builder setRequestorUid(final int uid) {
2289 mCaps.setRequestorUid(uid);
2290 return this;
2291 }
2292
2293 /**
2294 * Set the package name of the app causing this network to exist.
2295 *
2296 * Note: for security the system will clear out this field when received from a
2297 * non-privileged source.
2298 *
2299 * @param packageName package name of the app, or null to clear it.
2300 * @return this builder
2301 */
2302 @NonNull
2303 @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
2304 public Builder setRequestorPackageName(@Nullable final String packageName) {
2305 mCaps.setRequestorPackageName(packageName);
2306 return this;
2307 }
2308
2309 /**
2310 * Builds the instance of the capabilities.
2311 *
2312 * @return the built instance of NetworkCapabilities.
2313 */
2314 @NonNull
2315 public NetworkCapabilities build() {
2316 if (mCaps.getOwnerUid() != Process.INVALID_UID) {
2317 if (!ArrayUtils.contains(mCaps.getAdministratorUids(), mCaps.getOwnerUid())) {
2318 throw new IllegalStateException("The owner UID must be included in "
2319 + " administrator UIDs.");
2320 }
2321 }
2322 return new NetworkCapabilities(mCaps);
2323 }
2324 }
Robert Greenwalt1448f052014-04-08 13:41:39 -07002325}