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