1 /* 2 * Copyright (C) 2011 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 static android.annotation.SystemApi.Client.MODULE_LIBRARIES; 20 import static android.net.ConnectivityManager.TYPE_MOBILE; 21 import static android.net.ConnectivityManager.TYPE_WIFI; 22 import static android.net.NetworkTemplate.NETWORK_TYPE_ALL; 23 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; 24 25 import android.annotation.IntDef; 26 import android.annotation.NonNull; 27 import android.annotation.Nullable; 28 import android.annotation.SuppressLint; 29 import android.annotation.SystemApi; 30 import android.app.usage.NetworkStatsManager; 31 import android.content.Context; 32 import android.net.wifi.WifiInfo; 33 import android.service.NetworkIdentityProto; 34 import android.telephony.TelephonyManager; 35 import android.util.Log; 36 import android.util.proto.ProtoOutputStream; 37 38 import com.android.net.module.util.BitUtils; 39 import com.android.net.module.util.CollectionUtils; 40 import com.android.net.module.util.NetworkIdentityUtils; 41 42 import java.lang.annotation.Retention; 43 import java.lang.annotation.RetentionPolicy; 44 import java.util.ArrayList; 45 import java.util.Objects; 46 47 /** 48 * Network definition that includes strong identity. Analogous to combining 49 * {@link NetworkCapabilities} and an IMSI. 50 * 51 * @hide 52 */ 53 @SystemApi(client = MODULE_LIBRARIES) 54 public class NetworkIdentity { 55 private static final String TAG = "NetworkIdentity"; 56 57 /** @hide */ 58 // TODO: Remove this after migrating all callers to use 59 // {@link NetworkTemplate#NETWORK_TYPE_ALL} instead. 60 public static final int SUBTYPE_COMBINED = -1; 61 62 /** @hide */ 63 @Retention(RetentionPolicy.SOURCE) 64 @IntDef(prefix = { "OEM_MANAGED_" }, flag = true, value = { 65 NetworkTemplate.OEM_MANAGED_NO, 66 NetworkTemplate.OEM_MANAGED_PAID, 67 NetworkTemplate.OEM_MANAGED_PRIVATE 68 }) 69 public @interface OemManaged{} 70 71 /** 72 * Network has no {@code NetworkCapabilities#NET_CAPABILITY_OEM_*}. 73 * @hide 74 */ 75 public static final int OEM_NONE = 0x0; 76 /** 77 * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PAID}. 78 * @hide 79 */ 80 public static final int OEM_PAID = 1 << 0; 81 /** 82 * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PRIVATE}. 83 * @hide 84 */ 85 public static final int OEM_PRIVATE = 1 << 1; 86 87 private static final long SUPPORTED_OEM_MANAGED_TYPES = OEM_PAID | OEM_PRIVATE; 88 89 // Need to be synchronized with ConnectivityManager. 90 // TODO: Use {@code ConnectivityManager#*} when visible. 91 static final int TYPE_TEST = 18; 92 private static final int MAX_NETWORK_TYPE = TYPE_TEST; 93 private static final int MIN_NETWORK_TYPE = TYPE_MOBILE; 94 95 final int mType; 96 final int mRatType; 97 final int mSubId; 98 final String mSubscriberId; 99 final String mWifiNetworkKey; 100 final boolean mRoaming; 101 final boolean mMetered; 102 final boolean mDefaultNetwork; 103 final int mOemManaged; 104 105 /** @hide */ NetworkIdentity( int type, int ratType, @Nullable String subscriberId, @Nullable String wifiNetworkKey, boolean roaming, boolean metered, boolean defaultNetwork, int oemManaged, int subId)106 public NetworkIdentity( 107 int type, int ratType, @Nullable String subscriberId, @Nullable String wifiNetworkKey, 108 boolean roaming, boolean metered, boolean defaultNetwork, int oemManaged, int subId) { 109 mType = type; 110 mRatType = ratType; 111 mSubscriberId = subscriberId; 112 mWifiNetworkKey = wifiNetworkKey; 113 mRoaming = roaming; 114 mMetered = metered; 115 mDefaultNetwork = defaultNetwork; 116 mOemManaged = oemManaged; 117 mSubId = subId; 118 } 119 120 @Override hashCode()121 public int hashCode() { 122 return Objects.hash(mType, mRatType, mSubscriberId, mWifiNetworkKey, mRoaming, mMetered, 123 mDefaultNetwork, mOemManaged, mSubId); 124 } 125 126 @Override equals(@ullable Object obj)127 public boolean equals(@Nullable Object obj) { 128 if (obj instanceof NetworkIdentity) { 129 final NetworkIdentity ident = (NetworkIdentity) obj; 130 return mType == ident.mType && mRatType == ident.mRatType && mRoaming == ident.mRoaming 131 && Objects.equals(mSubscriberId, ident.mSubscriberId) 132 && Objects.equals(mWifiNetworkKey, ident.mWifiNetworkKey) 133 && mMetered == ident.mMetered 134 && mDefaultNetwork == ident.mDefaultNetwork 135 && mOemManaged == ident.mOemManaged 136 && mSubId == ident.mSubId; 137 } 138 return false; 139 } 140 141 @Override toString()142 public String toString() { 143 final StringBuilder builder = new StringBuilder("{"); 144 builder.append("type=").append(mType); 145 builder.append(", ratType="); 146 if (mRatType == NETWORK_TYPE_ALL) { 147 builder.append("COMBINED"); 148 } else { 149 builder.append(mRatType); 150 } 151 if (mSubscriberId != null) { 152 builder.append(", subscriberId=") 153 .append(NetworkIdentityUtils.scrubSubscriberId(mSubscriberId)); 154 } 155 if (mWifiNetworkKey != null) { 156 builder.append(", wifiNetworkKey=").append(mWifiNetworkKey); 157 } 158 if (mRoaming) { 159 builder.append(", ROAMING"); 160 } 161 builder.append(", metered=").append(mMetered); 162 builder.append(", defaultNetwork=").append(mDefaultNetwork); 163 builder.append(", oemManaged=").append(getOemManagedNames(mOemManaged)); 164 builder.append(", subId=").append(mSubId); 165 return builder.append("}").toString(); 166 } 167 168 /** 169 * Get the human readable representation of a bitfield representing the OEM managed state of a 170 * network. 171 */ getOemManagedNames(int oemManaged)172 static String getOemManagedNames(int oemManaged) { 173 if (oemManaged == OEM_NONE) { 174 return "OEM_NONE"; 175 } 176 final int[] bitPositions = BitUtils.unpackBits(oemManaged); 177 final ArrayList<String> oemManagedNames = new ArrayList<String>(); 178 for (int position : bitPositions) { 179 oemManagedNames.add(nameOfOemManaged(1 << position)); 180 } 181 return String.join(",", oemManagedNames); 182 } 183 nameOfOemManaged(int oemManagedBit)184 private static String nameOfOemManaged(int oemManagedBit) { 185 switch (oemManagedBit) { 186 case OEM_PAID: 187 return "OEM_PAID"; 188 case OEM_PRIVATE: 189 return "OEM_PRIVATE"; 190 default: 191 return "Invalid(" + oemManagedBit + ")"; 192 } 193 } 194 195 /** @hide */ dumpDebug(ProtoOutputStream proto, long tag)196 public void dumpDebug(ProtoOutputStream proto, long tag) { 197 final long start = proto.start(tag); 198 199 proto.write(NetworkIdentityProto.TYPE, mType); 200 201 // TODO: dump mRatType as well. 202 203 proto.write(NetworkIdentityProto.ROAMING, mRoaming); 204 proto.write(NetworkIdentityProto.METERED, mMetered); 205 proto.write(NetworkIdentityProto.DEFAULT_NETWORK, mDefaultNetwork); 206 proto.write(NetworkIdentityProto.OEM_MANAGED_NETWORK, mOemManaged); 207 208 proto.end(start); 209 } 210 211 /** Get the network type of this instance. */ getType()212 public int getType() { 213 return mType; 214 } 215 216 /** Get the Radio Access Technology(RAT) type of this instance. */ getRatType()217 public int getRatType() { 218 return mRatType; 219 } 220 221 /** Get the Subscriber Id of this instance. */ 222 @Nullable getSubscriberId()223 public String getSubscriberId() { 224 return mSubscriberId; 225 } 226 227 /** Get the Wifi Network Key of this instance. See {@link WifiInfo#getNetworkKey()}. */ 228 @Nullable getWifiNetworkKey()229 public String getWifiNetworkKey() { 230 return mWifiNetworkKey; 231 } 232 233 /** @hide */ 234 // TODO: Remove this function after all callers are removed. getRoaming()235 public boolean getRoaming() { 236 return mRoaming; 237 } 238 239 /** Return whether this network is roaming. */ isRoaming()240 public boolean isRoaming() { 241 return mRoaming; 242 } 243 244 /** @hide */ 245 // TODO: Remove this function after all callers are removed. getMetered()246 public boolean getMetered() { 247 return mMetered; 248 } 249 250 /** Return whether this network is metered. */ isMetered()251 public boolean isMetered() { 252 return mMetered; 253 } 254 255 /** @hide */ 256 // TODO: Remove this function after all callers are removed. getDefaultNetwork()257 public boolean getDefaultNetwork() { 258 return mDefaultNetwork; 259 } 260 261 /** Return whether this network is the default network. */ isDefaultNetwork()262 public boolean isDefaultNetwork() { 263 return mDefaultNetwork; 264 } 265 266 /** Get the OEM managed type of this instance. */ getOemManaged()267 public int getOemManaged() { 268 return mOemManaged; 269 } 270 271 /** Get the SubId of this instance. */ getSubId()272 public int getSubId() { 273 return mSubId; 274 } 275 276 /** 277 * Assemble a {@link NetworkIdentity} from the passed arguments. 278 * 279 * This methods builds an identity based on the capabilities of the network in the 280 * snapshot and other passed arguments. The identity is used as a key to record data usage. 281 * 282 * @param snapshot the snapshot of network state. See {@link NetworkStateSnapshot}. 283 * @param defaultNetwork whether the network is a default network. 284 * @param ratType the Radio Access Technology(RAT) type of the network. Or 285 * {@link TelephonyManager#NETWORK_TYPE_UNKNOWN} if not applicable. 286 * See {@code TelephonyManager.NETWORK_TYPE_*}. 287 * @hide 288 * @deprecated See {@link NetworkIdentity.Builder}. 289 */ 290 // TODO: Remove this after all callers are migrated to use new Api. 291 @Deprecated 292 @NonNull buildNetworkIdentity(Context context, @NonNull NetworkStateSnapshot snapshot, boolean defaultNetwork, int ratType)293 public static NetworkIdentity buildNetworkIdentity(Context context, 294 @NonNull NetworkStateSnapshot snapshot, boolean defaultNetwork, int ratType) { 295 final NetworkIdentity.Builder builder = new NetworkIdentity.Builder() 296 .setNetworkStateSnapshot(snapshot).setDefaultNetwork(defaultNetwork) 297 .setSubId(snapshot.getSubId()); 298 if (snapshot.getLegacyType() == TYPE_MOBILE && ratType != NETWORK_TYPE_ALL) { 299 builder.setRatType(ratType); 300 } 301 return builder.build(); 302 } 303 304 /** 305 * Builds a bitfield of {@code NetworkIdentity.OEM_*} based on {@link NetworkCapabilities}. 306 * @hide 307 */ getOemBitfield(@onNull NetworkCapabilities nc)308 public static int getOemBitfield(@NonNull NetworkCapabilities nc) { 309 int oemManaged = OEM_NONE; 310 311 if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID)) { 312 oemManaged |= OEM_PAID; 313 } 314 if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE)) { 315 oemManaged |= OEM_PRIVATE; 316 } 317 318 return oemManaged; 319 } 320 321 /** @hide */ compare(@onNull NetworkIdentity left, @NonNull NetworkIdentity right)322 public static int compare(@NonNull NetworkIdentity left, @NonNull NetworkIdentity right) { 323 Objects.requireNonNull(right); 324 int res = Integer.compare(left.mType, right.mType); 325 if (res == 0) { 326 res = Integer.compare(left.mRatType, right.mRatType); 327 } 328 if (res == 0 && left.mSubscriberId != null && right.mSubscriberId != null) { 329 res = left.mSubscriberId.compareTo(right.mSubscriberId); 330 } 331 if (res == 0 && left.mWifiNetworkKey != null && right.mWifiNetworkKey != null) { 332 res = left.mWifiNetworkKey.compareTo(right.mWifiNetworkKey); 333 } 334 if (res == 0) { 335 res = Boolean.compare(left.mRoaming, right.mRoaming); 336 } 337 if (res == 0) { 338 res = Boolean.compare(left.mMetered, right.mMetered); 339 } 340 if (res == 0) { 341 res = Boolean.compare(left.mDefaultNetwork, right.mDefaultNetwork); 342 } 343 if (res == 0) { 344 res = Integer.compare(left.mOemManaged, right.mOemManaged); 345 } 346 if (res == 0) { 347 res = Integer.compare(left.mSubId, right.mSubId); 348 } 349 return res; 350 } 351 352 /** 353 * Builder class for {@link NetworkIdentity}. 354 */ 355 public static final class Builder { 356 private int mType; 357 private int mRatType; 358 private String mSubscriberId; 359 private String mWifiNetworkKey; 360 private boolean mRoaming; 361 private boolean mMetered; 362 private boolean mDefaultNetwork; 363 private int mOemManaged; 364 private int mSubId; 365 366 /** 367 * Creates a new Builder. 368 */ Builder()369 public Builder() { 370 // Initialize with default values. Will be overwritten by setters. 371 mType = ConnectivityManager.TYPE_NONE; 372 mRatType = NetworkTemplate.NETWORK_TYPE_ALL; 373 mSubscriberId = null; 374 mWifiNetworkKey = null; 375 mRoaming = false; 376 mMetered = false; 377 mDefaultNetwork = false; 378 mOemManaged = NetworkTemplate.OEM_MANAGED_NO; 379 mSubId = INVALID_SUBSCRIPTION_ID; 380 } 381 382 /** 383 * Add an {@link NetworkStateSnapshot} into the {@link NetworkIdentity} instance. 384 * This is a useful shorthand that will read from the snapshot and set the 385 * following fields, if they are set in the snapshot : 386 * - type 387 * - subscriberId 388 * - roaming 389 * - metered 390 * - oemManaged 391 * - wifiNetworkKey 392 * 393 * @param snapshot The target {@link NetworkStateSnapshot} object. 394 * @return The builder object. 395 */ 396 @SuppressLint("MissingGetterMatchingBuilder") 397 @NonNull setNetworkStateSnapshot(@onNull NetworkStateSnapshot snapshot)398 public Builder setNetworkStateSnapshot(@NonNull NetworkStateSnapshot snapshot) { 399 setType(snapshot.getLegacyType()); 400 401 setSubscriberId(snapshot.getSubscriberId()); 402 setRoaming(!snapshot.getNetworkCapabilities().hasCapability( 403 NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)); 404 setMetered(!snapshot.getNetworkCapabilities().hasCapability( 405 NetworkCapabilities.NET_CAPABILITY_NOT_METERED)); 406 407 setOemManaged(getOemBitfield(snapshot.getNetworkCapabilities())); 408 409 if (mType == TYPE_WIFI) { 410 final NetworkCapabilities nc = snapshot.getNetworkCapabilities(); 411 final TransportInfo transportInfo = nc.getTransportInfo(); 412 if (transportInfo instanceof WifiInfo) { 413 final WifiInfo info = (WifiInfo) transportInfo; 414 // Log.wtf to catch trying to set a null wifiNetworkKey into NetworkIdentity. 415 // See b/266598304. The problematic data that has null wifi network key is 416 // thrown out when storing data, which is handled by the service. 417 if (info.getNetworkKey() == null) { 418 Log.wtf(TAG, "WifiInfo contains a null wifiNetworkKey and it will" 419 + " be set into NetworkIdentity, netId=" + snapshot.getNetwork() 420 + "NetworkCapabilities=" + nc); 421 } 422 setWifiNetworkKey(info.getNetworkKey()); 423 } 424 } else if (mType == TYPE_TEST) { 425 final NetworkSpecifier ns = snapshot.getNetworkCapabilities().getNetworkSpecifier(); 426 if (ns instanceof TestNetworkSpecifier) { 427 // Reuse the wifi network key field to identify individual test networks. 428 setWifiNetworkKey(((TestNetworkSpecifier) ns).getInterfaceName()); 429 } 430 } 431 return this; 432 } 433 434 /** 435 * Set the network type of the network. 436 * 437 * @param type the network type. See {@link ConnectivityManager#TYPE_*}. 438 * 439 * @return this builder. 440 */ 441 @NonNull setType(int type)442 public Builder setType(int type) { 443 // Include TYPE_NONE for compatibility, type field might not be filled by some 444 // networks such as test networks. 445 if ((type < MIN_NETWORK_TYPE || MAX_NETWORK_TYPE < type) 446 && type != ConnectivityManager.TYPE_NONE) { 447 throw new IllegalArgumentException("Invalid network type: " + type); 448 } 449 mType = type; 450 return this; 451 } 452 453 /** 454 * Set the Radio Access Technology(RAT) type of the network. 455 * 456 * No RAT type is specified by default. Call clearRatType to reset. 457 * 458 * @param ratType the Radio Access Technology(RAT) type if applicable. See 459 * {@code TelephonyManager.NETWORK_TYPE_*}. 460 * 461 * @return this builder. 462 */ 463 @NonNull setRatType(int ratType)464 public Builder setRatType(int ratType) { 465 if (!CollectionUtils.contains(TelephonyManager.getAllNetworkTypes(), ratType) 466 && ratType != TelephonyManager.NETWORK_TYPE_UNKNOWN 467 && ratType != NetworkStatsManager.NETWORK_TYPE_5G_NSA) { 468 throw new IllegalArgumentException("Invalid ratType " + ratType); 469 } 470 mRatType = ratType; 471 return this; 472 } 473 474 /** 475 * Clear the Radio Access Technology(RAT) type of the network. 476 * 477 * @return this builder. 478 */ 479 @NonNull clearRatType()480 public Builder clearRatType() { 481 mRatType = NetworkTemplate.NETWORK_TYPE_ALL; 482 return this; 483 } 484 485 /** 486 * Set the Subscriber Id. 487 * 488 * @param subscriberId the Subscriber Id of the network. Or null if not applicable. 489 * @return this builder. 490 */ 491 @NonNull setSubscriberId(@ullable String subscriberId)492 public Builder setSubscriberId(@Nullable String subscriberId) { 493 mSubscriberId = subscriberId; 494 return this; 495 } 496 497 /** 498 * Set the Wifi Network Key. 499 * 500 * @param wifiNetworkKey Wifi Network Key of the network, 501 * see {@link WifiInfo#getNetworkKey()}. 502 * Or null if not applicable. 503 * @return this builder. 504 */ 505 @NonNull setWifiNetworkKey(@ullable String wifiNetworkKey)506 public Builder setWifiNetworkKey(@Nullable String wifiNetworkKey) { 507 mWifiNetworkKey = wifiNetworkKey; 508 return this; 509 } 510 511 /** 512 * Set whether this network is roaming. 513 * 514 * This field is false by default. Call with false to reset. 515 * 516 * @param roaming the roaming status of the network. 517 * @return this builder. 518 */ 519 @NonNull setRoaming(boolean roaming)520 public Builder setRoaming(boolean roaming) { 521 mRoaming = roaming; 522 return this; 523 } 524 525 /** 526 * Set whether this network is metered. 527 * 528 * This field is false by default. Call with false to reset. 529 * 530 * @param metered the meteredness of the network. 531 * @return this builder. 532 */ 533 @NonNull setMetered(boolean metered)534 public Builder setMetered(boolean metered) { 535 mMetered = metered; 536 return this; 537 } 538 539 /** 540 * Set whether this network is the default network. 541 * 542 * This field is false by default. Call with false to reset. 543 * 544 * @param defaultNetwork the default network status of the network. 545 * @return this builder. 546 */ 547 @NonNull setDefaultNetwork(boolean defaultNetwork)548 public Builder setDefaultNetwork(boolean defaultNetwork) { 549 mDefaultNetwork = defaultNetwork; 550 return this; 551 } 552 553 /** 554 * Set the OEM managed type. 555 * 556 * @param oemManaged Type of OEM managed network or unmanaged networks. 557 * See {@code NetworkTemplate#OEM_MANAGED_*}. 558 * @return this builder. 559 */ 560 @NonNull setOemManaged(@emManaged int oemManaged)561 public Builder setOemManaged(@OemManaged int oemManaged) { 562 // Assert input does not contain illegal oemManage bits. 563 if ((~SUPPORTED_OEM_MANAGED_TYPES & oemManaged) != 0) { 564 throw new IllegalArgumentException("Invalid value for OemManaged : " + oemManaged); 565 } 566 mOemManaged = oemManaged; 567 return this; 568 } 569 570 /** 571 * Set the Subscription Id. 572 * 573 * @param subId the Subscription Id of the network. Or INVALID_SUBSCRIPTION_ID if not 574 * applicable. 575 * @return this builder. 576 */ 577 @NonNull setSubId(int subId)578 public Builder setSubId(int subId) { 579 mSubId = subId; 580 return this; 581 } 582 ensureValidParameters()583 private void ensureValidParameters() { 584 // Assert non-mobile network cannot have a ratType. 585 if (mType != TYPE_MOBILE && mRatType != NetworkTemplate.NETWORK_TYPE_ALL) { 586 throw new IllegalArgumentException( 587 "Invalid ratType " + mRatType + " for type " + mType); 588 } 589 590 // Assert non-wifi network cannot have a wifi network key. 591 if (mType != TYPE_WIFI && mType != TYPE_TEST && mWifiNetworkKey != null) { 592 throw new IllegalArgumentException("Invalid wifi network key for type " + mType); 593 } 594 } 595 596 /** 597 * Builds the instance of the {@link NetworkIdentity}. 598 * 599 * @return the built instance of {@link NetworkIdentity}. 600 */ 601 @NonNull build()602 public NetworkIdentity build() { 603 ensureValidParameters(); 604 return new NetworkIdentity(mType, mRatType, mSubscriberId, mWifiNetworkKey, 605 mRoaming, mMetered, mDefaultNetwork, mOemManaged, mSubId); 606 } 607 } 608 } 609