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