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 specifier for factories which want to match any network specifier 201 * (NS) in a request. Behavior: 202 * <li>Empty NS in request matches any network factory NS</li> 203 * <li>Empty NS in the network factory NS only matches a request with an 204 * empty NS</li> 205 * <li>"*" (this constant) NS in the network factory matches requests with 206 * any NS</li> 207 * 208 * @hide 209 */ 210 public static final String MATCH_ALL_REQUESTS_NETWORK_SPECIFIER = "*"; 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 (1 << NET_CAPABILITY_VALIDATED) | 221 (1 << NET_CAPABILITY_CAPTIVE_PORTAL); 222 223 /** 224 * Capabilities that are set by default when the object is constructed. 225 */ 226 private static final long DEFAULT_CAPABILITIES = 227 (1 << NET_CAPABILITY_NOT_RESTRICTED) | 228 (1 << NET_CAPABILITY_TRUSTED) | 229 (1 << NET_CAPABILITY_NOT_VPN); 230 231 /** 232 * Capabilities that suggest that a network is restricted. 233 * {@see #maybeMarkCapabilitiesRestricted}. 234 */ 235 private 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 * Adds the given capability to this {@code NetworkCapability} instance. 247 * Multiple capabilities may be applied sequentially. Note that when searching 248 * for a network to satisfy a request, all capabilities requested must be satisfied. 249 * 250 * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be added. 251 * @return This NetworkCapabilities instance, to facilitate chaining. 252 * @hide 253 */ addCapability(int capability)254 public NetworkCapabilities addCapability(int capability) { 255 if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) { 256 throw new IllegalArgumentException("NetworkCapability out of range"); 257 } 258 mNetworkCapabilities |= 1 << capability; 259 return this; 260 } 261 262 /** 263 * Removes (if found) the given capability from this {@code NetworkCapability} instance. 264 * 265 * @param capability the {@code NetworkCapabilities.NET_CAPABILTIY_*} to be removed. 266 * @return This NetworkCapabilities instance, to facilitate chaining. 267 * @hide 268 */ removeCapability(int capability)269 public NetworkCapabilities removeCapability(int capability) { 270 if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) { 271 throw new IllegalArgumentException("NetworkCapability out of range"); 272 } 273 mNetworkCapabilities &= ~(1 << capability); 274 return this; 275 } 276 277 /** 278 * Gets all the capabilities set on this {@code NetworkCapability} instance. 279 * 280 * @return an array of {@code NetworkCapabilities.NET_CAPABILITY_*} values 281 * for this instance. 282 * @hide 283 */ getCapabilities()284 public int[] getCapabilities() { 285 return enumerateBits(mNetworkCapabilities); 286 } 287 288 /** 289 * Tests for the presence of a capabilitity on this instance. 290 * 291 * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be tested for. 292 * @return {@code true} if set on this instance. 293 */ hasCapability(int capability)294 public boolean hasCapability(int capability) { 295 if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) { 296 return false; 297 } 298 return ((mNetworkCapabilities & (1 << capability)) != 0); 299 } 300 enumerateBits(long val)301 private int[] enumerateBits(long val) { 302 int size = Long.bitCount(val); 303 int[] result = new int[size]; 304 int index = 0; 305 int resource = 0; 306 while (val > 0) { 307 if ((val & 1) == 1) result[index++] = resource; 308 val = val >> 1; 309 resource++; 310 } 311 return result; 312 } 313 combineNetCapabilities(NetworkCapabilities nc)314 private void combineNetCapabilities(NetworkCapabilities nc) { 315 this.mNetworkCapabilities |= nc.mNetworkCapabilities; 316 } 317 318 /** 319 * Convenience function that returns a human-readable description of the first mutable 320 * capability we find. Used to present an error message to apps that request mutable 321 * capabilities. 322 * 323 * @hide 324 */ describeFirstNonRequestableCapability()325 public String describeFirstNonRequestableCapability() { 326 if (hasCapability(NET_CAPABILITY_VALIDATED)) return "NET_CAPABILITY_VALIDATED"; 327 if (hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return "NET_CAPABILITY_CAPTIVE_PORTAL"; 328 // This cannot happen unless the preceding checks are incomplete. 329 if ((mNetworkCapabilities & NON_REQUESTABLE_CAPABILITIES) != 0) { 330 return "unknown non-requestable capabilities " + Long.toHexString(mNetworkCapabilities); 331 } 332 if (mLinkUpBandwidthKbps != 0 || mLinkDownBandwidthKbps != 0) return "link bandwidth"; 333 if (hasSignalStrength()) return "signalStrength"; 334 return null; 335 } 336 satisfiedByNetCapabilities(NetworkCapabilities nc, boolean onlyImmutable)337 private boolean satisfiedByNetCapabilities(NetworkCapabilities nc, boolean onlyImmutable) { 338 long networkCapabilities = this.mNetworkCapabilities; 339 if (onlyImmutable) { 340 networkCapabilities = networkCapabilities & ~MUTABLE_CAPABILITIES; 341 } 342 return ((nc.mNetworkCapabilities & networkCapabilities) == networkCapabilities); 343 } 344 345 /** @hide */ equalsNetCapabilities(NetworkCapabilities nc)346 public boolean equalsNetCapabilities(NetworkCapabilities nc) { 347 return (nc.mNetworkCapabilities == this.mNetworkCapabilities); 348 } 349 equalsNetCapabilitiesImmutable(NetworkCapabilities that)350 private boolean equalsNetCapabilitiesImmutable(NetworkCapabilities that) { 351 return ((this.mNetworkCapabilities & ~MUTABLE_CAPABILITIES) == 352 (that.mNetworkCapabilities & ~MUTABLE_CAPABILITIES)); 353 } 354 355 /** 356 * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if all the capabilities it provides are 357 * typically provided by restricted networks. 358 * 359 * TODO: consider: 360 * - Renaming it to guessRestrictedCapability and make it set the 361 * restricted capability bit in addition to clearing it. 362 * @hide 363 */ maybeMarkCapabilitiesRestricted()364 public void maybeMarkCapabilitiesRestricted() { 365 // If all the capabilities are typically provided by restricted networks, conclude that this 366 // network is restricted. 367 if ((mNetworkCapabilities & ~(DEFAULT_CAPABILITIES | RESTRICTED_CAPABILITIES)) == 0 && 368 // Must have at least some restricted capabilities, otherwise a request for an 369 // internet-less network will get marked restricted. 370 (mNetworkCapabilities & RESTRICTED_CAPABILITIES) != 0) { 371 removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 372 } 373 } 374 375 /** 376 * Representing the transport type. Apps should generally not care about transport. A 377 * request for a fast internet connection could be satisfied by a number of different 378 * transports. If any are specified here it will be satisfied a Network that matches 379 * any of them. If a caller doesn't care about the transport it should not specify any. 380 */ 381 private long mTransportTypes; 382 383 /** 384 * Indicates this network uses a Cellular transport. 385 */ 386 public static final int TRANSPORT_CELLULAR = 0; 387 388 /** 389 * Indicates this network uses a Wi-Fi transport. 390 */ 391 public static final int TRANSPORT_WIFI = 1; 392 393 /** 394 * Indicates this network uses a Bluetooth transport. 395 */ 396 public static final int TRANSPORT_BLUETOOTH = 2; 397 398 /** 399 * Indicates this network uses an Ethernet transport. 400 */ 401 public static final int TRANSPORT_ETHERNET = 3; 402 403 /** 404 * Indicates this network uses a VPN transport. 405 */ 406 public static final int TRANSPORT_VPN = 4; 407 408 private static final int MIN_TRANSPORT = TRANSPORT_CELLULAR; 409 private static final int MAX_TRANSPORT = TRANSPORT_VPN; 410 411 /** 412 * Adds the given transport type to this {@code NetworkCapability} instance. 413 * Multiple transports may be applied sequentially. Note that when searching 414 * for a network to satisfy a request, any listed in the request will satisfy the request. 415 * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a 416 * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network 417 * to be selected. This is logically different than 418 * {@code NetworkCapabilities.NET_CAPABILITY_*} listed above. 419 * 420 * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be added. 421 * @return This NetworkCapabilities instance, to facilitate chaining. 422 * @hide 423 */ addTransportType(int transportType)424 public NetworkCapabilities addTransportType(int transportType) { 425 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) { 426 throw new IllegalArgumentException("TransportType out of range"); 427 } 428 mTransportTypes |= 1 << transportType; 429 setNetworkSpecifier(mNetworkSpecifier); // used for exception checking 430 return this; 431 } 432 433 /** 434 * Removes (if found) the given transport from this {@code NetworkCapability} instance. 435 * 436 * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be removed. 437 * @return This NetworkCapabilities instance, to facilitate chaining. 438 * @hide 439 */ removeTransportType(int transportType)440 public NetworkCapabilities removeTransportType(int transportType) { 441 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) { 442 throw new IllegalArgumentException("TransportType out of range"); 443 } 444 mTransportTypes &= ~(1 << transportType); 445 setNetworkSpecifier(mNetworkSpecifier); // used for exception checking 446 return this; 447 } 448 449 /** 450 * Gets all the transports set on this {@code NetworkCapability} instance. 451 * 452 * @return an array of {@code NetworkCapabilities.TRANSPORT_*} values 453 * for this instance. 454 * @hide 455 */ getTransportTypes()456 public int[] getTransportTypes() { 457 return enumerateBits(mTransportTypes); 458 } 459 460 /** 461 * Tests for the presence of a transport on this instance. 462 * 463 * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be tested for. 464 * @return {@code true} if set on this instance. 465 */ hasTransport(int transportType)466 public boolean hasTransport(int transportType) { 467 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) { 468 return false; 469 } 470 return ((mTransportTypes & (1 << transportType)) != 0); 471 } 472 combineTransportTypes(NetworkCapabilities nc)473 private void combineTransportTypes(NetworkCapabilities nc) { 474 this.mTransportTypes |= nc.mTransportTypes; 475 } satisfiedByTransportTypes(NetworkCapabilities nc)476 private boolean satisfiedByTransportTypes(NetworkCapabilities nc) { 477 return ((this.mTransportTypes == 0) || 478 ((this.mTransportTypes & nc.mTransportTypes) != 0)); 479 } 480 /** @hide */ equalsTransportTypes(NetworkCapabilities nc)481 public boolean equalsTransportTypes(NetworkCapabilities nc) { 482 return (nc.mTransportTypes == this.mTransportTypes); 483 } 484 485 /** 486 * Passive link bandwidth. This is a rough guide of the expected peak bandwidth 487 * for the first hop on the given transport. It is not measured, but may take into account 488 * link parameters (Radio technology, allocated channels, etc). 489 */ 490 private int mLinkUpBandwidthKbps; 491 private int mLinkDownBandwidthKbps; 492 493 /** 494 * Sets the upstream bandwidth for this network in Kbps. This always only refers to 495 * the estimated first hop transport bandwidth. 496 * <p> 497 * Note that when used to request a network, this specifies the minimum acceptable. 498 * When received as the state of an existing network this specifies the typical 499 * first hop bandwidth expected. This is never measured, but rather is inferred 500 * from technology type and other link parameters. It could be used to differentiate 501 * between very slow 1xRTT cellular links and other faster networks or even between 502 * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between 503 * fast backhauls and slow backhauls. 504 * 505 * @param upKbps the estimated first hop upstream (device to network) bandwidth. 506 * @hide 507 */ setLinkUpstreamBandwidthKbps(int upKbps)508 public void setLinkUpstreamBandwidthKbps(int upKbps) { 509 mLinkUpBandwidthKbps = upKbps; 510 } 511 512 /** 513 * Retrieves the upstream bandwidth for this network in Kbps. This always only refers to 514 * the estimated first hop transport bandwidth. 515 * 516 * @return The estimated first hop upstream (device to network) bandwidth. 517 */ getLinkUpstreamBandwidthKbps()518 public int getLinkUpstreamBandwidthKbps() { 519 return mLinkUpBandwidthKbps; 520 } 521 522 /** 523 * Sets the downstream bandwidth for this network in Kbps. This always only refers to 524 * the estimated first hop transport bandwidth. 525 * <p> 526 * Note that when used to request a network, this specifies the minimum acceptable. 527 * When received as the state of an existing network this specifies the typical 528 * first hop bandwidth expected. This is never measured, but rather is inferred 529 * from technology type and other link parameters. It could be used to differentiate 530 * between very slow 1xRTT cellular links and other faster networks or even between 531 * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between 532 * fast backhauls and slow backhauls. 533 * 534 * @param downKbps the estimated first hop downstream (network to device) bandwidth. 535 * @hide 536 */ setLinkDownstreamBandwidthKbps(int downKbps)537 public void setLinkDownstreamBandwidthKbps(int downKbps) { 538 mLinkDownBandwidthKbps = downKbps; 539 } 540 541 /** 542 * Retrieves the downstream bandwidth for this network in Kbps. This always only refers to 543 * the estimated first hop transport bandwidth. 544 * 545 * @return The estimated first hop downstream (network to device) bandwidth. 546 */ getLinkDownstreamBandwidthKbps()547 public int getLinkDownstreamBandwidthKbps() { 548 return mLinkDownBandwidthKbps; 549 } 550 combineLinkBandwidths(NetworkCapabilities nc)551 private void combineLinkBandwidths(NetworkCapabilities nc) { 552 this.mLinkUpBandwidthKbps = 553 Math.max(this.mLinkUpBandwidthKbps, nc.mLinkUpBandwidthKbps); 554 this.mLinkDownBandwidthKbps = 555 Math.max(this.mLinkDownBandwidthKbps, nc.mLinkDownBandwidthKbps); 556 } satisfiedByLinkBandwidths(NetworkCapabilities nc)557 private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) { 558 return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps || 559 this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps); 560 } equalsLinkBandwidths(NetworkCapabilities nc)561 private boolean equalsLinkBandwidths(NetworkCapabilities nc) { 562 return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps && 563 this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps); 564 } 565 566 private String mNetworkSpecifier; 567 /** 568 * Sets the optional bearer specific network specifier. 569 * This has no meaning if a single transport is also not specified, so calling 570 * this without a single transport set will generate an exception, as will 571 * subsequently adding or removing transports after this is set. 572 * </p> 573 * The interpretation of this {@code String} is bearer specific and bearers that use 574 * it should document their particulars. For example, Bluetooth may use some sort of 575 * device id while WiFi could used SSID and/or BSSID. Cellular may use carrier SPN (name) 576 * or Subscription ID. 577 * 578 * @param networkSpecifier An {@code String} of opaque format used to specify the bearer 579 * specific network specifier where the bearer has a choice of 580 * networks. 581 * @return This NetworkCapabilities instance, to facilitate chaining. 582 * @hide 583 */ setNetworkSpecifier(String networkSpecifier)584 public NetworkCapabilities setNetworkSpecifier(String networkSpecifier) { 585 if (TextUtils.isEmpty(networkSpecifier) == false && Long.bitCount(mTransportTypes) != 1) { 586 throw new IllegalStateException("Must have a single transport specified to use " + 587 "setNetworkSpecifier"); 588 } 589 mNetworkSpecifier = networkSpecifier; 590 return this; 591 } 592 593 /** 594 * Gets the optional bearer specific network specifier. 595 * 596 * @return The optional {@code String} specifying the bearer specific network specifier. 597 * See {@link #setNetworkSpecifier}. 598 * @hide 599 */ getNetworkSpecifier()600 public String getNetworkSpecifier() { 601 return mNetworkSpecifier; 602 } 603 combineSpecifiers(NetworkCapabilities nc)604 private void combineSpecifiers(NetworkCapabilities nc) { 605 String otherSpecifier = nc.getNetworkSpecifier(); 606 if (TextUtils.isEmpty(otherSpecifier)) return; 607 if (TextUtils.isEmpty(mNetworkSpecifier) == false) { 608 throw new IllegalStateException("Can't combine two networkSpecifiers"); 609 } 610 setNetworkSpecifier(otherSpecifier); 611 } satisfiedBySpecifier(NetworkCapabilities nc)612 private boolean satisfiedBySpecifier(NetworkCapabilities nc) { 613 return (TextUtils.isEmpty(mNetworkSpecifier) || 614 mNetworkSpecifier.equals(nc.mNetworkSpecifier) || 615 MATCH_ALL_REQUESTS_NETWORK_SPECIFIER.equals(nc.mNetworkSpecifier)); 616 } equalsSpecifier(NetworkCapabilities nc)617 private boolean equalsSpecifier(NetworkCapabilities nc) { 618 if (TextUtils.isEmpty(mNetworkSpecifier)) { 619 return TextUtils.isEmpty(nc.mNetworkSpecifier); 620 } else { 621 return mNetworkSpecifier.equals(nc.mNetworkSpecifier); 622 } 623 } 624 625 /** 626 * Magic value that indicates no signal strength provided. A request specifying this value is 627 * always satisfied. 628 * 629 * @hide 630 */ 631 public static final int SIGNAL_STRENGTH_UNSPECIFIED = Integer.MIN_VALUE; 632 633 /** 634 * Signal strength. This is a signed integer, and higher values indicate better signal. 635 * The exact units are bearer-dependent. For example, Wi-Fi uses RSSI. 636 */ 637 private int mSignalStrength; 638 639 /** 640 * Sets the signal strength. This is a signed integer, with higher values indicating a stronger 641 * signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same RSSI units 642 * reported by WifiManager. 643 * <p> 644 * Note that when used to register a network callback, this specifies the minimum acceptable 645 * signal strength. When received as the state of an existing network it specifies the current 646 * value. A value of code SIGNAL_STRENGTH_UNSPECIFIED} means no value when received and has no 647 * effect when requesting a callback. 648 * 649 * @param signalStrength the bearer-specific signal strength. 650 * @hide 651 */ setSignalStrength(int signalStrength)652 public void setSignalStrength(int signalStrength) { 653 mSignalStrength = signalStrength; 654 } 655 656 /** 657 * Returns {@code true} if this object specifies a signal strength. 658 * 659 * @hide 660 */ hasSignalStrength()661 public boolean hasSignalStrength() { 662 return mSignalStrength > SIGNAL_STRENGTH_UNSPECIFIED; 663 } 664 665 /** 666 * Retrieves the signal strength. 667 * 668 * @return The bearer-specific signal strength. 669 * @hide 670 */ getSignalStrength()671 public int getSignalStrength() { 672 return mSignalStrength; 673 } 674 combineSignalStrength(NetworkCapabilities nc)675 private void combineSignalStrength(NetworkCapabilities nc) { 676 this.mSignalStrength = Math.max(this.mSignalStrength, nc.mSignalStrength); 677 } 678 satisfiedBySignalStrength(NetworkCapabilities nc)679 private boolean satisfiedBySignalStrength(NetworkCapabilities nc) { 680 return this.mSignalStrength <= nc.mSignalStrength; 681 } 682 equalsSignalStrength(NetworkCapabilities nc)683 private boolean equalsSignalStrength(NetworkCapabilities nc) { 684 return this.mSignalStrength == nc.mSignalStrength; 685 } 686 687 /** 688 * Combine a set of Capabilities to this one. Useful for coming up with the complete set 689 * @hide 690 */ combineCapabilities(NetworkCapabilities nc)691 public void combineCapabilities(NetworkCapabilities nc) { 692 combineNetCapabilities(nc); 693 combineTransportTypes(nc); 694 combineLinkBandwidths(nc); 695 combineSpecifiers(nc); 696 combineSignalStrength(nc); 697 } 698 699 /** 700 * Check if our requirements are satisfied by the given {@code NetworkCapabilities}. 701 * 702 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements. 703 * @param onlyImmutable if {@code true}, do not consider mutable requirements such as link 704 * bandwidth, signal strength, or validation / captive portal status. 705 * 706 * @hide 707 */ satisfiedByNetworkCapabilities(NetworkCapabilities nc, boolean onlyImmutable)708 private boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc, boolean onlyImmutable) { 709 return (nc != null && 710 satisfiedByNetCapabilities(nc, onlyImmutable) && 711 satisfiedByTransportTypes(nc) && 712 (onlyImmutable || satisfiedByLinkBandwidths(nc)) && 713 satisfiedBySpecifier(nc) && 714 (onlyImmutable || satisfiedBySignalStrength(nc))); 715 } 716 717 /** 718 * Check if our requirements are satisfied by the given {@code NetworkCapabilities}. 719 * 720 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements. 721 * 722 * @hide 723 */ satisfiedByNetworkCapabilities(NetworkCapabilities nc)724 public boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc) { 725 return satisfiedByNetworkCapabilities(nc, false); 726 } 727 728 /** 729 * Check if our immutable requirements are satisfied by the given {@code NetworkCapabilities}. 730 * 731 * @param nc the {@code NetworkCapabilities} that may or may not satisfy our requirements. 732 * 733 * @hide 734 */ satisfiedByImmutableNetworkCapabilities(NetworkCapabilities nc)735 public boolean satisfiedByImmutableNetworkCapabilities(NetworkCapabilities nc) { 736 return satisfiedByNetworkCapabilities(nc, true); 737 } 738 739 /** 740 * Checks that our immutable capabilities are the same as those of the given 741 * {@code NetworkCapabilities}. 742 * 743 * @hide 744 */ equalImmutableCapabilities(NetworkCapabilities nc)745 public boolean equalImmutableCapabilities(NetworkCapabilities nc) { 746 if (nc == null) return false; 747 return (equalsNetCapabilitiesImmutable(nc) && 748 equalsTransportTypes(nc) && 749 equalsSpecifier(nc)); 750 } 751 752 @Override equals(Object obj)753 public boolean equals(Object obj) { 754 if (obj == null || (obj instanceof NetworkCapabilities == false)) return false; 755 NetworkCapabilities that = (NetworkCapabilities)obj; 756 return (equalsNetCapabilities(that) && 757 equalsTransportTypes(that) && 758 equalsLinkBandwidths(that) && 759 equalsSignalStrength(that) && 760 equalsSpecifier(that)); 761 } 762 763 @Override hashCode()764 public int hashCode() { 765 return ((int)(mNetworkCapabilities & 0xFFFFFFFF) + 766 ((int)(mNetworkCapabilities >> 32) * 3) + 767 ((int)(mTransportTypes & 0xFFFFFFFF) * 5) + 768 ((int)(mTransportTypes >> 32) * 7) + 769 (mLinkUpBandwidthKbps * 11) + 770 (mLinkDownBandwidthKbps * 13) + 771 (TextUtils.isEmpty(mNetworkSpecifier) ? 0 : mNetworkSpecifier.hashCode() * 17) + 772 (mSignalStrength * 19)); 773 } 774 775 @Override describeContents()776 public int describeContents() { 777 return 0; 778 } 779 @Override writeToParcel(Parcel dest, int flags)780 public void writeToParcel(Parcel dest, int flags) { 781 dest.writeLong(mNetworkCapabilities); 782 dest.writeLong(mTransportTypes); 783 dest.writeInt(mLinkUpBandwidthKbps); 784 dest.writeInt(mLinkDownBandwidthKbps); 785 dest.writeString(mNetworkSpecifier); 786 dest.writeInt(mSignalStrength); 787 } 788 789 public static final Creator<NetworkCapabilities> CREATOR = 790 new Creator<NetworkCapabilities>() { 791 @Override 792 public NetworkCapabilities createFromParcel(Parcel in) { 793 NetworkCapabilities netCap = new NetworkCapabilities(); 794 795 netCap.mNetworkCapabilities = in.readLong(); 796 netCap.mTransportTypes = in.readLong(); 797 netCap.mLinkUpBandwidthKbps = in.readInt(); 798 netCap.mLinkDownBandwidthKbps = in.readInt(); 799 netCap.mNetworkSpecifier = in.readString(); 800 netCap.mSignalStrength = in.readInt(); 801 return netCap; 802 } 803 @Override 804 public NetworkCapabilities[] newArray(int size) { 805 return new NetworkCapabilities[size]; 806 } 807 }; 808 809 @Override toString()810 public String toString() { 811 int[] types = getTransportTypes(); 812 String transports = (types.length > 0) ? " Transports: " + transportNamesOf(types) : ""; 813 814 types = getCapabilities(); 815 String capabilities = (types.length > 0 ? " Capabilities: " : ""); 816 for (int i = 0; i < types.length; ) { 817 switch (types[i]) { 818 case NET_CAPABILITY_MMS: capabilities += "MMS"; break; 819 case NET_CAPABILITY_SUPL: capabilities += "SUPL"; break; 820 case NET_CAPABILITY_DUN: capabilities += "DUN"; break; 821 case NET_CAPABILITY_FOTA: capabilities += "FOTA"; break; 822 case NET_CAPABILITY_IMS: capabilities += "IMS"; break; 823 case NET_CAPABILITY_CBS: capabilities += "CBS"; break; 824 case NET_CAPABILITY_WIFI_P2P: capabilities += "WIFI_P2P"; break; 825 case NET_CAPABILITY_IA: capabilities += "IA"; break; 826 case NET_CAPABILITY_RCS: capabilities += "RCS"; break; 827 case NET_CAPABILITY_XCAP: capabilities += "XCAP"; break; 828 case NET_CAPABILITY_EIMS: capabilities += "EIMS"; break; 829 case NET_CAPABILITY_NOT_METERED: capabilities += "NOT_METERED"; break; 830 case NET_CAPABILITY_INTERNET: capabilities += "INTERNET"; break; 831 case NET_CAPABILITY_NOT_RESTRICTED: capabilities += "NOT_RESTRICTED"; break; 832 case NET_CAPABILITY_TRUSTED: capabilities += "TRUSTED"; break; 833 case NET_CAPABILITY_NOT_VPN: capabilities += "NOT_VPN"; break; 834 case NET_CAPABILITY_VALIDATED: capabilities += "VALIDATED"; break; 835 case NET_CAPABILITY_CAPTIVE_PORTAL: capabilities += "CAPTIVE_PORTAL"; break; 836 } 837 if (++i < types.length) capabilities += "&"; 838 } 839 840 String upBand = ((mLinkUpBandwidthKbps > 0) ? " LinkUpBandwidth>=" + 841 mLinkUpBandwidthKbps + "Kbps" : ""); 842 String dnBand = ((mLinkDownBandwidthKbps > 0) ? " LinkDnBandwidth>=" + 843 mLinkDownBandwidthKbps + "Kbps" : ""); 844 845 String specifier = (mNetworkSpecifier == null ? 846 "" : " Specifier: <" + mNetworkSpecifier + ">"); 847 848 String signalStrength = (hasSignalStrength() ? " SignalStrength: " + mSignalStrength : ""); 849 850 return "[" + transports + capabilities + upBand + dnBand + specifier + signalStrength + "]"; 851 } 852 853 /** 854 * @hide 855 */ transportNamesOf(int[] types)856 public static String transportNamesOf(int[] types) { 857 String transports = ""; 858 for (int i = 0; i < types.length;) { 859 switch (types[i]) { 860 case TRANSPORT_CELLULAR: transports += "CELLULAR"; break; 861 case TRANSPORT_WIFI: transports += "WIFI"; break; 862 case TRANSPORT_BLUETOOTH: transports += "BLUETOOTH"; break; 863 case TRANSPORT_ETHERNET: transports += "ETHERNET"; break; 864 case TRANSPORT_VPN: transports += "VPN"; break; 865 } 866 if (++i < types.length) transports += "|"; 867 } 868 return transports; 869 } 870 } 871