1 /* 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 17 package android.net; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.SystemApi; 23 import android.annotation.TestApi; 24 import android.annotation.UnsupportedAppUsage; 25 import android.net.ConnectivityManager.NetworkCallback; 26 import android.os.Build; 27 import android.os.Parcel; 28 import android.os.Parcelable; 29 import android.util.ArraySet; 30 import android.util.proto.ProtoOutputStream; 31 32 import com.android.internal.annotations.VisibleForTesting; 33 import com.android.internal.util.BitUtils; 34 import com.android.internal.util.Preconditions; 35 36 import java.lang.annotation.Retention; 37 import java.lang.annotation.RetentionPolicy; 38 import java.util.Objects; 39 import java.util.Set; 40 import java.util.StringJoiner; 41 42 /** 43 * Representation of the capabilities of an active network. Instances are 44 * typically obtained through 45 * {@link NetworkCallback#onCapabilitiesChanged(Network, NetworkCapabilities)} 46 * or {@link ConnectivityManager#getNetworkCapabilities(Network)}. 47 * <p> 48 * This replaces the old {@link ConnectivityManager#TYPE_MOBILE} method of 49 * network selection. Rather than indicate a need for Wi-Fi because an 50 * application needs high bandwidth and risk obsolescence when a new, fast 51 * network appears (like LTE), the application should specify it needs high 52 * bandwidth. Similarly if an application needs an unmetered network for a bulk 53 * transfer it can specify that rather than assuming all cellular based 54 * connections are metered and all Wi-Fi based connections are not. 55 */ 56 public final class NetworkCapabilities implements Parcelable { 57 private static final String TAG = "NetworkCapabilities"; 58 private static final int INVALID_UID = -1; 59 60 /** 61 * @hide 62 */ 63 @UnsupportedAppUsage NetworkCapabilities()64 public NetworkCapabilities() { 65 clearAll(); 66 mNetworkCapabilities = DEFAULT_CAPABILITIES; 67 } 68 NetworkCapabilities(NetworkCapabilities nc)69 public NetworkCapabilities(NetworkCapabilities nc) { 70 if (nc != null) { 71 set(nc); 72 } 73 } 74 75 /** 76 * Completely clears the contents of this object, removing even the capabilities that are set 77 * by default when the object is constructed. 78 * @hide 79 */ clearAll()80 public void clearAll() { 81 mNetworkCapabilities = mTransportTypes = mUnwantedNetworkCapabilities = 0; 82 mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED; 83 mNetworkSpecifier = null; 84 mTransportInfo = null; 85 mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED; 86 mUids = null; 87 mEstablishingVpnAppUid = INVALID_UID; 88 mSSID = null; 89 } 90 91 /** 92 * Set all contents of this object to the contents of a NetworkCapabilities. 93 * @hide 94 */ set(@onNull NetworkCapabilities nc)95 public void set(@NonNull NetworkCapabilities nc) { 96 mNetworkCapabilities = nc.mNetworkCapabilities; 97 mTransportTypes = nc.mTransportTypes; 98 mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps; 99 mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps; 100 mNetworkSpecifier = nc.mNetworkSpecifier; 101 mTransportInfo = nc.mTransportInfo; 102 mSignalStrength = nc.mSignalStrength; 103 setUids(nc.mUids); // Will make the defensive copy 104 mEstablishingVpnAppUid = nc.mEstablishingVpnAppUid; 105 mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities; 106 mSSID = nc.mSSID; 107 } 108 109 /** 110 * Represents the network's capabilities. If any are specified they will be satisfied 111 * by any Network that matches all of them. 112 */ 113 @UnsupportedAppUsage 114 private long mNetworkCapabilities; 115 116 /** 117 * If any capabilities specified here they must not exist in the matching Network. 118 */ 119 private long mUnwantedNetworkCapabilities; 120 121 /** @hide */ 122 @Retention(RetentionPolicy.SOURCE) 123 @IntDef(prefix = { "NET_CAPABILITY_" }, value = { 124 NET_CAPABILITY_MMS, 125 NET_CAPABILITY_SUPL, 126 NET_CAPABILITY_DUN, 127 NET_CAPABILITY_FOTA, 128 NET_CAPABILITY_IMS, 129 NET_CAPABILITY_CBS, 130 NET_CAPABILITY_WIFI_P2P, 131 NET_CAPABILITY_IA, 132 NET_CAPABILITY_RCS, 133 NET_CAPABILITY_XCAP, 134 NET_CAPABILITY_EIMS, 135 NET_CAPABILITY_NOT_METERED, 136 NET_CAPABILITY_INTERNET, 137 NET_CAPABILITY_NOT_RESTRICTED, 138 NET_CAPABILITY_TRUSTED, 139 NET_CAPABILITY_NOT_VPN, 140 NET_CAPABILITY_VALIDATED, 141 NET_CAPABILITY_CAPTIVE_PORTAL, 142 NET_CAPABILITY_NOT_ROAMING, 143 NET_CAPABILITY_FOREGROUND, 144 NET_CAPABILITY_NOT_CONGESTED, 145 NET_CAPABILITY_NOT_SUSPENDED, 146 NET_CAPABILITY_OEM_PAID, 147 NET_CAPABILITY_MCX, 148 NET_CAPABILITY_PARTIAL_CONNECTIVITY, 149 }) 150 public @interface NetCapability { } 151 152 /** 153 * Indicates this is a network that has the ability to reach the 154 * carrier's MMSC for sending and receiving MMS messages. 155 */ 156 public static final int NET_CAPABILITY_MMS = 0; 157 158 /** 159 * Indicates this is a network that has the ability to reach the carrier's 160 * SUPL server, used to retrieve GPS information. 161 */ 162 public static final int NET_CAPABILITY_SUPL = 1; 163 164 /** 165 * Indicates this is a network that has the ability to reach the carrier's 166 * DUN or tethering gateway. 167 */ 168 public static final int NET_CAPABILITY_DUN = 2; 169 170 /** 171 * Indicates this is a network that has the ability to reach the carrier's 172 * FOTA portal, used for over the air updates. 173 */ 174 public static final int NET_CAPABILITY_FOTA = 3; 175 176 /** 177 * Indicates this is a network that has the ability to reach the carrier's 178 * IMS servers, used for network registration and signaling. 179 */ 180 public static final int NET_CAPABILITY_IMS = 4; 181 182 /** 183 * Indicates this is a network that has the ability to reach the carrier's 184 * CBS servers, used for carrier specific services. 185 */ 186 public static final int NET_CAPABILITY_CBS = 5; 187 188 /** 189 * Indicates this is a network that has the ability to reach a Wi-Fi direct 190 * peer. 191 */ 192 public static final int NET_CAPABILITY_WIFI_P2P = 6; 193 194 /** 195 * Indicates this is a network that has the ability to reach a carrier's 196 * Initial Attach servers. 197 */ 198 public static final int NET_CAPABILITY_IA = 7; 199 200 /** 201 * Indicates this is a network that has the ability to reach a carrier's 202 * RCS servers, used for Rich Communication Services. 203 */ 204 public static final int NET_CAPABILITY_RCS = 8; 205 206 /** 207 * Indicates this is a network that has the ability to reach a carrier's 208 * XCAP servers, used for configuration and control. 209 */ 210 public static final int NET_CAPABILITY_XCAP = 9; 211 212 /** 213 * Indicates this is a network that has the ability to reach a carrier's 214 * Emergency IMS servers or other services, used for network signaling 215 * during emergency calls. 216 */ 217 public static final int NET_CAPABILITY_EIMS = 10; 218 219 /** 220 * Indicates that this network is unmetered. 221 */ 222 public static final int NET_CAPABILITY_NOT_METERED = 11; 223 224 /** 225 * Indicates that this network should be able to reach the internet. 226 */ 227 public static final int NET_CAPABILITY_INTERNET = 12; 228 229 /** 230 * Indicates that this network is available for general use. If this is not set 231 * applications should not attempt to communicate on this network. Note that this 232 * is simply informative and not enforcement - enforcement is handled via other means. 233 * Set by default. 234 */ 235 public static final int NET_CAPABILITY_NOT_RESTRICTED = 13; 236 237 /** 238 * Indicates that the user has indicated implicit trust of this network. This 239 * generally means it's a sim-selected carrier, a plugged in ethernet, a paired 240 * BT device or a wifi the user asked to connect to. Untrusted networks 241 * are probably limited to unknown wifi AP. Set by default. 242 */ 243 public static final int NET_CAPABILITY_TRUSTED = 14; 244 245 /** 246 * Indicates that this network is not a VPN. This capability is set by default and should be 247 * explicitly cleared for VPN networks. 248 */ 249 public static final int NET_CAPABILITY_NOT_VPN = 15; 250 251 /** 252 * Indicates that connectivity on this network was successfully validated. For example, for a 253 * network with NET_CAPABILITY_INTERNET, it means that Internet connectivity was successfully 254 * detected. 255 */ 256 public static final int NET_CAPABILITY_VALIDATED = 16; 257 258 /** 259 * Indicates that this network was found to have a captive portal in place last time it was 260 * probed. 261 */ 262 public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17; 263 264 /** 265 * Indicates that this network is not roaming. 266 */ 267 public static final int NET_CAPABILITY_NOT_ROAMING = 18; 268 269 /** 270 * Indicates that this network is available for use by apps, and not a network that is being 271 * kept up in the background to facilitate fast network switching. 272 */ 273 public static final int NET_CAPABILITY_FOREGROUND = 19; 274 275 /** 276 * Indicates that this network is not congested. 277 * <p> 278 * When a network is congested, applications should defer network traffic 279 * that can be done at a later time, such as uploading analytics. 280 */ 281 public static final int NET_CAPABILITY_NOT_CONGESTED = 20; 282 283 /** 284 * Indicates that this network is not currently suspended. 285 * <p> 286 * When a network is suspended, the network's IP addresses and any connections 287 * established on the network remain valid, but the network is temporarily unable 288 * to transfer data. This can happen, for example, if a cellular network experiences 289 * a temporary loss of signal, such as when driving through a tunnel, etc. 290 * A network with this capability is not suspended, so is expected to be able to 291 * transfer data. 292 */ 293 public static final int NET_CAPABILITY_NOT_SUSPENDED = 21; 294 295 /** 296 * Indicates that traffic that goes through this network is paid by oem. For example, 297 * this network can be used by system apps to upload telemetry data. 298 * @hide 299 */ 300 @SystemApi 301 public static final int NET_CAPABILITY_OEM_PAID = 22; 302 303 /** 304 * Indicates this is a network that has the ability to reach a carrier's Mission Critical 305 * servers. 306 */ 307 public static final int NET_CAPABILITY_MCX = 23; 308 309 /** 310 * Indicates that this network was tested to only provide partial connectivity. 311 * @hide 312 */ 313 @SystemApi 314 public static final int NET_CAPABILITY_PARTIAL_CONNECTIVITY = 24; 315 316 private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS; 317 private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_PARTIAL_CONNECTIVITY; 318 319 /** 320 * Network capabilities that are expected to be mutable, i.e., can change while a particular 321 * network is connected. 322 */ 323 private static final long MUTABLE_CAPABILITIES = 324 // TRUSTED can change when user explicitly connects to an untrusted network in Settings. 325 // http://b/18206275 326 (1 << NET_CAPABILITY_TRUSTED) 327 | (1 << NET_CAPABILITY_VALIDATED) 328 | (1 << NET_CAPABILITY_CAPTIVE_PORTAL) 329 | (1 << NET_CAPABILITY_NOT_ROAMING) 330 | (1 << NET_CAPABILITY_FOREGROUND) 331 | (1 << NET_CAPABILITY_NOT_CONGESTED) 332 | (1 << NET_CAPABILITY_NOT_SUSPENDED) 333 | (1 << NET_CAPABILITY_PARTIAL_CONNECTIVITY); 334 335 /** 336 * Network capabilities that are not allowed in NetworkRequests. This exists because the 337 * NetworkFactory / NetworkAgent model does not deal well with the situation where a 338 * capability's presence cannot be known in advance. If such a capability is requested, then we 339 * can get into a cycle where the NetworkFactory endlessly churns out NetworkAgents that then 340 * get immediately torn down because they do not have the requested capability. 341 */ 342 private static final long NON_REQUESTABLE_CAPABILITIES = 343 MUTABLE_CAPABILITIES & ~(1 << NET_CAPABILITY_TRUSTED); 344 345 /** 346 * Capabilities that are set by default when the object is constructed. 347 */ 348 private static final long DEFAULT_CAPABILITIES = 349 (1 << NET_CAPABILITY_NOT_RESTRICTED) | 350 (1 << NET_CAPABILITY_TRUSTED) | 351 (1 << NET_CAPABILITY_NOT_VPN); 352 353 /** 354 * Capabilities that suggest that a network is restricted. 355 * {@see #maybeMarkCapabilitiesRestricted}, {@see #FORCE_RESTRICTED_CAPABILITIES} 356 */ 357 @VisibleForTesting 358 /* package */ static final long RESTRICTED_CAPABILITIES = 359 (1 << NET_CAPABILITY_CBS) | 360 (1 << NET_CAPABILITY_DUN) | 361 (1 << NET_CAPABILITY_EIMS) | 362 (1 << NET_CAPABILITY_FOTA) | 363 (1 << NET_CAPABILITY_IA) | 364 (1 << NET_CAPABILITY_IMS) | 365 (1 << NET_CAPABILITY_RCS) | 366 (1 << NET_CAPABILITY_XCAP) | 367 (1 << NET_CAPABILITY_MCX); 368 369 /** 370 * Capabilities that force network to be restricted. 371 * {@see #maybeMarkCapabilitiesRestricted}. 372 */ 373 private static final long FORCE_RESTRICTED_CAPABILITIES = 374 (1 << NET_CAPABILITY_OEM_PAID); 375 376 /** 377 * Capabilities that suggest that a network is unrestricted. 378 * {@see #maybeMarkCapabilitiesRestricted}. 379 */ 380 @VisibleForTesting 381 /* package */ static final long UNRESTRICTED_CAPABILITIES = 382 (1 << NET_CAPABILITY_INTERNET) | 383 (1 << NET_CAPABILITY_MMS) | 384 (1 << NET_CAPABILITY_SUPL) | 385 (1 << NET_CAPABILITY_WIFI_P2P); 386 387 /** 388 * Capabilities that are managed by ConnectivityService. 389 */ 390 private static final long CONNECTIVITY_MANAGED_CAPABILITIES = 391 (1 << NET_CAPABILITY_VALIDATED) 392 | (1 << NET_CAPABILITY_CAPTIVE_PORTAL) 393 | (1 << NET_CAPABILITY_FOREGROUND) 394 | (1 << NET_CAPABILITY_PARTIAL_CONNECTIVITY); 395 396 /** 397 * Adds the given capability to this {@code NetworkCapability} instance. 398 * Multiple capabilities may be applied sequentially. Note that when searching 399 * for a network to satisfy a request, all capabilities requested must be satisfied. 400 * <p> 401 * If the given capability was previously added to the list of unwanted capabilities 402 * then the capability will also be removed from the list of unwanted capabilities. 403 * 404 * @param capability the capability to be added. 405 * @return This NetworkCapabilities instance, to facilitate chaining. 406 * @hide 407 */ 408 @UnsupportedAppUsage addCapability(@etCapability int capability)409 public @NonNull NetworkCapabilities addCapability(@NetCapability int capability) { 410 checkValidCapability(capability); 411 mNetworkCapabilities |= 1 << capability; 412 mUnwantedNetworkCapabilities &= ~(1 << capability); // remove from unwanted capability list 413 return this; 414 } 415 416 /** 417 * Adds the given capability to the list of unwanted capabilities of this 418 * {@code NetworkCapability} instance. Multiple unwanted capabilities may be applied 419 * sequentially. Note that when searching for a network to satisfy a request, the network 420 * must not contain any capability from unwanted capability list. 421 * <p> 422 * If the capability was previously added to the list of required capabilities (for 423 * example, it was there by default or added using {@link #addCapability(int)} method), then 424 * it will be removed from the list of required capabilities as well. 425 * 426 * @see #addCapability(int) 427 * @hide 428 */ addUnwantedCapability(@etCapability int capability)429 public void addUnwantedCapability(@NetCapability int capability) { 430 checkValidCapability(capability); 431 mUnwantedNetworkCapabilities |= 1 << capability; 432 mNetworkCapabilities &= ~(1 << capability); // remove from requested capabilities 433 } 434 435 /** 436 * Removes (if found) the given capability from this {@code NetworkCapability} instance. 437 * <p> 438 * Note that this method removes capabilities that were added via {@link #addCapability(int)}, 439 * {@link #addUnwantedCapability(int)} or {@link #setCapabilities(int[], int[])} . 440 * 441 * @param capability the capability to be removed. 442 * @return This NetworkCapabilities instance, to facilitate chaining. 443 * @hide 444 */ 445 @UnsupportedAppUsage removeCapability(@etCapability int capability)446 public @NonNull NetworkCapabilities removeCapability(@NetCapability int capability) { 447 checkValidCapability(capability); 448 final long mask = ~(1 << capability); 449 mNetworkCapabilities &= mask; 450 mUnwantedNetworkCapabilities &= mask; 451 return this; 452 } 453 454 /** 455 * Sets (or clears) the given capability on this {@link NetworkCapabilities} 456 * instance. 457 * 458 * @hide 459 */ setCapability(@etCapability int capability, boolean value)460 public @NonNull NetworkCapabilities setCapability(@NetCapability int capability, 461 boolean value) { 462 if (value) { 463 addCapability(capability); 464 } else { 465 removeCapability(capability); 466 } 467 return this; 468 } 469 470 /** 471 * Gets all the capabilities set on this {@code NetworkCapability} instance. 472 * 473 * @return an array of capability values for this instance. 474 * @hide 475 */ 476 @TestApi getCapabilities()477 public @NetCapability int[] getCapabilities() { 478 return BitUtils.unpackBits(mNetworkCapabilities); 479 } 480 481 /** 482 * Gets all the unwanted capabilities set on this {@code NetworkCapability} instance. 483 * 484 * @return an array of unwanted capability values for this instance. 485 * @hide 486 */ getUnwantedCapabilities()487 public @NetCapability int[] getUnwantedCapabilities() { 488 return BitUtils.unpackBits(mUnwantedNetworkCapabilities); 489 } 490 491 492 /** 493 * Sets all the capabilities set on this {@code NetworkCapability} instance. 494 * This overwrites any existing capabilities. 495 * 496 * @hide 497 */ setCapabilities(@etCapability int[] capabilities, @NetCapability int[] unwantedCapabilities)498 public void setCapabilities(@NetCapability int[] capabilities, 499 @NetCapability int[] unwantedCapabilities) { 500 mNetworkCapabilities = BitUtils.packBits(capabilities); 501 mUnwantedNetworkCapabilities = BitUtils.packBits(unwantedCapabilities); 502 } 503 504 /** 505 * @deprecated use {@link #setCapabilities(int[], int[])} 506 * @hide 507 */ 508 @Deprecated setCapabilities(@etCapability int[] capabilities)509 public void setCapabilities(@NetCapability int[] capabilities) { 510 setCapabilities(capabilities, new int[] {}); 511 } 512 513 /** 514 * Tests for the presence of a capability on this instance. 515 * 516 * @param capability the capabilities to be tested for. 517 * @return {@code true} if set on this instance. 518 */ hasCapability(@etCapability int capability)519 public boolean hasCapability(@NetCapability int capability) { 520 return isValidCapability(capability) 521 && ((mNetworkCapabilities & (1 << capability)) != 0); 522 } 523 524 /** @hide */ hasUnwantedCapability(@etCapability int capability)525 public boolean hasUnwantedCapability(@NetCapability int capability) { 526 return isValidCapability(capability) 527 && ((mUnwantedNetworkCapabilities & (1 << capability)) != 0); 528 } 529 530 /** 531 * Check if this NetworkCapabilities has system managed capabilities or not. 532 * @hide 533 */ hasConnectivityManagedCapability()534 public boolean hasConnectivityManagedCapability() { 535 return ((mNetworkCapabilities & CONNECTIVITY_MANAGED_CAPABILITIES) != 0); 536 } 537 538 /** Note this method may result in having the same capability in wanted and unwanted lists. */ combineNetCapabilities(@onNull NetworkCapabilities nc)539 private void combineNetCapabilities(@NonNull NetworkCapabilities nc) { 540 this.mNetworkCapabilities |= nc.mNetworkCapabilities; 541 this.mUnwantedNetworkCapabilities |= nc.mUnwantedNetworkCapabilities; 542 } 543 544 /** 545 * Convenience function that returns a human-readable description of the first mutable 546 * capability we find. Used to present an error message to apps that request mutable 547 * capabilities. 548 * 549 * @hide 550 */ describeFirstNonRequestableCapability()551 public @Nullable String describeFirstNonRequestableCapability() { 552 final long nonRequestable = (mNetworkCapabilities | mUnwantedNetworkCapabilities) 553 & NON_REQUESTABLE_CAPABILITIES; 554 555 if (nonRequestable != 0) { 556 return capabilityNameOf(BitUtils.unpackBits(nonRequestable)[0]); 557 } 558 if (mLinkUpBandwidthKbps != 0 || mLinkDownBandwidthKbps != 0) return "link bandwidth"; 559 if (hasSignalStrength()) return "signalStrength"; 560 return null; 561 } 562 satisfiedByNetCapabilities(@onNull NetworkCapabilities nc, boolean onlyImmutable)563 private boolean satisfiedByNetCapabilities(@NonNull NetworkCapabilities nc, 564 boolean onlyImmutable) { 565 long requestedCapabilities = mNetworkCapabilities; 566 long requestedUnwantedCapabilities = mUnwantedNetworkCapabilities; 567 long providedCapabilities = nc.mNetworkCapabilities; 568 569 if (onlyImmutable) { 570 requestedCapabilities &= ~MUTABLE_CAPABILITIES; 571 requestedUnwantedCapabilities &= ~MUTABLE_CAPABILITIES; 572 } 573 return ((providedCapabilities & requestedCapabilities) == requestedCapabilities) 574 && ((requestedUnwantedCapabilities & providedCapabilities) == 0); 575 } 576 577 /** @hide */ equalsNetCapabilities(@onNull NetworkCapabilities nc)578 public boolean equalsNetCapabilities(@NonNull NetworkCapabilities nc) { 579 return (nc.mNetworkCapabilities == this.mNetworkCapabilities) 580 && (nc.mUnwantedNetworkCapabilities == this.mUnwantedNetworkCapabilities); 581 } 582 equalsNetCapabilitiesRequestable(@onNull NetworkCapabilities that)583 private boolean equalsNetCapabilitiesRequestable(@NonNull NetworkCapabilities that) { 584 return ((this.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) == 585 (that.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES)) 586 && ((this.mUnwantedNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) == 587 (that.mUnwantedNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES)); 588 } 589 590 /** 591 * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if all the capabilities it provides are 592 * typically provided by restricted networks. 593 * 594 * TODO: consider: 595 * - Renaming it to guessRestrictedCapability and make it set the 596 * restricted capability bit in addition to clearing it. 597 * @hide 598 */ maybeMarkCapabilitiesRestricted()599 public void maybeMarkCapabilitiesRestricted() { 600 // Check if we have any capability that forces the network to be restricted. 601 final boolean forceRestrictedCapability = 602 (mNetworkCapabilities & FORCE_RESTRICTED_CAPABILITIES) != 0; 603 604 // Verify there aren't any unrestricted capabilities. If there are we say 605 // the whole thing is unrestricted unless it is forced to be restricted. 606 final boolean hasUnrestrictedCapabilities = 607 (mNetworkCapabilities & UNRESTRICTED_CAPABILITIES) != 0; 608 609 // Must have at least some restricted capabilities. 610 final boolean hasRestrictedCapabilities = 611 (mNetworkCapabilities & RESTRICTED_CAPABILITIES) != 0; 612 613 if (forceRestrictedCapability 614 || (hasRestrictedCapabilities && !hasUnrestrictedCapabilities)) { 615 removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 616 } 617 } 618 619 /** 620 * Representing the transport type. Apps should generally not care about transport. A 621 * request for a fast internet connection could be satisfied by a number of different 622 * transports. If any are specified here it will be satisfied a Network that matches 623 * any of them. If a caller doesn't care about the transport it should not specify any. 624 */ 625 private long mTransportTypes; 626 627 /** @hide */ 628 @Retention(RetentionPolicy.SOURCE) 629 @IntDef(prefix = { "TRANSPORT_" }, value = { 630 TRANSPORT_CELLULAR, 631 TRANSPORT_WIFI, 632 TRANSPORT_BLUETOOTH, 633 TRANSPORT_ETHERNET, 634 TRANSPORT_VPN, 635 TRANSPORT_WIFI_AWARE, 636 TRANSPORT_LOWPAN, 637 TRANSPORT_TEST, 638 }) 639 public @interface Transport { } 640 641 /** 642 * Indicates this network uses a Cellular transport. 643 */ 644 public static final int TRANSPORT_CELLULAR = 0; 645 646 /** 647 * Indicates this network uses a Wi-Fi transport. 648 */ 649 public static final int TRANSPORT_WIFI = 1; 650 651 /** 652 * Indicates this network uses a Bluetooth transport. 653 */ 654 public static final int TRANSPORT_BLUETOOTH = 2; 655 656 /** 657 * Indicates this network uses an Ethernet transport. 658 */ 659 public static final int TRANSPORT_ETHERNET = 3; 660 661 /** 662 * Indicates this network uses a VPN transport. 663 */ 664 public static final int TRANSPORT_VPN = 4; 665 666 /** 667 * Indicates this network uses a Wi-Fi Aware transport. 668 */ 669 public static final int TRANSPORT_WIFI_AWARE = 5; 670 671 /** 672 * Indicates this network uses a LoWPAN transport. 673 */ 674 public static final int TRANSPORT_LOWPAN = 6; 675 676 /** 677 * Indicates this network uses a Test-only virtual interface as a transport. 678 * 679 * @hide 680 */ 681 @TestApi 682 public static final int TRANSPORT_TEST = 7; 683 684 /** @hide */ 685 public static final int MIN_TRANSPORT = TRANSPORT_CELLULAR; 686 /** @hide */ 687 public static final int MAX_TRANSPORT = TRANSPORT_TEST; 688 689 /** @hide */ isValidTransport(@ransport int transportType)690 public static boolean isValidTransport(@Transport int transportType) { 691 return (MIN_TRANSPORT <= transportType) && (transportType <= MAX_TRANSPORT); 692 } 693 694 private static final String[] TRANSPORT_NAMES = { 695 "CELLULAR", 696 "WIFI", 697 "BLUETOOTH", 698 "ETHERNET", 699 "VPN", 700 "WIFI_AWARE", 701 "LOWPAN", 702 "TEST" 703 }; 704 705 /** 706 * Adds the given transport type to this {@code NetworkCapability} instance. 707 * Multiple transports may be applied sequentially. Note that when searching 708 * for a network to satisfy a request, any listed in the request will satisfy the request. 709 * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a 710 * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network 711 * to be selected. This is logically different than 712 * {@code NetworkCapabilities.NET_CAPABILITY_*} listed above. 713 * 714 * @param transportType the transport type to be added. 715 * @return This NetworkCapabilities instance, to facilitate chaining. 716 * @hide 717 */ 718 @UnsupportedAppUsage addTransportType(@ransport int transportType)719 public @NonNull NetworkCapabilities addTransportType(@Transport int transportType) { 720 checkValidTransportType(transportType); 721 mTransportTypes |= 1 << transportType; 722 setNetworkSpecifier(mNetworkSpecifier); // used for exception checking 723 return this; 724 } 725 726 /** 727 * Removes (if found) the given transport from this {@code NetworkCapability} instance. 728 * 729 * @param transportType the transport type to be removed. 730 * @return This NetworkCapabilities instance, to facilitate chaining. 731 * @hide 732 */ removeTransportType(@ransport int transportType)733 public @NonNull NetworkCapabilities removeTransportType(@Transport int transportType) { 734 checkValidTransportType(transportType); 735 mTransportTypes &= ~(1 << transportType); 736 setNetworkSpecifier(mNetworkSpecifier); // used for exception checking 737 return this; 738 } 739 740 /** 741 * Sets (or clears) the given transport on this {@link NetworkCapabilities} 742 * instance. 743 * 744 * @hide 745 */ setTransportType(@ransport int transportType, boolean value)746 public @NonNull NetworkCapabilities setTransportType(@Transport int transportType, 747 boolean value) { 748 if (value) { 749 addTransportType(transportType); 750 } else { 751 removeTransportType(transportType); 752 } 753 return this; 754 } 755 756 /** 757 * Gets all the transports set on this {@code NetworkCapability} instance. 758 * 759 * @return an array of transport type values for this instance. 760 * @hide 761 */ 762 @TestApi 763 @SystemApi getTransportTypes()764 @NonNull public @Transport int[] getTransportTypes() { 765 return BitUtils.unpackBits(mTransportTypes); 766 } 767 768 /** 769 * Sets all the transports set on this {@code NetworkCapability} instance. 770 * This overwrites any existing transports. 771 * 772 * @hide 773 */ setTransportTypes(@ransport int[] transportTypes)774 public void setTransportTypes(@Transport int[] transportTypes) { 775 mTransportTypes = BitUtils.packBits(transportTypes); 776 } 777 778 /** 779 * Tests for the presence of a transport on this instance. 780 * 781 * @param transportType the transport type to be tested for. 782 * @return {@code true} if set on this instance. 783 */ hasTransport(@ransport int transportType)784 public boolean hasTransport(@Transport int transportType) { 785 return isValidTransport(transportType) && ((mTransportTypes & (1 << transportType)) != 0); 786 } 787 combineTransportTypes(NetworkCapabilities nc)788 private void combineTransportTypes(NetworkCapabilities nc) { 789 this.mTransportTypes |= nc.mTransportTypes; 790 } 791 satisfiedByTransportTypes(NetworkCapabilities nc)792 private boolean satisfiedByTransportTypes(NetworkCapabilities nc) { 793 return ((this.mTransportTypes == 0) || 794 ((this.mTransportTypes & nc.mTransportTypes) != 0)); 795 } 796 797 /** @hide */ equalsTransportTypes(NetworkCapabilities nc)798 public boolean equalsTransportTypes(NetworkCapabilities nc) { 799 return (nc.mTransportTypes == this.mTransportTypes); 800 } 801 802 /** 803 * UID of the app that manages this network, or INVALID_UID if none/unknown. 804 * 805 * This field keeps track of the UID of the app that created this network and is in charge 806 * of managing it. In the practice, it is used to store the UID of VPN apps so it is named 807 * accordingly, but it may be renamed if other mechanisms are offered for third party apps 808 * to create networks. 809 * 810 * Because this field is only used in the services side (and to avoid apps being able to 811 * set this to whatever they want), this field is not parcelled and will not be conserved 812 * across the IPC boundary. 813 * @hide 814 */ 815 private int mEstablishingVpnAppUid = INVALID_UID; 816 817 /** 818 * Set the UID of the managing app. 819 * @hide 820 */ setEstablishingVpnAppUid(final int uid)821 public void setEstablishingVpnAppUid(final int uid) { 822 mEstablishingVpnAppUid = uid; 823 } 824 825 /** @hide */ getEstablishingVpnAppUid()826 public int getEstablishingVpnAppUid() { 827 return mEstablishingVpnAppUid; 828 } 829 830 /** 831 * Value indicating that link bandwidth is unspecified. 832 * @hide 833 */ 834 public static final int LINK_BANDWIDTH_UNSPECIFIED = 0; 835 836 /** 837 * Passive link bandwidth. This is a rough guide of the expected peak bandwidth 838 * for the first hop on the given transport. It is not measured, but may take into account 839 * link parameters (Radio technology, allocated channels, etc). 840 */ 841 private int mLinkUpBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED; 842 private int mLinkDownBandwidthKbps = LINK_BANDWIDTH_UNSPECIFIED; 843 844 /** 845 * Sets the upstream bandwidth for this network in Kbps. This always only refers to 846 * the estimated first hop transport bandwidth. 847 * <p> 848 * Note that when used to request a network, this specifies the minimum acceptable. 849 * When received as the state of an existing network this specifies the typical 850 * first hop bandwidth expected. This is never measured, but rather is inferred 851 * from technology type and other link parameters. It could be used to differentiate 852 * between very slow 1xRTT cellular links and other faster networks or even between 853 * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between 854 * fast backhauls and slow backhauls. 855 * 856 * @param upKbps the estimated first hop upstream (device to network) bandwidth. 857 * @hide 858 */ setLinkUpstreamBandwidthKbps(int upKbps)859 public @NonNull NetworkCapabilities setLinkUpstreamBandwidthKbps(int upKbps) { 860 mLinkUpBandwidthKbps = upKbps; 861 return this; 862 } 863 864 /** 865 * Retrieves the upstream bandwidth for this network in Kbps. This always only refers to 866 * the estimated first hop transport bandwidth. 867 * 868 * @return The estimated first hop upstream (device to network) bandwidth. 869 */ getLinkUpstreamBandwidthKbps()870 public int getLinkUpstreamBandwidthKbps() { 871 return mLinkUpBandwidthKbps; 872 } 873 874 /** 875 * Sets the downstream bandwidth for this network in Kbps. This always only refers to 876 * the estimated first hop transport bandwidth. 877 * <p> 878 * Note that when used to request a network, this specifies the minimum acceptable. 879 * When received as the state of an existing network this specifies the typical 880 * first hop bandwidth expected. This is never measured, but rather is inferred 881 * from technology type and other link parameters. It could be used to differentiate 882 * between very slow 1xRTT cellular links and other faster networks or even between 883 * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between 884 * fast backhauls and slow backhauls. 885 * 886 * @param downKbps the estimated first hop downstream (network to device) bandwidth. 887 * @hide 888 */ setLinkDownstreamBandwidthKbps(int downKbps)889 public @NonNull NetworkCapabilities setLinkDownstreamBandwidthKbps(int downKbps) { 890 mLinkDownBandwidthKbps = downKbps; 891 return this; 892 } 893 894 /** 895 * Retrieves the downstream bandwidth for this network in Kbps. This always only refers to 896 * the estimated first hop transport bandwidth. 897 * 898 * @return The estimated first hop downstream (network to device) bandwidth. 899 */ getLinkDownstreamBandwidthKbps()900 public int getLinkDownstreamBandwidthKbps() { 901 return mLinkDownBandwidthKbps; 902 } 903 combineLinkBandwidths(NetworkCapabilities nc)904 private void combineLinkBandwidths(NetworkCapabilities nc) { 905 this.mLinkUpBandwidthKbps = 906 Math.max(this.mLinkUpBandwidthKbps, nc.mLinkUpBandwidthKbps); 907 this.mLinkDownBandwidthKbps = 908 Math.max(this.mLinkDownBandwidthKbps, nc.mLinkDownBandwidthKbps); 909 } satisfiedByLinkBandwidths(NetworkCapabilities nc)910 private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) { 911 return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps || 912 this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps); 913 } equalsLinkBandwidths(NetworkCapabilities nc)914 private boolean equalsLinkBandwidths(NetworkCapabilities nc) { 915 return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps && 916 this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps); 917 } 918 /** @hide */ minBandwidth(int a, int b)919 public static int minBandwidth(int a, int b) { 920 if (a == LINK_BANDWIDTH_UNSPECIFIED) { 921 return b; 922 } else if (b == LINK_BANDWIDTH_UNSPECIFIED) { 923 return a; 924 } else { 925 return Math.min(a, b); 926 } 927 } 928 /** @hide */ maxBandwidth(int a, int b)929 public static int maxBandwidth(int a, int b) { 930 return Math.max(a, b); 931 } 932 933 private NetworkSpecifier mNetworkSpecifier = null; 934 private TransportInfo mTransportInfo = null; 935 936 /** 937 * Sets the optional bearer specific network specifier. 938 * This has no meaning if a single transport is also not specified, so calling 939 * this without a single transport set will generate an exception, as will 940 * subsequently adding or removing transports after this is set. 941 * </p> 942 * 943 * @param networkSpecifier A concrete, parcelable framework class that extends 944 * NetworkSpecifier. 945 * @return This NetworkCapabilities instance, to facilitate chaining. 946 * @hide 947 */ setNetworkSpecifier(NetworkSpecifier networkSpecifier)948 public @NonNull NetworkCapabilities setNetworkSpecifier(NetworkSpecifier networkSpecifier) { 949 if (networkSpecifier != null && Long.bitCount(mTransportTypes) != 1) { 950 throw new IllegalStateException("Must have a single transport specified to use " + 951 "setNetworkSpecifier"); 952 } 953 954 mNetworkSpecifier = networkSpecifier; 955 956 return this; 957 } 958 959 /** 960 * Sets the optional transport specific information. 961 * 962 * @param transportInfo A concrete, parcelable framework class that extends 963 * {@link TransportInfo}. 964 * @return This NetworkCapabilities instance, to facilitate chaining. 965 * @hide 966 */ setTransportInfo(TransportInfo transportInfo)967 public @NonNull NetworkCapabilities setTransportInfo(TransportInfo transportInfo) { 968 mTransportInfo = transportInfo; 969 return this; 970 } 971 972 /** 973 * Gets the optional bearer specific network specifier. May be {@code null} if not set. 974 * 975 * @return The optional {@link NetworkSpecifier} specifying the bearer specific network 976 * specifier or {@code null}. See {@link #setNetworkSpecifier}. 977 * @hide 978 */ 979 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) getNetworkSpecifier()980 public @Nullable NetworkSpecifier getNetworkSpecifier() { 981 return mNetworkSpecifier; 982 } 983 984 /** 985 * Returns a transport-specific information container. The application may cast this 986 * container to a concrete sub-class based on its knowledge of the network request. The 987 * application should be able to deal with a {@code null} return value or an invalid case, 988 * e.g. use {@code instanceof} operator to verify expected type. 989 * 990 * @return A concrete implementation of the {@link TransportInfo} class or null if not 991 * available for the network. 992 */ getTransportInfo()993 @Nullable public TransportInfo getTransportInfo() { 994 return mTransportInfo; 995 } 996 combineSpecifiers(NetworkCapabilities nc)997 private void combineSpecifiers(NetworkCapabilities nc) { 998 if (mNetworkSpecifier != null && !mNetworkSpecifier.equals(nc.mNetworkSpecifier)) { 999 throw new IllegalStateException("Can't combine two networkSpecifiers"); 1000 } 1001 setNetworkSpecifier(nc.mNetworkSpecifier); 1002 } 1003 satisfiedBySpecifier(NetworkCapabilities nc)1004 private boolean satisfiedBySpecifier(NetworkCapabilities nc) { 1005 return mNetworkSpecifier == null || mNetworkSpecifier.satisfiedBy(nc.mNetworkSpecifier) 1006 || nc.mNetworkSpecifier instanceof MatchAllNetworkSpecifier; 1007 } 1008 equalsSpecifier(NetworkCapabilities nc)1009 private boolean equalsSpecifier(NetworkCapabilities nc) { 1010 return Objects.equals(mNetworkSpecifier, nc.mNetworkSpecifier); 1011 } 1012 combineTransportInfos(NetworkCapabilities nc)1013 private void combineTransportInfos(NetworkCapabilities nc) { 1014 if (mTransportInfo != null && !mTransportInfo.equals(nc.mTransportInfo)) { 1015 throw new IllegalStateException("Can't combine two TransportInfos"); 1016 } 1017 setTransportInfo(nc.mTransportInfo); 1018 } 1019 equalsTransportInfo(NetworkCapabilities nc)1020 private boolean equalsTransportInfo(NetworkCapabilities nc) { 1021 return Objects.equals(mTransportInfo, nc.mTransportInfo); 1022 } 1023 1024 /** 1025 * Magic value that indicates no signal strength provided. A request specifying this value is 1026 * always satisfied. 1027 */ 1028 public static final int SIGNAL_STRENGTH_UNSPECIFIED = Integer.MIN_VALUE; 1029 1030 /** 1031 * Signal strength. This is a signed integer, and higher values indicate better signal. 1032 * The exact units are bearer-dependent. For example, Wi-Fi uses RSSI. 1033 */ 1034 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) 1035 private int mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED; 1036 1037 /** 1038 * Sets the signal strength. This is a signed integer, with higher values indicating a stronger 1039 * signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same RSSI units 1040 * reported by wifi code. 1041 * <p> 1042 * Note that when used to register a network callback, this specifies the minimum acceptable 1043 * signal strength. When received as the state of an existing network it specifies the current 1044 * value. A value of code SIGNAL_STRENGTH_UNSPECIFIED} means no value when received and has no 1045 * effect when requesting a callback. 1046 * 1047 * @param signalStrength the bearer-specific signal strength. 1048 * @hide 1049 */ 1050 @UnsupportedAppUsage setSignalStrength(int signalStrength)1051 public @NonNull NetworkCapabilities setSignalStrength(int signalStrength) { 1052 mSignalStrength = signalStrength; 1053 return this; 1054 } 1055 1056 /** 1057 * Returns {@code true} if this object specifies a signal strength. 1058 * 1059 * @hide 1060 */ 1061 @UnsupportedAppUsage hasSignalStrength()1062 public boolean hasSignalStrength() { 1063 return mSignalStrength > SIGNAL_STRENGTH_UNSPECIFIED; 1064 } 1065 1066 /** 1067 * Retrieves the signal strength. 1068 * 1069 * @return The bearer-specific signal strength. 1070 */ getSignalStrength()1071 public int getSignalStrength() { 1072 return mSignalStrength; 1073 } 1074 combineSignalStrength(NetworkCapabilities nc)1075 private void combineSignalStrength(NetworkCapabilities nc) { 1076 this.mSignalStrength = Math.max(this.mSignalStrength, nc.mSignalStrength); 1077 } 1078 satisfiedBySignalStrength(NetworkCapabilities nc)1079 private boolean satisfiedBySignalStrength(NetworkCapabilities nc) { 1080 return this.mSignalStrength <= nc.mSignalStrength; 1081 } 1082 equalsSignalStrength(NetworkCapabilities nc)1083 private boolean equalsSignalStrength(NetworkCapabilities nc) { 1084 return this.mSignalStrength == nc.mSignalStrength; 1085 } 1086 1087 /** 1088 * List of UIDs this network applies to. No restriction if null. 1089 * <p> 1090 * For networks, mUids represent the list of network this applies to, and null means this 1091 * network applies to all UIDs. 1092 * For requests, mUids is the list of UIDs this network MUST apply to to match ; ALL UIDs 1093 * must be included in a network so that they match. As an exception to the general rule, 1094 * a null mUids field for requests mean "no requirements" rather than what the general rule 1095 * would suggest ("must apply to all UIDs") : this is because this has shown to be what users 1096 * of this API expect in practice. A network that must match all UIDs can still be 1097 * expressed with a set ranging the entire set of possible UIDs. 1098 * <p> 1099 * mUids is typically (and at this time, only) used by VPN. This network is only available to 1100 * the UIDs in this list, and it is their default network. Apps in this list that wish to 1101 * bypass the VPN can do so iff the VPN app allows them to or if they are privileged. If this 1102 * member is null, then the network is not restricted by app UID. If it's an empty list, then 1103 * it means nobody can use it. 1104 * As a special exception, the app managing this network (as identified by its UID stored in 1105 * mEstablishingVpnAppUid) can always see this network. This is embodied by a special check in 1106 * satisfiedByUids. That still does not mean the network necessarily <strong>applies</strong> 1107 * to the app that manages it as determined by #appliesToUid. 1108 * <p> 1109 * Please note that in principle a single app can be associated with multiple UIDs because 1110 * each app will have a different UID when it's run as a different (macro-)user. A single 1111 * macro user can only have a single active VPN app at any given time however. 1112 * <p> 1113 * Also please be aware this class does not try to enforce any normalization on this. Callers 1114 * can only alter the UIDs by setting them wholesale : this class does not provide any utility 1115 * to add or remove individual UIDs or ranges. If callers have any normalization needs on 1116 * their own (like requiring sortedness or no overlap) they need to enforce it 1117 * themselves. Some of the internal methods also assume this is normalized as in no adjacent 1118 * or overlapping ranges are present. 1119 * 1120 * @hide 1121 */ 1122 private ArraySet<UidRange> mUids = null; 1123 1124 /** 1125 * Convenience method to set the UIDs this network applies to to a single UID. 1126 * @hide 1127 */ setSingleUid(int uid)1128 public @NonNull NetworkCapabilities setSingleUid(int uid) { 1129 final ArraySet<UidRange> identity = new ArraySet<>(1); 1130 identity.add(new UidRange(uid, uid)); 1131 setUids(identity); 1132 return this; 1133 } 1134 1135 /** 1136 * Set the list of UIDs this network applies to. 1137 * This makes a copy of the set so that callers can't modify it after the call. 1138 * @hide 1139 */ setUids(Set<UidRange> uids)1140 public @NonNull NetworkCapabilities setUids(Set<UidRange> uids) { 1141 if (null == uids) { 1142 mUids = null; 1143 } else { 1144 mUids = new ArraySet<>(uids); 1145 } 1146 return this; 1147 } 1148 1149 /** 1150 * Get the list of UIDs this network applies to. 1151 * This returns a copy of the set so that callers can't modify the original object. 1152 * @hide 1153 */ getUids()1154 public @Nullable Set<UidRange> getUids() { 1155 return null == mUids ? null : new ArraySet<>(mUids); 1156 } 1157 1158 /** 1159 * Test whether this network applies to this UID. 1160 * @hide 1161 */ appliesToUid(int uid)1162 public boolean appliesToUid(int uid) { 1163 if (null == mUids) return true; 1164 for (UidRange range : mUids) { 1165 if (range.contains(uid)) { 1166 return true; 1167 } 1168 } 1169 return false; 1170 } 1171 1172 /** 1173 * Tests if the set of UIDs that this network applies to is the same as the passed network. 1174 * <p> 1175 * This test only checks whether equal range objects are in both sets. It will 1176 * return false if the ranges are not exactly the same, even if the covered UIDs 1177 * are for an equivalent result. 1178 * <p> 1179 * Note that this method is not very optimized, which is fine as long as it's not used very 1180 * often. 1181 * <p> 1182 * nc is assumed nonnull. 1183 * 1184 * @hide 1185 */ 1186 @VisibleForTesting equalsUids(@onNull NetworkCapabilities nc)1187 public boolean equalsUids(@NonNull NetworkCapabilities nc) { 1188 Set<UidRange> comparedUids = nc.mUids; 1189 if (null == comparedUids) return null == mUids; 1190 if (null == mUids) return false; 1191 // Make a copy so it can be mutated to check that all ranges in mUids 1192 // also are in uids. 1193 final Set<UidRange> uids = new ArraySet<>(mUids); 1194 for (UidRange range : comparedUids) { 1195 if (!uids.contains(range)) { 1196 return false; 1197 } 1198 uids.remove(range); 1199 } 1200 return uids.isEmpty(); 1201 } 1202 1203 /** 1204 * Test whether the passed NetworkCapabilities satisfies the UIDs this capabilities require. 1205 * 1206 * This method is called on the NetworkCapabilities embedded in a request with the 1207 * capabilities of an available network. It checks whether all the UIDs from this listen 1208 * (representing the UIDs that must have access to the network) are satisfied by the UIDs 1209 * in the passed nc (representing the UIDs that this network is available to). 1210 * <p> 1211 * As a special exception, the UID that created the passed network (as represented by its 1212 * mEstablishingVpnAppUid field) always satisfies a NetworkRequest requiring it (of LISTEN 1213 * or REQUEST types alike), even if the network does not apply to it. That is so a VPN app 1214 * can see its own network when it listens for it. 1215 * <p> 1216 * nc is assumed nonnull. Else, NPE. 1217 * @see #appliesToUid 1218 * @hide 1219 */ satisfiedByUids(@onNull NetworkCapabilities nc)1220 public boolean satisfiedByUids(@NonNull NetworkCapabilities nc) { 1221 if (null == nc.mUids || null == mUids) return true; // The network satisfies everything. 1222 for (UidRange requiredRange : mUids) { 1223 if (requiredRange.contains(nc.mEstablishingVpnAppUid)) return true; 1224 if (!nc.appliesToUidRange(requiredRange)) { 1225 return false; 1226 } 1227 } 1228 return true; 1229 } 1230 1231 /** 1232 * Returns whether this network applies to the passed ranges. 1233 * This assumes that to apply, the passed range has to be entirely contained 1234 * within one of the ranges this network applies to. If the ranges are not normalized, 1235 * this method may return false even though all required UIDs are covered because no 1236 * single range contained them all. 1237 * @hide 1238 */ 1239 @VisibleForTesting appliesToUidRange(@ullable UidRange requiredRange)1240 public boolean appliesToUidRange(@Nullable UidRange requiredRange) { 1241 if (null == mUids) return true; 1242 for (UidRange uidRange : mUids) { 1243 if (uidRange.containsRange(requiredRange)) { 1244 return true; 1245 } 1246 } 1247 return false; 1248 } 1249 1250 /** 1251 * Combine the UIDs this network currently applies to with the UIDs the passed 1252 * NetworkCapabilities apply to. 1253 * nc is assumed nonnull. 1254 */ combineUids(@onNull NetworkCapabilities nc)1255 private void combineUids(@NonNull NetworkCapabilities nc) { 1256 if (null == nc.mUids || null == mUids) { 1257 mUids = null; 1258 return; 1259 } 1260 mUids.addAll(nc.mUids); 1261 } 1262 1263 1264 /** 1265 * The SSID of the network, or null if not applicable or unknown. 1266 * <p> 1267 * This is filled in by wifi code. 1268 * @hide 1269 */ 1270 private String mSSID; 1271 1272 /** 1273 * Sets the SSID of this network. 1274 * @hide 1275 */ setSSID(@ullable String ssid)1276 public @NonNull NetworkCapabilities setSSID(@Nullable String ssid) { 1277 mSSID = ssid; 1278 return this; 1279 } 1280 1281 /** 1282 * Gets the SSID of this network, or null if none or unknown. 1283 * @hide 1284 */ getSSID()1285 public @Nullable String getSSID() { 1286 return mSSID; 1287 } 1288 1289 /** 1290 * Tests if the SSID of this network is the same as the SSID of the passed network. 1291 * @hide 1292 */ equalsSSID(@onNull NetworkCapabilities nc)1293 public boolean equalsSSID(@NonNull NetworkCapabilities nc) { 1294 return Objects.equals(mSSID, nc.mSSID); 1295 } 1296 1297 /** 1298 * Check if the SSID requirements of this object are matched by the passed object. 1299 * @hide 1300 */ satisfiedBySSID(@onNull NetworkCapabilities nc)1301 public boolean satisfiedBySSID(@NonNull NetworkCapabilities nc) { 1302 return mSSID == null || mSSID.equals(nc.mSSID); 1303 } 1304 1305 /** 1306 * Combine SSIDs of the capabilities. 1307 * <p> 1308 * This is only legal if either the SSID of this object is null, or both SSIDs are 1309 * equal. 1310 * @hide 1311 */ combineSSIDs(@onNull NetworkCapabilities nc)1312 private void combineSSIDs(@NonNull NetworkCapabilities nc) { 1313 if (mSSID != null && !mSSID.equals(nc.mSSID)) { 1314 throw new IllegalStateException("Can't combine two SSIDs"); 1315 } 1316 setSSID(nc.mSSID); 1317 } 1318 1319 /** 1320 * Combine a set of Capabilities to this one. Useful for coming up with the complete set. 1321 * <p> 1322 * Note that this method may break an invariant of having a particular capability in either 1323 * wanted or unwanted lists but never in both. Requests that have the same capability in 1324 * both lists will never be satisfied. 1325 * @hide 1326 */ combineCapabilities(@onNull NetworkCapabilities nc)1327 public void combineCapabilities(@NonNull NetworkCapabilities nc) { 1328 combineNetCapabilities(nc); 1329 combineTransportTypes(nc); 1330 combineLinkBandwidths(nc); 1331 combineSpecifiers(nc); 1332 combineTransportInfos(nc); 1333 combineSignalStrength(nc); 1334 combineUids(nc); 1335 combineSSIDs(nc); 1336 } 1337 1338 /** 1339 * Check if our requirements are satisfied by the given {@code NetworkCapabilities}. 1340 * 1341 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements. 1342 * @param onlyImmutable if {@code true}, do not consider mutable requirements such as link 1343 * bandwidth, signal strength, or validation / captive portal status. 1344 * 1345 * @hide 1346 */ satisfiedByNetworkCapabilities(NetworkCapabilities nc, boolean onlyImmutable)1347 private boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc, boolean onlyImmutable) { 1348 return (nc != null 1349 && satisfiedByNetCapabilities(nc, onlyImmutable) 1350 && satisfiedByTransportTypes(nc) 1351 && (onlyImmutable || satisfiedByLinkBandwidths(nc)) 1352 && satisfiedBySpecifier(nc) 1353 && (onlyImmutable || satisfiedBySignalStrength(nc)) 1354 && (onlyImmutable || satisfiedByUids(nc)) 1355 && (onlyImmutable || satisfiedBySSID(nc))); 1356 } 1357 1358 /** 1359 * Check if our requirements are satisfied by the given {@code NetworkCapabilities}. 1360 * 1361 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements. 1362 * 1363 * @hide 1364 */ 1365 @TestApi 1366 @SystemApi satisfiedByNetworkCapabilities(@ullable NetworkCapabilities nc)1367 public boolean satisfiedByNetworkCapabilities(@Nullable NetworkCapabilities nc) { 1368 return satisfiedByNetworkCapabilities(nc, false); 1369 } 1370 1371 /** 1372 * Check if our immutable requirements are satisfied by the given {@code NetworkCapabilities}. 1373 * 1374 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements. 1375 * 1376 * @hide 1377 */ satisfiedByImmutableNetworkCapabilities(@ullable NetworkCapabilities nc)1378 public boolean satisfiedByImmutableNetworkCapabilities(@Nullable NetworkCapabilities nc) { 1379 return satisfiedByNetworkCapabilities(nc, true); 1380 } 1381 1382 /** 1383 * Checks that our immutable capabilities are the same as those of the given 1384 * {@code NetworkCapabilities} and return a String describing any difference. 1385 * The returned String is empty if there is no difference. 1386 * 1387 * @hide 1388 */ describeImmutableDifferences(@ullable NetworkCapabilities that)1389 public String describeImmutableDifferences(@Nullable NetworkCapabilities that) { 1390 if (that == null) { 1391 return "other NetworkCapabilities was null"; 1392 } 1393 1394 StringJoiner joiner = new StringJoiner(", "); 1395 1396 // Ignore NOT_METERED being added or removed as it is effectively dynamic. http://b/63326103 1397 // TODO: properly support NOT_METERED as a mutable and requestable capability. 1398 final long mask = ~MUTABLE_CAPABILITIES & ~(1 << NET_CAPABILITY_NOT_METERED); 1399 long oldImmutableCapabilities = this.mNetworkCapabilities & mask; 1400 long newImmutableCapabilities = that.mNetworkCapabilities & mask; 1401 if (oldImmutableCapabilities != newImmutableCapabilities) { 1402 String before = capabilityNamesOf(BitUtils.unpackBits(oldImmutableCapabilities)); 1403 String after = capabilityNamesOf(BitUtils.unpackBits(newImmutableCapabilities)); 1404 joiner.add(String.format("immutable capabilities changed: %s -> %s", before, after)); 1405 } 1406 1407 if (!equalsSpecifier(that)) { 1408 NetworkSpecifier before = this.getNetworkSpecifier(); 1409 NetworkSpecifier after = that.getNetworkSpecifier(); 1410 joiner.add(String.format("specifier changed: %s -> %s", before, after)); 1411 } 1412 1413 if (!equalsTransportTypes(that)) { 1414 String before = transportNamesOf(this.getTransportTypes()); 1415 String after = transportNamesOf(that.getTransportTypes()); 1416 joiner.add(String.format("transports changed: %s -> %s", before, after)); 1417 } 1418 1419 return joiner.toString(); 1420 } 1421 1422 /** 1423 * Checks that our requestable capabilities are the same as those of the given 1424 * {@code NetworkCapabilities}. 1425 * 1426 * @hide 1427 */ equalRequestableCapabilities(@ullable NetworkCapabilities nc)1428 public boolean equalRequestableCapabilities(@Nullable NetworkCapabilities nc) { 1429 if (nc == null) return false; 1430 return (equalsNetCapabilitiesRequestable(nc) && 1431 equalsTransportTypes(nc) && 1432 equalsSpecifier(nc)); 1433 } 1434 1435 @Override equals(@ullable Object obj)1436 public boolean equals(@Nullable Object obj) { 1437 if (obj == null || (obj instanceof NetworkCapabilities == false)) return false; 1438 NetworkCapabilities that = (NetworkCapabilities) obj; 1439 return (equalsNetCapabilities(that) 1440 && equalsTransportTypes(that) 1441 && equalsLinkBandwidths(that) 1442 && equalsSignalStrength(that) 1443 && equalsSpecifier(that) 1444 && equalsTransportInfo(that) 1445 && equalsUids(that) 1446 && equalsSSID(that)); 1447 } 1448 1449 @Override hashCode()1450 public int hashCode() { 1451 return (int) (mNetworkCapabilities & 0xFFFFFFFF) 1452 + ((int) (mNetworkCapabilities >> 32) * 3) 1453 + ((int) (mUnwantedNetworkCapabilities & 0xFFFFFFFF) * 5) 1454 + ((int) (mUnwantedNetworkCapabilities >> 32) * 7) 1455 + ((int) (mTransportTypes & 0xFFFFFFFF) * 11) 1456 + ((int) (mTransportTypes >> 32) * 13) 1457 + (mLinkUpBandwidthKbps * 17) 1458 + (mLinkDownBandwidthKbps * 19) 1459 + Objects.hashCode(mNetworkSpecifier) * 23 1460 + (mSignalStrength * 29) 1461 + Objects.hashCode(mUids) * 31 1462 + Objects.hashCode(mSSID) * 37 1463 + Objects.hashCode(mTransportInfo) * 41; 1464 } 1465 1466 @Override describeContents()1467 public int describeContents() { 1468 return 0; 1469 } 1470 @Override writeToParcel(Parcel dest, int flags)1471 public void writeToParcel(Parcel dest, int flags) { 1472 dest.writeLong(mNetworkCapabilities); 1473 dest.writeLong(mUnwantedNetworkCapabilities); 1474 dest.writeLong(mTransportTypes); 1475 dest.writeInt(mLinkUpBandwidthKbps); 1476 dest.writeInt(mLinkDownBandwidthKbps); 1477 dest.writeParcelable((Parcelable) mNetworkSpecifier, flags); 1478 dest.writeParcelable((Parcelable) mTransportInfo, flags); 1479 dest.writeInt(mSignalStrength); 1480 dest.writeArraySet(mUids); 1481 dest.writeString(mSSID); 1482 } 1483 1484 public static final @android.annotation.NonNull Creator<NetworkCapabilities> CREATOR = 1485 new Creator<NetworkCapabilities>() { 1486 @Override 1487 public NetworkCapabilities createFromParcel(Parcel in) { 1488 NetworkCapabilities netCap = new NetworkCapabilities(); 1489 1490 netCap.mNetworkCapabilities = in.readLong(); 1491 netCap.mUnwantedNetworkCapabilities = in.readLong(); 1492 netCap.mTransportTypes = in.readLong(); 1493 netCap.mLinkUpBandwidthKbps = in.readInt(); 1494 netCap.mLinkDownBandwidthKbps = in.readInt(); 1495 netCap.mNetworkSpecifier = in.readParcelable(null); 1496 netCap.mTransportInfo = in.readParcelable(null); 1497 netCap.mSignalStrength = in.readInt(); 1498 netCap.mUids = (ArraySet<UidRange>) in.readArraySet( 1499 null /* ClassLoader, null for default */); 1500 netCap.mSSID = in.readString(); 1501 return netCap; 1502 } 1503 @Override 1504 public NetworkCapabilities[] newArray(int size) { 1505 return new NetworkCapabilities[size]; 1506 } 1507 }; 1508 1509 @Override toString()1510 public @NonNull String toString() { 1511 final StringBuilder sb = new StringBuilder("["); 1512 if (0 != mTransportTypes) { 1513 sb.append(" Transports: "); 1514 appendStringRepresentationOfBitMaskToStringBuilder(sb, mTransportTypes, 1515 NetworkCapabilities::transportNameOf, "|"); 1516 } 1517 if (0 != mNetworkCapabilities) { 1518 sb.append(" Capabilities: "); 1519 appendStringRepresentationOfBitMaskToStringBuilder(sb, mNetworkCapabilities, 1520 NetworkCapabilities::capabilityNameOf, "&"); 1521 } 1522 if (0 != mUnwantedNetworkCapabilities) { 1523 sb.append(" Unwanted: "); 1524 appendStringRepresentationOfBitMaskToStringBuilder(sb, mUnwantedNetworkCapabilities, 1525 NetworkCapabilities::capabilityNameOf, "&"); 1526 } 1527 if (mLinkUpBandwidthKbps > 0) { 1528 sb.append(" LinkUpBandwidth>=").append(mLinkUpBandwidthKbps).append("Kbps"); 1529 } 1530 if (mLinkDownBandwidthKbps > 0) { 1531 sb.append(" LinkDnBandwidth>=").append(mLinkDownBandwidthKbps).append("Kbps"); 1532 } 1533 if (mNetworkSpecifier != null) { 1534 sb.append(" Specifier: <").append(mNetworkSpecifier).append(">"); 1535 } 1536 if (mTransportInfo != null) { 1537 sb.append(" TransportInfo: <").append(mTransportInfo).append(">"); 1538 } 1539 if (hasSignalStrength()) { 1540 sb.append(" SignalStrength: ").append(mSignalStrength); 1541 } 1542 1543 if (null != mUids) { 1544 if ((1 == mUids.size()) && (mUids.valueAt(0).count() == 1)) { 1545 sb.append(" Uid: ").append(mUids.valueAt(0).start); 1546 } else { 1547 sb.append(" Uids: <").append(mUids).append(">"); 1548 } 1549 } 1550 if (mEstablishingVpnAppUid != INVALID_UID) { 1551 sb.append(" EstablishingAppUid: ").append(mEstablishingVpnAppUid); 1552 } 1553 1554 if (null != mSSID) { 1555 sb.append(" SSID: ").append(mSSID); 1556 } 1557 1558 sb.append("]"); 1559 return sb.toString(); 1560 } 1561 1562 1563 private interface NameOf { nameOf(int value)1564 String nameOf(int value); 1565 } 1566 /** 1567 * @hide 1568 */ appendStringRepresentationOfBitMaskToStringBuilder(@onNull StringBuilder sb, long bitMask, @NonNull NameOf nameFetcher, @NonNull String separator)1569 public static void appendStringRepresentationOfBitMaskToStringBuilder(@NonNull StringBuilder sb, 1570 long bitMask, @NonNull NameOf nameFetcher, @NonNull String separator) { 1571 int bitPos = 0; 1572 boolean firstElementAdded = false; 1573 while (bitMask != 0) { 1574 if ((bitMask & 1) != 0) { 1575 if (firstElementAdded) { 1576 sb.append(separator); 1577 } else { 1578 firstElementAdded = true; 1579 } 1580 sb.append(nameFetcher.nameOf(bitPos)); 1581 } 1582 bitMask >>= 1; 1583 ++bitPos; 1584 } 1585 } 1586 1587 /** @hide */ writeToProto(@onNull ProtoOutputStream proto, long fieldId)1588 public void writeToProto(@NonNull ProtoOutputStream proto, long fieldId) { 1589 final long token = proto.start(fieldId); 1590 1591 for (int transport : getTransportTypes()) { 1592 proto.write(NetworkCapabilitiesProto.TRANSPORTS, transport); 1593 } 1594 1595 for (int capability : getCapabilities()) { 1596 proto.write(NetworkCapabilitiesProto.CAPABILITIES, capability); 1597 } 1598 1599 proto.write(NetworkCapabilitiesProto.LINK_UP_BANDWIDTH_KBPS, mLinkUpBandwidthKbps); 1600 proto.write(NetworkCapabilitiesProto.LINK_DOWN_BANDWIDTH_KBPS, mLinkDownBandwidthKbps); 1601 1602 if (mNetworkSpecifier != null) { 1603 proto.write(NetworkCapabilitiesProto.NETWORK_SPECIFIER, mNetworkSpecifier.toString()); 1604 } 1605 if (mTransportInfo != null) { 1606 // TODO b/120653863: write transport-specific info to proto? 1607 } 1608 1609 proto.write(NetworkCapabilitiesProto.CAN_REPORT_SIGNAL_STRENGTH, hasSignalStrength()); 1610 proto.write(NetworkCapabilitiesProto.SIGNAL_STRENGTH, mSignalStrength); 1611 1612 proto.end(token); 1613 } 1614 1615 /** 1616 * @hide 1617 */ capabilityNamesOf(@ullable @etCapability int[] capabilities)1618 public static @NonNull String capabilityNamesOf(@Nullable @NetCapability int[] capabilities) { 1619 StringJoiner joiner = new StringJoiner("|"); 1620 if (capabilities != null) { 1621 for (int c : capabilities) { 1622 joiner.add(capabilityNameOf(c)); 1623 } 1624 } 1625 return joiner.toString(); 1626 } 1627 1628 /** 1629 * @hide 1630 */ capabilityNameOf(@etCapability int capability)1631 public static @NonNull String capabilityNameOf(@NetCapability int capability) { 1632 switch (capability) { 1633 case NET_CAPABILITY_MMS: return "MMS"; 1634 case NET_CAPABILITY_SUPL: return "SUPL"; 1635 case NET_CAPABILITY_DUN: return "DUN"; 1636 case NET_CAPABILITY_FOTA: return "FOTA"; 1637 case NET_CAPABILITY_IMS: return "IMS"; 1638 case NET_CAPABILITY_CBS: return "CBS"; 1639 case NET_CAPABILITY_WIFI_P2P: return "WIFI_P2P"; 1640 case NET_CAPABILITY_IA: return "IA"; 1641 case NET_CAPABILITY_RCS: return "RCS"; 1642 case NET_CAPABILITY_XCAP: return "XCAP"; 1643 case NET_CAPABILITY_EIMS: return "EIMS"; 1644 case NET_CAPABILITY_NOT_METERED: return "NOT_METERED"; 1645 case NET_CAPABILITY_INTERNET: return "INTERNET"; 1646 case NET_CAPABILITY_NOT_RESTRICTED: return "NOT_RESTRICTED"; 1647 case NET_CAPABILITY_TRUSTED: return "TRUSTED"; 1648 case NET_CAPABILITY_NOT_VPN: return "NOT_VPN"; 1649 case NET_CAPABILITY_VALIDATED: return "VALIDATED"; 1650 case NET_CAPABILITY_CAPTIVE_PORTAL: return "CAPTIVE_PORTAL"; 1651 case NET_CAPABILITY_NOT_ROAMING: return "NOT_ROAMING"; 1652 case NET_CAPABILITY_FOREGROUND: return "FOREGROUND"; 1653 case NET_CAPABILITY_NOT_CONGESTED: return "NOT_CONGESTED"; 1654 case NET_CAPABILITY_NOT_SUSPENDED: return "NOT_SUSPENDED"; 1655 case NET_CAPABILITY_OEM_PAID: return "OEM_PAID"; 1656 case NET_CAPABILITY_MCX: return "MCX"; 1657 case NET_CAPABILITY_PARTIAL_CONNECTIVITY: return "PARTIAL_CONNECTIVITY"; 1658 default: return Integer.toString(capability); 1659 } 1660 } 1661 1662 /** 1663 * @hide 1664 */ 1665 @UnsupportedAppUsage transportNamesOf(@ullable @ransport int[] types)1666 public static @NonNull String transportNamesOf(@Nullable @Transport int[] types) { 1667 StringJoiner joiner = new StringJoiner("|"); 1668 if (types != null) { 1669 for (int t : types) { 1670 joiner.add(transportNameOf(t)); 1671 } 1672 } 1673 return joiner.toString(); 1674 } 1675 1676 /** 1677 * @hide 1678 */ transportNameOf(@ransport int transport)1679 public static @NonNull String transportNameOf(@Transport int transport) { 1680 if (!isValidTransport(transport)) { 1681 return "UNKNOWN"; 1682 } 1683 return TRANSPORT_NAMES[transport]; 1684 } 1685 checkValidTransportType(@ransport int transport)1686 private static void checkValidTransportType(@Transport int transport) { 1687 Preconditions.checkArgument( 1688 isValidTransport(transport), "Invalid TransportType " + transport); 1689 } 1690 isValidCapability(@etworkCapabilities.NetCapability int capability)1691 private static boolean isValidCapability(@NetworkCapabilities.NetCapability int capability) { 1692 return capability >= MIN_NET_CAPABILITY && capability <= MAX_NET_CAPABILITY; 1693 } 1694 checkValidCapability(@etworkCapabilities.NetCapability int capability)1695 private static void checkValidCapability(@NetworkCapabilities.NetCapability int capability) { 1696 Preconditions.checkArgument(isValidCapability(capability), 1697 "NetworkCapability " + capability + "out of range"); 1698 } 1699 1700 /** 1701 * Check if this {@code NetworkCapability} instance is metered. 1702 * 1703 * @return {@code true} if {@code NET_CAPABILITY_NOT_METERED} is not set on this instance. 1704 * @hide 1705 */ isMetered()1706 public boolean isMetered() { 1707 return !hasCapability(NET_CAPABILITY_NOT_METERED); 1708 } 1709 } 1710