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