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.os.Parcel; 20 import android.os.Parcelable; 21 22 import com.android.internal.annotations.VisibleForTesting; 23 import com.android.internal.util.BitUtils; 24 25 import java.util.Objects; 26 27 /** 28 * This class represents the capabilities of a network. This is used both to specify 29 * needs to {@link ConnectivityManager} and when inspecting a network. 30 * 31 * Note that this replaces the old {@link ConnectivityManager#TYPE_MOBILE} method 32 * of network selection. Rather than indicate a need for Wi-Fi because an application 33 * needs high bandwidth and risk obsolescence when a new, fast network appears (like LTE), 34 * the application should specify it needs high bandwidth. Similarly if an application 35 * needs an unmetered network for a bulk transfer it can specify that rather than assuming 36 * all cellular based connections are metered and all Wi-Fi based connections are not. 37 */ 38 public final class NetworkCapabilities implements Parcelable { 39 private static final String TAG = "NetworkCapabilities"; 40 41 /** 42 * @hide 43 */ NetworkCapabilities()44 public NetworkCapabilities() { 45 clearAll(); 46 mNetworkCapabilities = DEFAULT_CAPABILITIES; 47 } 48 NetworkCapabilities(NetworkCapabilities nc)49 public NetworkCapabilities(NetworkCapabilities nc) { 50 if (nc != null) { 51 mNetworkCapabilities = nc.mNetworkCapabilities; 52 mTransportTypes = nc.mTransportTypes; 53 mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps; 54 mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps; 55 mNetworkSpecifier = nc.mNetworkSpecifier; 56 mSignalStrength = nc.mSignalStrength; 57 } 58 } 59 60 /** 61 * Completely clears the contents of this object, removing even the capabilities that are set 62 * by default when the object is constructed. 63 * @hide 64 */ clearAll()65 public void clearAll() { 66 mNetworkCapabilities = mTransportTypes = 0; 67 mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = 0; 68 mNetworkSpecifier = null; 69 mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED; 70 } 71 72 /** 73 * Represents the network's capabilities. If any are specified they will be satisfied 74 * by any Network that matches all of them. 75 */ 76 private long mNetworkCapabilities; 77 78 /** 79 * Indicates this is a network that has the ability to reach the 80 * carrier's MMSC for sending and receiving MMS messages. 81 */ 82 public static final int NET_CAPABILITY_MMS = 0; 83 84 /** 85 * Indicates this is a network that has the ability to reach the carrier's 86 * SUPL server, used to retrieve GPS information. 87 */ 88 public static final int NET_CAPABILITY_SUPL = 1; 89 90 /** 91 * Indicates this is a network that has the ability to reach the carrier's 92 * DUN or tethering gateway. 93 */ 94 public static final int NET_CAPABILITY_DUN = 2; 95 96 /** 97 * Indicates this is a network that has the ability to reach the carrier's 98 * FOTA portal, used for over the air updates. 99 */ 100 public static final int NET_CAPABILITY_FOTA = 3; 101 102 /** 103 * Indicates this is a network that has the ability to reach the carrier's 104 * IMS servers, used for network registration and signaling. 105 */ 106 public static final int NET_CAPABILITY_IMS = 4; 107 108 /** 109 * Indicates this is a network that has the ability to reach the carrier's 110 * CBS servers, used for carrier specific services. 111 */ 112 public static final int NET_CAPABILITY_CBS = 5; 113 114 /** 115 * Indicates this is a network that has the ability to reach a Wi-Fi direct 116 * peer. 117 */ 118 public static final int NET_CAPABILITY_WIFI_P2P = 6; 119 120 /** 121 * Indicates this is a network that has the ability to reach a carrier's 122 * Initial Attach servers. 123 */ 124 public static final int NET_CAPABILITY_IA = 7; 125 126 /** 127 * Indicates this is a network that has the ability to reach a carrier's 128 * RCS servers, used for Rich Communication Services. 129 */ 130 public static final int NET_CAPABILITY_RCS = 8; 131 132 /** 133 * Indicates this is a network that has the ability to reach a carrier's 134 * XCAP servers, used for configuration and control. 135 */ 136 public static final int NET_CAPABILITY_XCAP = 9; 137 138 /** 139 * Indicates this is a network that has the ability to reach a carrier's 140 * Emergency IMS servers or other services, used for network signaling 141 * during emergency calls. 142 */ 143 public static final int NET_CAPABILITY_EIMS = 10; 144 145 /** 146 * Indicates that this network is unmetered. 147 */ 148 public static final int NET_CAPABILITY_NOT_METERED = 11; 149 150 /** 151 * Indicates that this network should be able to reach the internet. 152 */ 153 public static final int NET_CAPABILITY_INTERNET = 12; 154 155 /** 156 * Indicates that this network is available for general use. If this is not set 157 * applications should not attempt to communicate on this network. Note that this 158 * is simply informative and not enforcement - enforcement is handled via other means. 159 * Set by default. 160 */ 161 public static final int NET_CAPABILITY_NOT_RESTRICTED = 13; 162 163 /** 164 * Indicates that the user has indicated implicit trust of this network. This 165 * generally means it's a sim-selected carrier, a plugged in ethernet, a paired 166 * BT device or a wifi the user asked to connect to. Untrusted networks 167 * are probably limited to unknown wifi AP. Set by default. 168 */ 169 public static final int NET_CAPABILITY_TRUSTED = 14; 170 171 /** 172 * Indicates that this network is not a VPN. This capability is set by default and should be 173 * explicitly cleared for VPN networks. 174 */ 175 public static final int NET_CAPABILITY_NOT_VPN = 15; 176 177 /** 178 * Indicates that connectivity on this network was successfully validated. For example, for a 179 * network with NET_CAPABILITY_INTERNET, it means that Internet connectivity was successfully 180 * detected. 181 */ 182 public static final int NET_CAPABILITY_VALIDATED = 16; 183 184 /** 185 * Indicates that this network was found to have a captive portal in place last time it was 186 * probed. 187 */ 188 public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17; 189 190 /** 191 * Indicates that this network is available for use by apps, and not a network that is being 192 * kept up in the background to facilitate fast network switching. 193 * @hide 194 */ 195 public static final int NET_CAPABILITY_FOREGROUND = 18; 196 197 private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS; 198 private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_FOREGROUND; 199 200 /** 201 * Network capabilities that are expected to be mutable, i.e., can change while a particular 202 * network is connected. 203 */ 204 private static final long MUTABLE_CAPABILITIES = 205 // TRUSTED can change when user explicitly connects to an untrusted network in Settings. 206 // http://b/18206275 207 (1 << NET_CAPABILITY_TRUSTED) | 208 (1 << NET_CAPABILITY_VALIDATED) | 209 (1 << NET_CAPABILITY_CAPTIVE_PORTAL) | 210 (1 << NET_CAPABILITY_FOREGROUND); 211 212 /** 213 * Network capabilities that are not allowed in NetworkRequests. This exists because the 214 * NetworkFactory / NetworkAgent model does not deal well with the situation where a 215 * capability's presence cannot be known in advance. If such a capability is requested, then we 216 * can get into a cycle where the NetworkFactory endlessly churns out NetworkAgents that then 217 * get immediately torn down because they do not have the requested capability. 218 */ 219 private static final long NON_REQUESTABLE_CAPABILITIES = 220 MUTABLE_CAPABILITIES & ~(1 << NET_CAPABILITY_TRUSTED); 221 222 /** 223 * Capabilities that are set by default when the object is constructed. 224 */ 225 private static final long DEFAULT_CAPABILITIES = 226 (1 << NET_CAPABILITY_NOT_RESTRICTED) | 227 (1 << NET_CAPABILITY_TRUSTED) | 228 (1 << NET_CAPABILITY_NOT_VPN); 229 230 /** 231 * Capabilities that suggest that a network is restricted. 232 * {@see #maybeMarkCapabilitiesRestricted}. 233 */ 234 @VisibleForTesting 235 /* package */ static final long RESTRICTED_CAPABILITIES = 236 (1 << NET_CAPABILITY_CBS) | 237 (1 << NET_CAPABILITY_DUN) | 238 (1 << NET_CAPABILITY_EIMS) | 239 (1 << NET_CAPABILITY_FOTA) | 240 (1 << NET_CAPABILITY_IA) | 241 (1 << NET_CAPABILITY_IMS) | 242 (1 << NET_CAPABILITY_RCS) | 243 (1 << NET_CAPABILITY_XCAP); 244 245 /** 246 * Capabilities that suggest that a network is unrestricted. 247 * {@see #maybeMarkCapabilitiesRestricted}. 248 */ 249 @VisibleForTesting 250 /* package */ static final long UNRESTRICTED_CAPABILITIES = 251 (1 << NET_CAPABILITY_INTERNET) | 252 (1 << NET_CAPABILITY_MMS) | 253 (1 << NET_CAPABILITY_SUPL) | 254 (1 << NET_CAPABILITY_WIFI_P2P); 255 256 /** 257 * Adds the given capability to this {@code NetworkCapability} instance. 258 * Multiple capabilities may be applied sequentially. Note that when searching 259 * for a network to satisfy a request, all capabilities requested must be satisfied. 260 * 261 * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be added. 262 * @return This NetworkCapabilities instance, to facilitate chaining. 263 * @hide 264 */ addCapability(int capability)265 public NetworkCapabilities addCapability(int capability) { 266 if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) { 267 throw new IllegalArgumentException("NetworkCapability out of range"); 268 } 269 mNetworkCapabilities |= 1 << capability; 270 return this; 271 } 272 273 /** 274 * Removes (if found) the given capability from this {@code NetworkCapability} instance. 275 * 276 * @param capability the {@code NetworkCapabilities.NET_CAPABILTIY_*} to be removed. 277 * @return This NetworkCapabilities instance, to facilitate chaining. 278 * @hide 279 */ removeCapability(int capability)280 public NetworkCapabilities removeCapability(int capability) { 281 if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) { 282 throw new IllegalArgumentException("NetworkCapability out of range"); 283 } 284 mNetworkCapabilities &= ~(1 << capability); 285 return this; 286 } 287 288 /** 289 * Gets all the capabilities set on this {@code NetworkCapability} instance. 290 * 291 * @return an array of {@code NetworkCapabilities.NET_CAPABILITY_*} values 292 * for this instance. 293 * @hide 294 */ getCapabilities()295 public int[] getCapabilities() { 296 return BitUtils.unpackBits(mNetworkCapabilities); 297 } 298 299 /** 300 * Tests for the presence of a capabilitity on this instance. 301 * 302 * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be tested for. 303 * @return {@code true} if set on this instance. 304 */ hasCapability(int capability)305 public boolean hasCapability(int capability) { 306 if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) { 307 return false; 308 } 309 return ((mNetworkCapabilities & (1 << capability)) != 0); 310 } 311 combineNetCapabilities(NetworkCapabilities nc)312 private void combineNetCapabilities(NetworkCapabilities nc) { 313 this.mNetworkCapabilities |= nc.mNetworkCapabilities; 314 } 315 316 /** 317 * Convenience function that returns a human-readable description of the first mutable 318 * capability we find. Used to present an error message to apps that request mutable 319 * capabilities. 320 * 321 * @hide 322 */ describeFirstNonRequestableCapability()323 public String describeFirstNonRequestableCapability() { 324 if (hasCapability(NET_CAPABILITY_VALIDATED)) return "NET_CAPABILITY_VALIDATED"; 325 if (hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return "NET_CAPABILITY_CAPTIVE_PORTAL"; 326 if (hasCapability(NET_CAPABILITY_FOREGROUND)) return "NET_CAPABILITY_FOREGROUND"; 327 // This cannot happen unless the preceding checks are incomplete. 328 if ((mNetworkCapabilities & NON_REQUESTABLE_CAPABILITIES) != 0) { 329 return "unknown non-requestable capabilities " + Long.toHexString(mNetworkCapabilities); 330 } 331 if (mLinkUpBandwidthKbps != 0 || mLinkDownBandwidthKbps != 0) return "link bandwidth"; 332 if (hasSignalStrength()) return "signalStrength"; 333 return null; 334 } 335 satisfiedByNetCapabilities(NetworkCapabilities nc, boolean onlyImmutable)336 private boolean satisfiedByNetCapabilities(NetworkCapabilities nc, boolean onlyImmutable) { 337 long networkCapabilities = this.mNetworkCapabilities; 338 if (onlyImmutable) { 339 networkCapabilities = networkCapabilities & ~MUTABLE_CAPABILITIES; 340 } 341 return ((nc.mNetworkCapabilities & networkCapabilities) == networkCapabilities); 342 } 343 344 /** @hide */ equalsNetCapabilities(NetworkCapabilities nc)345 public boolean equalsNetCapabilities(NetworkCapabilities nc) { 346 return (nc.mNetworkCapabilities == this.mNetworkCapabilities); 347 } 348 equalsNetCapabilitiesImmutable(NetworkCapabilities that)349 private boolean equalsNetCapabilitiesImmutable(NetworkCapabilities that) { 350 return ((this.mNetworkCapabilities & ~MUTABLE_CAPABILITIES) == 351 (that.mNetworkCapabilities & ~MUTABLE_CAPABILITIES)); 352 } 353 equalsNetCapabilitiesRequestable(NetworkCapabilities that)354 private boolean equalsNetCapabilitiesRequestable(NetworkCapabilities that) { 355 return ((this.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) == 356 (that.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES)); 357 } 358 359 /** 360 * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if all the capabilities it provides are 361 * typically provided by restricted networks. 362 * 363 * TODO: consider: 364 * - Renaming it to guessRestrictedCapability and make it set the 365 * restricted capability bit in addition to clearing it. 366 * @hide 367 */ maybeMarkCapabilitiesRestricted()368 public void maybeMarkCapabilitiesRestricted() { 369 // Verify there aren't any unrestricted capabilities. If there are we say 370 // the whole thing is unrestricted. 371 final boolean hasUnrestrictedCapabilities = 372 ((mNetworkCapabilities & UNRESTRICTED_CAPABILITIES) != 0); 373 374 // Must have at least some restricted capabilities. 375 final boolean hasRestrictedCapabilities = 376 ((mNetworkCapabilities & RESTRICTED_CAPABILITIES) != 0); 377 378 if (hasRestrictedCapabilities && !hasUnrestrictedCapabilities) { 379 removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 380 } 381 } 382 383 /** 384 * Representing the transport type. Apps should generally not care about transport. A 385 * request for a fast internet connection could be satisfied by a number of different 386 * transports. If any are specified here it will be satisfied a Network that matches 387 * any of them. If a caller doesn't care about the transport it should not specify any. 388 */ 389 private long mTransportTypes; 390 391 /** 392 * Indicates this network uses a Cellular transport. 393 */ 394 public static final int TRANSPORT_CELLULAR = 0; 395 396 /** 397 * Indicates this network uses a Wi-Fi transport. 398 */ 399 public static final int TRANSPORT_WIFI = 1; 400 401 /** 402 * Indicates this network uses a Bluetooth transport. 403 */ 404 public static final int TRANSPORT_BLUETOOTH = 2; 405 406 /** 407 * Indicates this network uses an Ethernet transport. 408 */ 409 public static final int TRANSPORT_ETHERNET = 3; 410 411 /** 412 * Indicates this network uses a VPN transport. 413 */ 414 public static final int TRANSPORT_VPN = 4; 415 416 /** 417 * Indicates this network uses a Wi-Fi Aware transport. 418 */ 419 public static final int TRANSPORT_WIFI_AWARE = 5; 420 421 /** @hide */ 422 public static final int MIN_TRANSPORT = TRANSPORT_CELLULAR; 423 /** @hide */ 424 public static final int MAX_TRANSPORT = TRANSPORT_WIFI_AWARE; 425 426 private static final String[] TRANSPORT_NAMES = { 427 "CELLULAR", 428 "WIFI", 429 "BLUETOOTH", 430 "ETHERNET", 431 "VPN", 432 "WIFI_AWARE" 433 }; 434 435 /** 436 * Adds the given transport type to this {@code NetworkCapability} instance. 437 * Multiple transports may be applied sequentially. Note that when searching 438 * for a network to satisfy a request, any listed in the request will satisfy the request. 439 * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a 440 * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network 441 * to be selected. This is logically different than 442 * {@code NetworkCapabilities.NET_CAPABILITY_*} listed above. 443 * 444 * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be added. 445 * @return This NetworkCapabilities instance, to facilitate chaining. 446 * @hide 447 */ addTransportType(int transportType)448 public NetworkCapabilities addTransportType(int transportType) { 449 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) { 450 throw new IllegalArgumentException("TransportType out of range"); 451 } 452 mTransportTypes |= 1 << transportType; 453 setNetworkSpecifier(mNetworkSpecifier); // used for exception checking 454 return this; 455 } 456 457 /** 458 * Removes (if found) the given transport from this {@code NetworkCapability} instance. 459 * 460 * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be removed. 461 * @return This NetworkCapabilities instance, to facilitate chaining. 462 * @hide 463 */ removeTransportType(int transportType)464 public NetworkCapabilities removeTransportType(int transportType) { 465 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) { 466 throw new IllegalArgumentException("TransportType out of range"); 467 } 468 mTransportTypes &= ~(1 << transportType); 469 setNetworkSpecifier(mNetworkSpecifier); // used for exception checking 470 return this; 471 } 472 473 /** 474 * Gets all the transports set on this {@code NetworkCapability} instance. 475 * 476 * @return an array of {@code NetworkCapabilities.TRANSPORT_*} values 477 * for this instance. 478 * @hide 479 */ getTransportTypes()480 public int[] getTransportTypes() { 481 return BitUtils.unpackBits(mTransportTypes); 482 } 483 484 /** 485 * Tests for the presence of a transport on this instance. 486 * 487 * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be tested for. 488 * @return {@code true} if set on this instance. 489 */ hasTransport(int transportType)490 public boolean hasTransport(int transportType) { 491 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) { 492 return false; 493 } 494 return ((mTransportTypes & (1 << transportType)) != 0); 495 } 496 combineTransportTypes(NetworkCapabilities nc)497 private void combineTransportTypes(NetworkCapabilities nc) { 498 this.mTransportTypes |= nc.mTransportTypes; 499 } satisfiedByTransportTypes(NetworkCapabilities nc)500 private boolean satisfiedByTransportTypes(NetworkCapabilities nc) { 501 return ((this.mTransportTypes == 0) || 502 ((this.mTransportTypes & nc.mTransportTypes) != 0)); 503 } 504 /** @hide */ equalsTransportTypes(NetworkCapabilities nc)505 public boolean equalsTransportTypes(NetworkCapabilities nc) { 506 return (nc.mTransportTypes == this.mTransportTypes); 507 } 508 509 /** 510 * Passive link bandwidth. This is a rough guide of the expected peak bandwidth 511 * for the first hop on the given transport. It is not measured, but may take into account 512 * link parameters (Radio technology, allocated channels, etc). 513 */ 514 private int mLinkUpBandwidthKbps; 515 private int mLinkDownBandwidthKbps; 516 517 /** 518 * Sets the upstream bandwidth for this network in Kbps. This always only refers to 519 * the estimated first hop transport bandwidth. 520 * <p> 521 * Note that when used to request a network, this specifies the minimum acceptable. 522 * When received as the state of an existing network this specifies the typical 523 * first hop bandwidth expected. This is never measured, but rather is inferred 524 * from technology type and other link parameters. It could be used to differentiate 525 * between very slow 1xRTT cellular links and other faster networks or even between 526 * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between 527 * fast backhauls and slow backhauls. 528 * 529 * @param upKbps the estimated first hop upstream (device to network) bandwidth. 530 * @hide 531 */ setLinkUpstreamBandwidthKbps(int upKbps)532 public void setLinkUpstreamBandwidthKbps(int upKbps) { 533 mLinkUpBandwidthKbps = upKbps; 534 } 535 536 /** 537 * Retrieves the upstream bandwidth for this network in Kbps. This always only refers to 538 * the estimated first hop transport bandwidth. 539 * 540 * @return The estimated first hop upstream (device to network) bandwidth. 541 */ getLinkUpstreamBandwidthKbps()542 public int getLinkUpstreamBandwidthKbps() { 543 return mLinkUpBandwidthKbps; 544 } 545 546 /** 547 * Sets the downstream bandwidth for this network in Kbps. This always only refers to 548 * the estimated first hop transport bandwidth. 549 * <p> 550 * Note that when used to request a network, this specifies the minimum acceptable. 551 * When received as the state of an existing network this specifies the typical 552 * first hop bandwidth expected. This is never measured, but rather is inferred 553 * from technology type and other link parameters. It could be used to differentiate 554 * between very slow 1xRTT cellular links and other faster networks or even between 555 * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between 556 * fast backhauls and slow backhauls. 557 * 558 * @param downKbps the estimated first hop downstream (network to device) bandwidth. 559 * @hide 560 */ setLinkDownstreamBandwidthKbps(int downKbps)561 public void setLinkDownstreamBandwidthKbps(int downKbps) { 562 mLinkDownBandwidthKbps = downKbps; 563 } 564 565 /** 566 * Retrieves the downstream bandwidth for this network in Kbps. This always only refers to 567 * the estimated first hop transport bandwidth. 568 * 569 * @return The estimated first hop downstream (network to device) bandwidth. 570 */ getLinkDownstreamBandwidthKbps()571 public int getLinkDownstreamBandwidthKbps() { 572 return mLinkDownBandwidthKbps; 573 } 574 combineLinkBandwidths(NetworkCapabilities nc)575 private void combineLinkBandwidths(NetworkCapabilities nc) { 576 this.mLinkUpBandwidthKbps = 577 Math.max(this.mLinkUpBandwidthKbps, nc.mLinkUpBandwidthKbps); 578 this.mLinkDownBandwidthKbps = 579 Math.max(this.mLinkDownBandwidthKbps, nc.mLinkDownBandwidthKbps); 580 } satisfiedByLinkBandwidths(NetworkCapabilities nc)581 private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) { 582 return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps || 583 this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps); 584 } equalsLinkBandwidths(NetworkCapabilities nc)585 private boolean equalsLinkBandwidths(NetworkCapabilities nc) { 586 return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps && 587 this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps); 588 } 589 590 private NetworkSpecifier mNetworkSpecifier = null; 591 592 /** 593 * Sets the optional bearer specific network specifier. 594 * This has no meaning if a single transport is also not specified, so calling 595 * this without a single transport set will generate an exception, as will 596 * subsequently adding or removing transports after this is set. 597 * </p> 598 * 599 * @param networkSpecifier A concrete, parcelable framework class that extends 600 * NetworkSpecifier. 601 * @return This NetworkCapabilities instance, to facilitate chaining. 602 * @hide 603 */ setNetworkSpecifier(NetworkSpecifier networkSpecifier)604 public NetworkCapabilities setNetworkSpecifier(NetworkSpecifier networkSpecifier) { 605 if (networkSpecifier != null && Long.bitCount(mTransportTypes) != 1) { 606 throw new IllegalStateException("Must have a single transport specified to use " + 607 "setNetworkSpecifier"); 608 } 609 610 mNetworkSpecifier = networkSpecifier; 611 612 return this; 613 } 614 615 /** 616 * Gets the optional bearer specific network specifier. 617 * 618 * @return The optional {@link NetworkSpecifier} specifying the bearer specific network 619 * specifier. See {@link #setNetworkSpecifier}. 620 * @hide 621 */ getNetworkSpecifier()622 public NetworkSpecifier getNetworkSpecifier() { 623 return mNetworkSpecifier; 624 } 625 combineSpecifiers(NetworkCapabilities nc)626 private void combineSpecifiers(NetworkCapabilities nc) { 627 if (mNetworkSpecifier != null && !mNetworkSpecifier.equals(nc.mNetworkSpecifier)) { 628 throw new IllegalStateException("Can't combine two networkSpecifiers"); 629 } 630 setNetworkSpecifier(nc.mNetworkSpecifier); 631 } 632 satisfiedBySpecifier(NetworkCapabilities nc)633 private boolean satisfiedBySpecifier(NetworkCapabilities nc) { 634 return mNetworkSpecifier == null || mNetworkSpecifier.satisfiedBy(nc.mNetworkSpecifier) 635 || nc.mNetworkSpecifier instanceof MatchAllNetworkSpecifier; 636 } 637 equalsSpecifier(NetworkCapabilities nc)638 private boolean equalsSpecifier(NetworkCapabilities nc) { 639 return Objects.equals(mNetworkSpecifier, nc.mNetworkSpecifier); 640 } 641 642 /** 643 * Magic value that indicates no signal strength provided. A request specifying this value is 644 * always satisfied. 645 * 646 * @hide 647 */ 648 public static final int SIGNAL_STRENGTH_UNSPECIFIED = Integer.MIN_VALUE; 649 650 /** 651 * Signal strength. This is a signed integer, and higher values indicate better signal. 652 * The exact units are bearer-dependent. For example, Wi-Fi uses RSSI. 653 */ 654 private int mSignalStrength; 655 656 /** 657 * Sets the signal strength. This is a signed integer, with higher values indicating a stronger 658 * signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same RSSI units 659 * reported by WifiManager. 660 * <p> 661 * Note that when used to register a network callback, this specifies the minimum acceptable 662 * signal strength. When received as the state of an existing network it specifies the current 663 * value. A value of code SIGNAL_STRENGTH_UNSPECIFIED} means no value when received and has no 664 * effect when requesting a callback. 665 * 666 * @param signalStrength the bearer-specific signal strength. 667 * @hide 668 */ setSignalStrength(int signalStrength)669 public void setSignalStrength(int signalStrength) { 670 mSignalStrength = signalStrength; 671 } 672 673 /** 674 * Returns {@code true} if this object specifies a signal strength. 675 * 676 * @hide 677 */ hasSignalStrength()678 public boolean hasSignalStrength() { 679 return mSignalStrength > SIGNAL_STRENGTH_UNSPECIFIED; 680 } 681 682 /** 683 * Retrieves the signal strength. 684 * 685 * @return The bearer-specific signal strength. 686 * @hide 687 */ getSignalStrength()688 public int getSignalStrength() { 689 return mSignalStrength; 690 } 691 combineSignalStrength(NetworkCapabilities nc)692 private void combineSignalStrength(NetworkCapabilities nc) { 693 this.mSignalStrength = Math.max(this.mSignalStrength, nc.mSignalStrength); 694 } 695 satisfiedBySignalStrength(NetworkCapabilities nc)696 private boolean satisfiedBySignalStrength(NetworkCapabilities nc) { 697 return this.mSignalStrength <= nc.mSignalStrength; 698 } 699 equalsSignalStrength(NetworkCapabilities nc)700 private boolean equalsSignalStrength(NetworkCapabilities nc) { 701 return this.mSignalStrength == nc.mSignalStrength; 702 } 703 704 /** 705 * Combine a set of Capabilities to this one. Useful for coming up with the complete set 706 * @hide 707 */ combineCapabilities(NetworkCapabilities nc)708 public void combineCapabilities(NetworkCapabilities nc) { 709 combineNetCapabilities(nc); 710 combineTransportTypes(nc); 711 combineLinkBandwidths(nc); 712 combineSpecifiers(nc); 713 combineSignalStrength(nc); 714 } 715 716 /** 717 * Check if our requirements are satisfied by the given {@code NetworkCapabilities}. 718 * 719 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements. 720 * @param onlyImmutable if {@code true}, do not consider mutable requirements such as link 721 * bandwidth, signal strength, or validation / captive portal status. 722 * 723 * @hide 724 */ satisfiedByNetworkCapabilities(NetworkCapabilities nc, boolean onlyImmutable)725 private boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc, boolean onlyImmutable) { 726 return (nc != null && 727 satisfiedByNetCapabilities(nc, onlyImmutable) && 728 satisfiedByTransportTypes(nc) && 729 (onlyImmutable || satisfiedByLinkBandwidths(nc)) && 730 satisfiedBySpecifier(nc) && 731 (onlyImmutable || satisfiedBySignalStrength(nc))); 732 } 733 734 /** 735 * Check if our requirements are satisfied by the given {@code NetworkCapabilities}. 736 * 737 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements. 738 * 739 * @hide 740 */ satisfiedByNetworkCapabilities(NetworkCapabilities nc)741 public boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc) { 742 return satisfiedByNetworkCapabilities(nc, false); 743 } 744 745 /** 746 * Check if our immutable requirements are satisfied by the given {@code NetworkCapabilities}. 747 * 748 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements. 749 * 750 * @hide 751 */ satisfiedByImmutableNetworkCapabilities(NetworkCapabilities nc)752 public boolean satisfiedByImmutableNetworkCapabilities(NetworkCapabilities nc) { 753 return satisfiedByNetworkCapabilities(nc, true); 754 } 755 756 /** 757 * Checks that our immutable capabilities are the same as those of the given 758 * {@code NetworkCapabilities}. 759 * 760 * @hide 761 */ equalImmutableCapabilities(NetworkCapabilities nc)762 public boolean equalImmutableCapabilities(NetworkCapabilities nc) { 763 if (nc == null) return false; 764 return (equalsNetCapabilitiesImmutable(nc) && 765 equalsTransportTypes(nc) && 766 equalsSpecifier(nc)); 767 } 768 769 /** 770 * Checks that our requestable capabilities are the same as those of the given 771 * {@code NetworkCapabilities}. 772 * 773 * @hide 774 */ equalRequestableCapabilities(NetworkCapabilities nc)775 public boolean equalRequestableCapabilities(NetworkCapabilities nc) { 776 if (nc == null) return false; 777 return (equalsNetCapabilitiesRequestable(nc) && 778 equalsTransportTypes(nc) && 779 equalsSpecifier(nc)); 780 } 781 782 @Override equals(Object obj)783 public boolean equals(Object obj) { 784 if (obj == null || (obj instanceof NetworkCapabilities == false)) return false; 785 NetworkCapabilities that = (NetworkCapabilities)obj; 786 return (equalsNetCapabilities(that) && 787 equalsTransportTypes(that) && 788 equalsLinkBandwidths(that) && 789 equalsSignalStrength(that) && 790 equalsSpecifier(that)); 791 } 792 793 @Override hashCode()794 public int hashCode() { 795 return ((int)(mNetworkCapabilities & 0xFFFFFFFF) + 796 ((int)(mNetworkCapabilities >> 32) * 3) + 797 ((int)(mTransportTypes & 0xFFFFFFFF) * 5) + 798 ((int)(mTransportTypes >> 32) * 7) + 799 (mLinkUpBandwidthKbps * 11) + 800 (mLinkDownBandwidthKbps * 13) + 801 Objects.hashCode(mNetworkSpecifier) * 17 + 802 (mSignalStrength * 19)); 803 } 804 805 @Override describeContents()806 public int describeContents() { 807 return 0; 808 } 809 @Override writeToParcel(Parcel dest, int flags)810 public void writeToParcel(Parcel dest, int flags) { 811 dest.writeLong(mNetworkCapabilities); 812 dest.writeLong(mTransportTypes); 813 dest.writeInt(mLinkUpBandwidthKbps); 814 dest.writeInt(mLinkDownBandwidthKbps); 815 dest.writeParcelable((Parcelable) mNetworkSpecifier, flags); 816 dest.writeInt(mSignalStrength); 817 } 818 819 public static final Creator<NetworkCapabilities> CREATOR = 820 new Creator<NetworkCapabilities>() { 821 @Override 822 public NetworkCapabilities createFromParcel(Parcel in) { 823 NetworkCapabilities netCap = new NetworkCapabilities(); 824 825 netCap.mNetworkCapabilities = in.readLong(); 826 netCap.mTransportTypes = in.readLong(); 827 netCap.mLinkUpBandwidthKbps = in.readInt(); 828 netCap.mLinkDownBandwidthKbps = in.readInt(); 829 netCap.mNetworkSpecifier = in.readParcelable(null); 830 netCap.mSignalStrength = in.readInt(); 831 return netCap; 832 } 833 @Override 834 public NetworkCapabilities[] newArray(int size) { 835 return new NetworkCapabilities[size]; 836 } 837 }; 838 839 @Override toString()840 public String toString() { 841 int[] types = getTransportTypes(); 842 String transports = (types.length > 0) ? " Transports: " + transportNamesOf(types) : ""; 843 844 types = getCapabilities(); 845 String capabilities = (types.length > 0 ? " Capabilities: " : ""); 846 for (int i = 0; i < types.length; ) { 847 switch (types[i]) { 848 case NET_CAPABILITY_MMS: capabilities += "MMS"; break; 849 case NET_CAPABILITY_SUPL: capabilities += "SUPL"; break; 850 case NET_CAPABILITY_DUN: capabilities += "DUN"; break; 851 case NET_CAPABILITY_FOTA: capabilities += "FOTA"; break; 852 case NET_CAPABILITY_IMS: capabilities += "IMS"; break; 853 case NET_CAPABILITY_CBS: capabilities += "CBS"; break; 854 case NET_CAPABILITY_WIFI_P2P: capabilities += "WIFI_P2P"; break; 855 case NET_CAPABILITY_IA: capabilities += "IA"; break; 856 case NET_CAPABILITY_RCS: capabilities += "RCS"; break; 857 case NET_CAPABILITY_XCAP: capabilities += "XCAP"; break; 858 case NET_CAPABILITY_EIMS: capabilities += "EIMS"; break; 859 case NET_CAPABILITY_NOT_METERED: capabilities += "NOT_METERED"; break; 860 case NET_CAPABILITY_INTERNET: capabilities += "INTERNET"; break; 861 case NET_CAPABILITY_NOT_RESTRICTED: capabilities += "NOT_RESTRICTED"; break; 862 case NET_CAPABILITY_TRUSTED: capabilities += "TRUSTED"; break; 863 case NET_CAPABILITY_NOT_VPN: capabilities += "NOT_VPN"; break; 864 case NET_CAPABILITY_VALIDATED: capabilities += "VALIDATED"; break; 865 case NET_CAPABILITY_CAPTIVE_PORTAL: capabilities += "CAPTIVE_PORTAL"; break; 866 case NET_CAPABILITY_FOREGROUND: capabilities += "FOREGROUND"; break; 867 } 868 if (++i < types.length) capabilities += "&"; 869 } 870 871 String upBand = ((mLinkUpBandwidthKbps > 0) ? " LinkUpBandwidth>=" + 872 mLinkUpBandwidthKbps + "Kbps" : ""); 873 String dnBand = ((mLinkDownBandwidthKbps > 0) ? " LinkDnBandwidth>=" + 874 mLinkDownBandwidthKbps + "Kbps" : ""); 875 876 String specifier = (mNetworkSpecifier == null ? 877 "" : " Specifier: <" + mNetworkSpecifier + ">"); 878 879 String signalStrength = (hasSignalStrength() ? " SignalStrength: " + mSignalStrength : ""); 880 881 return "[" + transports + capabilities + upBand + dnBand + specifier + signalStrength + "]"; 882 } 883 884 /** 885 * @hide 886 */ transportNamesOf(int[] types)887 public static String transportNamesOf(int[] types) { 888 if (types == null || types.length == 0) { 889 return ""; 890 } 891 StringBuilder transports = new StringBuilder(); 892 for (int t : types) { 893 transports.append("|").append(transportNameOf(t)); 894 } 895 return transports.substring(1); 896 } 897 898 /** 899 * @hide 900 */ transportNameOf(int transport)901 public static String transportNameOf(int transport) { 902 if (transport < 0 || TRANSPORT_NAMES.length <= transport) { 903 return "UNKNOWN"; 904 } 905 return TRANSPORT_NAMES[transport]; 906 } 907 } 908