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 } 52 } 53 54 /** 55 * Completely clears the contents of this object, removing even the capabilities that are set 56 * by default when the object is constructed. 57 * @hide 58 */ clearAll()59 public void clearAll() { 60 mNetworkCapabilities = mTransportTypes = 0; 61 mLinkUpBandwidthKbps = mLinkDownBandwidthKbps = 0; 62 mNetworkSpecifier = null; 63 } 64 65 /** 66 * Represents the network's capabilities. If any are specified they will be satisfied 67 * by any Network that matches all of them. 68 */ 69 private long mNetworkCapabilities; 70 71 /** 72 * Indicates this is a network that has the ability to reach the 73 * carrier's MMSC for sending and receiving MMS messages. 74 */ 75 public static final int NET_CAPABILITY_MMS = 0; 76 77 /** 78 * Indicates this is a network that has the ability to reach the carrier's 79 * SUPL server, used to retrieve GPS information. 80 */ 81 public static final int NET_CAPABILITY_SUPL = 1; 82 83 /** 84 * Indicates this is a network that has the ability to reach the carrier's 85 * DUN or tethering gateway. 86 */ 87 public static final int NET_CAPABILITY_DUN = 2; 88 89 /** 90 * Indicates this is a network that has the ability to reach the carrier's 91 * FOTA portal, used for over the air updates. 92 */ 93 public static final int NET_CAPABILITY_FOTA = 3; 94 95 /** 96 * Indicates this is a network that has the ability to reach the carrier's 97 * IMS servers, used for network registration and signaling. 98 */ 99 public static final int NET_CAPABILITY_IMS = 4; 100 101 /** 102 * Indicates this is a network that has the ability to reach the carrier's 103 * CBS servers, used for carrier specific services. 104 */ 105 public static final int NET_CAPABILITY_CBS = 5; 106 107 /** 108 * Indicates this is a network that has the ability to reach a Wi-Fi direct 109 * peer. 110 */ 111 public static final int NET_CAPABILITY_WIFI_P2P = 6; 112 113 /** 114 * Indicates this is a network that has the ability to reach a carrier's 115 * Initial Attach servers. 116 */ 117 public static final int NET_CAPABILITY_IA = 7; 118 119 /** 120 * Indicates this is a network that has the ability to reach a carrier's 121 * RCS servers, used for Rich Communication Services. 122 */ 123 public static final int NET_CAPABILITY_RCS = 8; 124 125 /** 126 * Indicates this is a network that has the ability to reach a carrier's 127 * XCAP servers, used for configuration and control. 128 */ 129 public static final int NET_CAPABILITY_XCAP = 9; 130 131 /** 132 * Indicates this is a network that has the ability to reach a carrier's 133 * Emergency IMS servers or other services, used for network signaling 134 * during emergency calls. 135 */ 136 public static final int NET_CAPABILITY_EIMS = 10; 137 138 /** 139 * Indicates that this network is unmetered. 140 */ 141 public static final int NET_CAPABILITY_NOT_METERED = 11; 142 143 /** 144 * Indicates that this network should be able to reach the internet. 145 */ 146 public static final int NET_CAPABILITY_INTERNET = 12; 147 148 /** 149 * Indicates that this network is available for general use. If this is not set 150 * applications should not attempt to communicate on this network. Note that this 151 * is simply informative and not enforcement - enforcement is handled via other means. 152 * Set by default. 153 */ 154 public static final int NET_CAPABILITY_NOT_RESTRICTED = 13; 155 156 /** 157 * Indicates that the user has indicated implicit trust of this network. This 158 * generally means it's a sim-selected carrier, a plugged in ethernet, a paired 159 * BT device or a wifi the user asked to connect to. Untrusted networks 160 * are probably limited to unknown wifi AP. Set by default. 161 */ 162 public static final int NET_CAPABILITY_TRUSTED = 14; 163 164 /** 165 * Indicates that this network is not a VPN. This capability is set by default and should be 166 * explicitly cleared for VPN networks. 167 */ 168 public static final int NET_CAPABILITY_NOT_VPN = 15; 169 170 /** 171 * Indicates that connectivity on this network was successfully validated. For example, for a 172 * network with NET_CAPABILITY_INTERNET, it means that Internet connectivity was successfully 173 * detected. 174 */ 175 public static final int NET_CAPABILITY_VALIDATED = 16; 176 177 /** 178 * Indicates that this network was found to have a captive portal in place last time it was 179 * probed. 180 */ 181 public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17; 182 183 private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS; 184 private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_CAPTIVE_PORTAL; 185 186 /** 187 * Capabilities that are set by default when the object is constructed. 188 */ 189 private static final long DEFAULT_CAPABILITIES = 190 (1 << NET_CAPABILITY_NOT_RESTRICTED) | 191 (1 << NET_CAPABILITY_TRUSTED) | 192 (1 << NET_CAPABILITY_NOT_VPN); 193 194 /** 195 * Capabilities that suggest that a network is restricted. 196 * {@see #maybeMarkCapabilitiesRestricted}. 197 */ 198 private static final long RESTRICTED_CAPABILITIES = 199 (1 << NET_CAPABILITY_CBS) | 200 (1 << NET_CAPABILITY_DUN) | 201 (1 << NET_CAPABILITY_EIMS) | 202 (1 << NET_CAPABILITY_FOTA) | 203 (1 << NET_CAPABILITY_IA) | 204 (1 << NET_CAPABILITY_IMS) | 205 (1 << NET_CAPABILITY_RCS) | 206 (1 << NET_CAPABILITY_XCAP); 207 208 /** 209 * Adds the given capability to this {@code NetworkCapability} instance. 210 * Multiple capabilities may be applied sequentially. Note that when searching 211 * for a network to satisfy a request, all capabilities requested must be satisfied. 212 * 213 * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be added. 214 * @return This NetworkCapability to facilitate chaining. 215 * @hide 216 */ addCapability(int capability)217 public NetworkCapabilities addCapability(int capability) { 218 if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) { 219 throw new IllegalArgumentException("NetworkCapability out of range"); 220 } 221 mNetworkCapabilities |= 1 << capability; 222 return this; 223 } 224 225 /** 226 * Removes (if found) the given capability from this {@code NetworkCapability} instance. 227 * 228 * @param capability the {@code NetworkCapabilities.NET_CAPABILTIY_*} to be removed. 229 * @return This NetworkCapability to facilitate chaining. 230 * @hide 231 */ removeCapability(int capability)232 public NetworkCapabilities removeCapability(int capability) { 233 if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) { 234 throw new IllegalArgumentException("NetworkCapability out of range"); 235 } 236 mNetworkCapabilities &= ~(1 << capability); 237 return this; 238 } 239 240 /** 241 * Gets all the capabilities set on this {@code NetworkCapability} instance. 242 * 243 * @return an array of {@code NetworkCapabilities.NET_CAPABILITY_*} values 244 * for this instance. 245 * @hide 246 */ getCapabilities()247 public int[] getCapabilities() { 248 return enumerateBits(mNetworkCapabilities); 249 } 250 251 /** 252 * Tests for the presence of a capabilitity on this instance. 253 * 254 * @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be tested for. 255 * @return {@code true} if set on this instance. 256 */ hasCapability(int capability)257 public boolean hasCapability(int capability) { 258 if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) { 259 return false; 260 } 261 return ((mNetworkCapabilities & (1 << capability)) != 0); 262 } 263 enumerateBits(long val)264 private int[] enumerateBits(long val) { 265 int size = Long.bitCount(val); 266 int[] result = new int[size]; 267 int index = 0; 268 int resource = 0; 269 while (val > 0) { 270 if ((val & 1) == 1) result[index++] = resource; 271 val = val >> 1; 272 resource++; 273 } 274 return result; 275 } 276 combineNetCapabilities(NetworkCapabilities nc)277 private void combineNetCapabilities(NetworkCapabilities nc) { 278 this.mNetworkCapabilities |= nc.mNetworkCapabilities; 279 } 280 satisfiedByNetCapabilities(NetworkCapabilities nc)281 private boolean satisfiedByNetCapabilities(NetworkCapabilities nc) { 282 return ((nc.mNetworkCapabilities & this.mNetworkCapabilities) == this.mNetworkCapabilities); 283 } 284 285 /** @hide */ equalsNetCapabilities(NetworkCapabilities nc)286 public boolean equalsNetCapabilities(NetworkCapabilities nc) { 287 return (nc.mNetworkCapabilities == this.mNetworkCapabilities); 288 } 289 290 /** 291 * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if all the capabilities it provides are 292 * typically provided by restricted networks. 293 * 294 * TODO: consider: 295 * - Renaming it to guessRestrictedCapability and make it set the 296 * restricted capability bit in addition to clearing it. 297 * @hide 298 */ maybeMarkCapabilitiesRestricted()299 public void maybeMarkCapabilitiesRestricted() { 300 // If all the capabilities are typically provided by restricted networks, conclude that this 301 // network is restricted. 302 if ((mNetworkCapabilities & ~(DEFAULT_CAPABILITIES | RESTRICTED_CAPABILITIES)) == 0 && 303 // Must have at least some restricted capabilities, otherwise a request for an 304 // internet-less network will get marked restricted. 305 (mNetworkCapabilities & RESTRICTED_CAPABILITIES) != 0) { 306 removeCapability(NET_CAPABILITY_NOT_RESTRICTED); 307 } 308 } 309 310 /** 311 * Representing the transport type. Apps should generally not care about transport. A 312 * request for a fast internet connection could be satisfied by a number of different 313 * transports. If any are specified here it will be satisfied a Network that matches 314 * any of them. If a caller doesn't care about the transport it should not specify any. 315 */ 316 private long mTransportTypes; 317 318 /** 319 * Indicates this network uses a Cellular transport. 320 */ 321 public static final int TRANSPORT_CELLULAR = 0; 322 323 /** 324 * Indicates this network uses a Wi-Fi transport. 325 */ 326 public static final int TRANSPORT_WIFI = 1; 327 328 /** 329 * Indicates this network uses a Bluetooth transport. 330 */ 331 public static final int TRANSPORT_BLUETOOTH = 2; 332 333 /** 334 * Indicates this network uses an Ethernet transport. 335 */ 336 public static final int TRANSPORT_ETHERNET = 3; 337 338 /** 339 * Indicates this network uses a VPN transport. 340 */ 341 public static final int TRANSPORT_VPN = 4; 342 343 private static final int MIN_TRANSPORT = TRANSPORT_CELLULAR; 344 private static final int MAX_TRANSPORT = TRANSPORT_VPN; 345 346 /** 347 * Adds the given transport type to this {@code NetworkCapability} instance. 348 * Multiple transports may be applied sequentially. Note that when searching 349 * for a network to satisfy a request, any listed in the request will satisfy the request. 350 * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a 351 * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network 352 * to be selected. This is logically different than 353 * {@code NetworkCapabilities.NET_CAPABILITY_*} listed above. 354 * 355 * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be added. 356 * @return This NetworkCapability to facilitate chaining. 357 * @hide 358 */ addTransportType(int transportType)359 public NetworkCapabilities addTransportType(int transportType) { 360 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) { 361 throw new IllegalArgumentException("TransportType out of range"); 362 } 363 mTransportTypes |= 1 << transportType; 364 setNetworkSpecifier(mNetworkSpecifier); // used for exception checking 365 return this; 366 } 367 368 /** 369 * Removes (if found) the given transport from this {@code NetworkCapability} instance. 370 * 371 * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be removed. 372 * @return This NetworkCapability to facilitate chaining. 373 * @hide 374 */ removeTransportType(int transportType)375 public NetworkCapabilities removeTransportType(int transportType) { 376 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) { 377 throw new IllegalArgumentException("TransportType out of range"); 378 } 379 mTransportTypes &= ~(1 << transportType); 380 setNetworkSpecifier(mNetworkSpecifier); // used for exception checking 381 return this; 382 } 383 384 /** 385 * Gets all the transports set on this {@code NetworkCapability} instance. 386 * 387 * @return an array of {@code NetworkCapabilities.TRANSPORT_*} values 388 * for this instance. 389 * @hide 390 */ getTransportTypes()391 public int[] getTransportTypes() { 392 return enumerateBits(mTransportTypes); 393 } 394 395 /** 396 * Tests for the presence of a transport on this instance. 397 * 398 * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be tested for. 399 * @return {@code true} if set on this instance. 400 */ hasTransport(int transportType)401 public boolean hasTransport(int transportType) { 402 if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) { 403 return false; 404 } 405 return ((mTransportTypes & (1 << transportType)) != 0); 406 } 407 combineTransportTypes(NetworkCapabilities nc)408 private void combineTransportTypes(NetworkCapabilities nc) { 409 this.mTransportTypes |= nc.mTransportTypes; 410 } satisfiedByTransportTypes(NetworkCapabilities nc)411 private boolean satisfiedByTransportTypes(NetworkCapabilities nc) { 412 return ((this.mTransportTypes == 0) || 413 ((this.mTransportTypes & nc.mTransportTypes) != 0)); 414 } 415 /** @hide */ equalsTransportTypes(NetworkCapabilities nc)416 public boolean equalsTransportTypes(NetworkCapabilities nc) { 417 return (nc.mTransportTypes == this.mTransportTypes); 418 } 419 420 /** 421 * Passive link bandwidth. This is a rough guide of the expected peak bandwidth 422 * for the first hop on the given transport. It is not measured, but may take into account 423 * link parameters (Radio technology, allocated channels, etc). 424 */ 425 private int mLinkUpBandwidthKbps; 426 private int mLinkDownBandwidthKbps; 427 428 /** 429 * Sets the upstream bandwidth for this network in Kbps. This always only refers to 430 * the estimated first hop transport bandwidth. 431 * <p> 432 * Note that when used to request a network, this specifies the minimum acceptable. 433 * When received as the state of an existing network this specifies the typical 434 * first hop bandwidth expected. This is never measured, but rather is inferred 435 * from technology type and other link parameters. It could be used to differentiate 436 * between very slow 1xRTT cellular links and other faster networks or even between 437 * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between 438 * fast backhauls and slow backhauls. 439 * 440 * @param upKbps the estimated first hop upstream (device to network) bandwidth. 441 * @hide 442 */ setLinkUpstreamBandwidthKbps(int upKbps)443 public void setLinkUpstreamBandwidthKbps(int upKbps) { 444 mLinkUpBandwidthKbps = upKbps; 445 } 446 447 /** 448 * Retrieves the upstream bandwidth for this network in Kbps. This always only refers to 449 * the estimated first hop transport bandwidth. 450 * 451 * @return The estimated first hop upstream (device to network) bandwidth. 452 */ getLinkUpstreamBandwidthKbps()453 public int getLinkUpstreamBandwidthKbps() { 454 return mLinkUpBandwidthKbps; 455 } 456 457 /** 458 * Sets the downstream bandwidth for this network in Kbps. This always only refers to 459 * the estimated first hop transport bandwidth. 460 * <p> 461 * Note that when used to request a network, this specifies the minimum acceptable. 462 * When received as the state of an existing network this specifies the typical 463 * first hop bandwidth expected. This is never measured, but rather is inferred 464 * from technology type and other link parameters. It could be used to differentiate 465 * between very slow 1xRTT cellular links and other faster networks or even between 466 * 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between 467 * fast backhauls and slow backhauls. 468 * 469 * @param downKbps the estimated first hop downstream (network to device) bandwidth. 470 * @hide 471 */ setLinkDownstreamBandwidthKbps(int downKbps)472 public void setLinkDownstreamBandwidthKbps(int downKbps) { 473 mLinkDownBandwidthKbps = downKbps; 474 } 475 476 /** 477 * Retrieves the downstream bandwidth for this network in Kbps. This always only refers to 478 * the estimated first hop transport bandwidth. 479 * 480 * @return The estimated first hop downstream (network to device) bandwidth. 481 */ getLinkDownstreamBandwidthKbps()482 public int getLinkDownstreamBandwidthKbps() { 483 return mLinkDownBandwidthKbps; 484 } 485 combineLinkBandwidths(NetworkCapabilities nc)486 private void combineLinkBandwidths(NetworkCapabilities nc) { 487 this.mLinkUpBandwidthKbps = 488 Math.max(this.mLinkUpBandwidthKbps, nc.mLinkUpBandwidthKbps); 489 this.mLinkDownBandwidthKbps = 490 Math.max(this.mLinkDownBandwidthKbps, nc.mLinkDownBandwidthKbps); 491 } satisfiedByLinkBandwidths(NetworkCapabilities nc)492 private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) { 493 return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps || 494 this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps); 495 } equalsLinkBandwidths(NetworkCapabilities nc)496 private boolean equalsLinkBandwidths(NetworkCapabilities nc) { 497 return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps && 498 this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps); 499 } 500 501 private String mNetworkSpecifier; 502 /** 503 * Sets the optional bearer specific network specifier. 504 * This has no meaning if a single transport is also not specified, so calling 505 * this without a single transport set will generate an exception, as will 506 * subsequently adding or removing transports after this is set. 507 * </p> 508 * The interpretation of this {@code String} is bearer specific and bearers that use 509 * it should document their particulars. For example, Bluetooth may use some sort of 510 * device id while WiFi could used SSID and/or BSSID. Cellular may use carrier SPN (name) 511 * or Subscription ID. 512 * 513 * @param networkSpecifier An {@code String} of opaque format used to specify the bearer 514 * specific network specifier where the bearer has a choice of 515 * networks. 516 * @hide 517 */ setNetworkSpecifier(String networkSpecifier)518 public void setNetworkSpecifier(String networkSpecifier) { 519 if (TextUtils.isEmpty(networkSpecifier) == false && Long.bitCount(mTransportTypes) != 1) { 520 throw new IllegalStateException("Must have a single transport specified to use " + 521 "setNetworkSpecifier"); 522 } 523 mNetworkSpecifier = networkSpecifier; 524 } 525 526 /** 527 * Gets the optional bearer specific network specifier. 528 * 529 * @return The optional {@code String} specifying the bearer specific network specifier. 530 * See {@link #setNetworkSpecifier}. 531 * @hide 532 */ getNetworkSpecifier()533 public String getNetworkSpecifier() { 534 return mNetworkSpecifier; 535 } 536 combineSpecifiers(NetworkCapabilities nc)537 private void combineSpecifiers(NetworkCapabilities nc) { 538 String otherSpecifier = nc.getNetworkSpecifier(); 539 if (TextUtils.isEmpty(otherSpecifier)) return; 540 if (TextUtils.isEmpty(mNetworkSpecifier) == false) { 541 throw new IllegalStateException("Can't combine two networkSpecifiers"); 542 } 543 setNetworkSpecifier(otherSpecifier); 544 } satisfiedBySpecifier(NetworkCapabilities nc)545 private boolean satisfiedBySpecifier(NetworkCapabilities nc) { 546 return (TextUtils.isEmpty(mNetworkSpecifier) || 547 mNetworkSpecifier.equals(nc.mNetworkSpecifier)); 548 } equalsSpecifier(NetworkCapabilities nc)549 private boolean equalsSpecifier(NetworkCapabilities nc) { 550 if (TextUtils.isEmpty(mNetworkSpecifier)) { 551 return TextUtils.isEmpty(nc.mNetworkSpecifier); 552 } else { 553 return mNetworkSpecifier.equals(nc.mNetworkSpecifier); 554 } 555 } 556 557 /** 558 * Combine a set of Capabilities to this one. Useful for coming up with the complete set 559 * {@hide} 560 */ combineCapabilities(NetworkCapabilities nc)561 public void combineCapabilities(NetworkCapabilities nc) { 562 combineNetCapabilities(nc); 563 combineTransportTypes(nc); 564 combineLinkBandwidths(nc); 565 combineSpecifiers(nc); 566 } 567 568 /** 569 * Check if our requirements are satisfied by the given Capabilities. 570 * {@hide} 571 */ satisfiedByNetworkCapabilities(NetworkCapabilities nc)572 public boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc) { 573 return (nc != null && 574 satisfiedByNetCapabilities(nc) && 575 satisfiedByTransportTypes(nc) && 576 satisfiedByLinkBandwidths(nc) && 577 satisfiedBySpecifier(nc)); 578 } 579 580 @Override equals(Object obj)581 public boolean equals(Object obj) { 582 if (obj == null || (obj instanceof NetworkCapabilities == false)) return false; 583 NetworkCapabilities that = (NetworkCapabilities)obj; 584 return (equalsNetCapabilities(that) && 585 equalsTransportTypes(that) && 586 equalsLinkBandwidths(that) && 587 equalsSpecifier(that)); 588 } 589 590 @Override hashCode()591 public int hashCode() { 592 return ((int)(mNetworkCapabilities & 0xFFFFFFFF) + 593 ((int)(mNetworkCapabilities >> 32) * 3) + 594 ((int)(mTransportTypes & 0xFFFFFFFF) * 5) + 595 ((int)(mTransportTypes >> 32) * 7) + 596 (mLinkUpBandwidthKbps * 11) + 597 (mLinkDownBandwidthKbps * 13) + 598 (TextUtils.isEmpty(mNetworkSpecifier) ? 0 : mNetworkSpecifier.hashCode() * 17)); 599 } 600 601 @Override describeContents()602 public int describeContents() { 603 return 0; 604 } 605 @Override writeToParcel(Parcel dest, int flags)606 public void writeToParcel(Parcel dest, int flags) { 607 dest.writeLong(mNetworkCapabilities); 608 dest.writeLong(mTransportTypes); 609 dest.writeInt(mLinkUpBandwidthKbps); 610 dest.writeInt(mLinkDownBandwidthKbps); 611 dest.writeString(mNetworkSpecifier); 612 } 613 public static final Creator<NetworkCapabilities> CREATOR = 614 new Creator<NetworkCapabilities>() { 615 @Override 616 public NetworkCapabilities createFromParcel(Parcel in) { 617 NetworkCapabilities netCap = new NetworkCapabilities(); 618 619 netCap.mNetworkCapabilities = in.readLong(); 620 netCap.mTransportTypes = in.readLong(); 621 netCap.mLinkUpBandwidthKbps = in.readInt(); 622 netCap.mLinkDownBandwidthKbps = in.readInt(); 623 netCap.mNetworkSpecifier = in.readString(); 624 return netCap; 625 } 626 @Override 627 public NetworkCapabilities[] newArray(int size) { 628 return new NetworkCapabilities[size]; 629 } 630 }; 631 632 @Override toString()633 public String toString() { 634 int[] types = getTransportTypes(); 635 String transports = (types.length > 0 ? " Transports: " : ""); 636 for (int i = 0; i < types.length;) { 637 switch (types[i]) { 638 case TRANSPORT_CELLULAR: transports += "CELLULAR"; break; 639 case TRANSPORT_WIFI: transports += "WIFI"; break; 640 case TRANSPORT_BLUETOOTH: transports += "BLUETOOTH"; break; 641 case TRANSPORT_ETHERNET: transports += "ETHERNET"; break; 642 case TRANSPORT_VPN: transports += "VPN"; break; 643 } 644 if (++i < types.length) transports += "|"; 645 } 646 647 types = getCapabilities(); 648 String capabilities = (types.length > 0 ? " Capabilities: " : ""); 649 for (int i = 0; i < types.length; ) { 650 switch (types[i]) { 651 case NET_CAPABILITY_MMS: capabilities += "MMS"; break; 652 case NET_CAPABILITY_SUPL: capabilities += "SUPL"; break; 653 case NET_CAPABILITY_DUN: capabilities += "DUN"; break; 654 case NET_CAPABILITY_FOTA: capabilities += "FOTA"; break; 655 case NET_CAPABILITY_IMS: capabilities += "IMS"; break; 656 case NET_CAPABILITY_CBS: capabilities += "CBS"; break; 657 case NET_CAPABILITY_WIFI_P2P: capabilities += "WIFI_P2P"; break; 658 case NET_CAPABILITY_IA: capabilities += "IA"; break; 659 case NET_CAPABILITY_RCS: capabilities += "RCS"; break; 660 case NET_CAPABILITY_XCAP: capabilities += "XCAP"; break; 661 case NET_CAPABILITY_EIMS: capabilities += "EIMS"; break; 662 case NET_CAPABILITY_NOT_METERED: capabilities += "NOT_METERED"; break; 663 case NET_CAPABILITY_INTERNET: capabilities += "INTERNET"; break; 664 case NET_CAPABILITY_NOT_RESTRICTED: capabilities += "NOT_RESTRICTED"; break; 665 case NET_CAPABILITY_TRUSTED: capabilities += "TRUSTED"; break; 666 case NET_CAPABILITY_NOT_VPN: capabilities += "NOT_VPN"; break; 667 case NET_CAPABILITY_VALIDATED: capabilities += "VALIDATED"; break; 668 case NET_CAPABILITY_CAPTIVE_PORTAL: capabilities += "CAPTIVE_PORTAL"; break; 669 } 670 if (++i < types.length) capabilities += "&"; 671 } 672 673 String upBand = ((mLinkUpBandwidthKbps > 0) ? " LinkUpBandwidth>=" + 674 mLinkUpBandwidthKbps + "Kbps" : ""); 675 String dnBand = ((mLinkDownBandwidthKbps > 0) ? " LinkDnBandwidth>=" + 676 mLinkDownBandwidthKbps + "Kbps" : ""); 677 678 String specifier = (mNetworkSpecifier == null ? 679 "" : " Specifier: <" + mNetworkSpecifier + ">"); 680 681 return "[" + transports + capabilities + upBand + dnBand + specifier + "]"; 682 } 683 } 684