1 /* 2 * Copyright (C) 2007 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.NetworkStats.UID_ALL; 21 22 import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE; 23 24 import android.annotation.NonNull; 25 import android.annotation.Nullable; 26 import android.annotation.RequiresPermission; 27 import android.annotation.SuppressLint; 28 import android.annotation.SystemApi; 29 import android.annotation.TestApi; 30 import android.app.DownloadManager; 31 import android.app.backup.BackupManager; 32 import android.app.usage.NetworkStatsManager; 33 import android.compat.annotation.UnsupportedAppUsage; 34 import android.content.Context; 35 import android.media.MediaPlayer; 36 import android.net.netstats.StatsResult; 37 import android.net.netstats.TrafficStatsRateLimitCacheConfig; 38 import android.os.Binder; 39 import android.os.Build; 40 import android.os.RemoteException; 41 import android.os.StrictMode; 42 import android.os.SystemClock; 43 import android.util.Log; 44 45 import com.android.internal.annotations.GuardedBy; 46 import com.android.internal.annotations.VisibleForTesting; 47 import com.android.net.module.util.BinderUtils; 48 import com.android.net.module.util.LruCacheWithExpiry; 49 50 import java.io.FileDescriptor; 51 import java.io.IOException; 52 import java.net.DatagramSocket; 53 import java.net.Socket; 54 import java.net.SocketException; 55 import java.util.function.LongSupplier; 56 57 /** 58 * Class that provides network traffic statistics. These statistics include 59 * bytes transmitted and received and network packets transmitted and received, 60 * over all interfaces, over the mobile interface, and on a per-UID basis. 61 * <p> 62 * These statistics may not be available on all platforms. If the statistics are 63 * not supported by this device, {@link #UNSUPPORTED} will be returned. 64 * <p> 65 * Note that the statistics returned by this class reset and start from zero 66 * after every reboot. To access more robust historical network statistics data, 67 * use {@link NetworkStatsManager} instead. 68 */ 69 public class TrafficStats { 70 static { 71 System.loadLibrary("framework-connectivity-tiramisu-jni"); 72 } 73 74 private static final String TAG = TrafficStats.class.getSimpleName(); 75 /** 76 * The return value to indicate that the device does not support the statistic. 77 */ 78 public final static int UNSUPPORTED = -1; 79 80 /** @hide @deprecated use {@code DataUnit} instead to clarify SI-vs-IEC */ 81 @Deprecated 82 public static final long KB_IN_BYTES = 1024; 83 /** @hide @deprecated use {@code DataUnit} instead to clarify SI-vs-IEC */ 84 @Deprecated 85 public static final long MB_IN_BYTES = KB_IN_BYTES * 1024; 86 /** @hide @deprecated use {@code DataUnit} instead to clarify SI-vs-IEC */ 87 @Deprecated 88 public static final long GB_IN_BYTES = MB_IN_BYTES * 1024; 89 /** @hide @deprecated use {@code DataUnit} instead to clarify SI-vs-IEC */ 90 @Deprecated 91 public static final long TB_IN_BYTES = GB_IN_BYTES * 1024; 92 /** @hide @deprecated use {@code DataUnit} instead to clarify SI-vs-IEC */ 93 @Deprecated 94 public static final long PB_IN_BYTES = TB_IN_BYTES * 1024; 95 96 /** 97 * Special UID value used when collecting {@link NetworkStatsHistory} for 98 * removed applications. 99 * 100 * @hide 101 */ 102 public static final int UID_REMOVED = -4; 103 104 /** 105 * Special UID value used when collecting {@link NetworkStatsHistory} for 106 * tethering traffic. 107 * 108 * @hide 109 */ 110 public static final int UID_TETHERING = NetworkStats.UID_TETHERING; 111 112 /** 113 * Tag values in this range are reserved for the network stack. The network stack is 114 * running as UID {@link android.os.Process.NETWORK_STACK_UID} when in the mainline 115 * module separate process, and as the system UID otherwise. 116 */ 117 /** @hide */ 118 @SystemApi 119 public static final int TAG_NETWORK_STACK_RANGE_START = 0xFFFFFD00; 120 /** @hide */ 121 @SystemApi 122 public static final int TAG_NETWORK_STACK_RANGE_END = 0xFFFFFEFF; 123 124 /** 125 * Tags between 0xFFFFFF00 and 0xFFFFFFFF are reserved and used internally by system services 126 * like DownloadManager when performing traffic on behalf of an application. 127 */ 128 // Please note there is no enforcement of these constants, so do not rely on them to 129 // determine that the caller is a system caller. 130 /** @hide */ 131 @SystemApi 132 public static final int TAG_SYSTEM_IMPERSONATION_RANGE_START = 0xFFFFFF00; 133 /** @hide */ 134 @SystemApi 135 public static final int TAG_SYSTEM_IMPERSONATION_RANGE_END = 0xFFFFFF0F; 136 137 /** 138 * Tag values between these ranges are reserved for the network stack to do traffic 139 * on behalf of applications. It is a subrange of the range above. 140 */ 141 /** @hide */ 142 @SystemApi 143 public static final int TAG_NETWORK_STACK_IMPERSONATION_RANGE_START = 0xFFFFFF80; 144 /** @hide */ 145 @SystemApi 146 public static final int TAG_NETWORK_STACK_IMPERSONATION_RANGE_END = 0xFFFFFF8F; 147 148 /** 149 * Default tag value for {@link DownloadManager} traffic. 150 * 151 * @hide 152 */ 153 public static final int TAG_SYSTEM_DOWNLOAD = 0xFFFFFF01; 154 155 /** 156 * Default tag value for {@link MediaPlayer} traffic. 157 * 158 * @hide 159 */ 160 public static final int TAG_SYSTEM_MEDIA = 0xFFFFFF02; 161 162 /** 163 * Default tag value for {@link BackupManager} backup traffic; that is, 164 * traffic from the device to the storage backend. 165 * 166 * @hide 167 */ 168 public static final int TAG_SYSTEM_BACKUP = 0xFFFFFF03; 169 170 /** 171 * Default tag value for {@link BackupManager} restore traffic; that is, 172 * app data retrieved from the storage backend at install time. 173 * 174 * @hide 175 */ 176 public static final int TAG_SYSTEM_RESTORE = 0xFFFFFF04; 177 178 /** 179 * Default tag value for code (typically APKs) downloaded by an app store on 180 * behalf of the app, such as updates. 181 * 182 * @hide 183 */ 184 public static final int TAG_SYSTEM_APP = 0xFFFFFF05; 185 186 // TODO : remove this constant when Wifi code is updated 187 /** @hide */ 188 public static final int TAG_SYSTEM_PROBE = 0xFFFFFF42; 189 190 private static final StatsResult EMPTY_STATS = new StatsResult(0L, 0L, 0L, 0L); 191 192 private static final Object sRateLimitCacheLock = new Object(); 193 194 @GuardedBy("TrafficStats.class") 195 @Nullable 196 private static INetworkStatsService sStatsService; 197 198 // The variable will only be accessed in the test, which is effectively 199 // single-threaded. 200 @Nullable 201 private static INetworkStatsService sStatsServiceForTest = null; 202 203 // This holds the configuration for the TrafficStats rate limit caches. 204 // It will be filled with the result of a query to the service the first time 205 // the caller invokes get*Stats APIs. 206 // This variable can be accessed from any thread with the lock held. 207 @GuardedBy("sRateLimitCacheLock") 208 @Nullable 209 private static TrafficStatsRateLimitCacheConfig sRateLimitCacheConfig; 210 211 // Cache for getIfaceStats and getTotalStats binder interfaces. 212 // This variable can be accessed from any thread with the lock held, 213 // while the cache itself is thread-safe and can be accessed outside 214 // the lock. 215 @GuardedBy("sRateLimitCacheLock") 216 @Nullable 217 private static LruCacheWithExpiry<String, StatsResult> sRateLimitIfaceCache; 218 219 // Cache for getUidStats binder interface. 220 // This variable can be accessed from any thread with the lock held, 221 // while the cache itself is thread-safe and can be accessed outside 222 // the lock. 223 @GuardedBy("sRateLimitCacheLock") 224 @Nullable 225 private static LruCacheWithExpiry<Integer, StatsResult> sRateLimitUidCache; 226 227 // The variable will only be accessed in the test, which is effectively 228 // single-threaded. 229 @Nullable 230 private static LongSupplier sTimeSupplierForTest = null; 231 232 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562) getStatsService()233 private synchronized static INetworkStatsService getStatsService() { 234 if (sStatsServiceForTest != null) return sStatsServiceForTest; 235 if (sStatsService == null) { 236 throw new IllegalStateException("TrafficStats not initialized, uid=" 237 + Binder.getCallingUid()); 238 } 239 return sStatsService; 240 } 241 242 /** @hide */ getMyUid()243 private static int getMyUid() { 244 return android.os.Process.myUid(); 245 } 246 247 /** 248 * Set the network stats service for testing, or null to reset. 249 * 250 * @hide 251 */ 252 @VisibleForTesting(visibility = PRIVATE) setServiceForTest(INetworkStatsService statsService)253 public static void setServiceForTest(INetworkStatsService statsService) { 254 sStatsServiceForTest = statsService; 255 } 256 257 /** 258 * Set time supplier for test, or null to reset. 259 * 260 * @hide 261 */ 262 @VisibleForTesting(visibility = PRIVATE) setTimeSupplierForTest(LongSupplier timeSupplier)263 public static void setTimeSupplierForTest(LongSupplier timeSupplier) { 264 sTimeSupplierForTest = timeSupplier; 265 } 266 267 /** 268 * Trigger query rate-limit cache config and initializing the caches. 269 * 270 * This is for test purpose. 271 * 272 * @hide 273 */ 274 @VisibleForTesting(visibility = PRIVATE) reinitRateLimitCacheForTest()275 public static void reinitRateLimitCacheForTest() { 276 maybeGetConfigAndInitRateLimitCache(true /* forceReinit */); 277 } 278 279 /** 280 * Snapshot of {@link NetworkStats} when the currently active profiling 281 * session started, or {@code null} if no session active. 282 * 283 * @see #startDataProfiling(Context) 284 * @see #stopDataProfiling(Context) 285 */ 286 private static NetworkStats sActiveProfilingStart; 287 288 private static Object sProfilingLock = new Object(); 289 290 private static final String LOOPBACK_IFACE = "lo"; 291 292 /** 293 * Initialization {@link TrafficStats} with the context, to 294 * allow {@link TrafficStats} to fetch the needed binder. 295 * 296 * @param context a long-lived context, such as the application context or system 297 * server context. 298 * @hide 299 */ 300 @SystemApi(client = MODULE_LIBRARIES) 301 @SuppressLint("VisiblySynchronized") init(@onNull final Context context)302 public static synchronized void init(@NonNull final Context context) { 303 if (sStatsService != null) { 304 throw new IllegalStateException("TrafficStats is already initialized, uid=" 305 + Binder.getCallingUid()); 306 } 307 final NetworkStatsManager statsManager = 308 context.getSystemService(NetworkStatsManager.class); 309 if (statsManager == null) { 310 // TODO: Currently Process.isSupplemental is not working yet, because it depends on 311 // process to run in a certain UID range, which is not true for now. Change this 312 // to Log.wtf once Process.isSupplemental is ready. 313 Log.e(TAG, "TrafficStats not initialized, uid=" + Binder.getCallingUid()); 314 return; 315 } 316 sStatsService = statsManager.getBinder(); 317 } 318 319 @Nullable maybeGetRateLimitIfaceCache()320 private static LruCacheWithExpiry<String, StatsResult> maybeGetRateLimitIfaceCache() { 321 if (!maybeGetConfigAndInitRateLimitCache(false /* forceReinit */)) return null; 322 synchronized (sRateLimitCacheLock) { 323 return sRateLimitIfaceCache; 324 } 325 } 326 327 @Nullable maybeGetRateLimitUidCache()328 private static LruCacheWithExpiry<Integer, StatsResult> maybeGetRateLimitUidCache() { 329 if (!maybeGetConfigAndInitRateLimitCache(false /* forceReinit */)) return null; 330 synchronized (sRateLimitCacheLock) { 331 return sRateLimitUidCache; 332 } 333 } 334 335 /** 336 * Gets the rate limit cache configuration and init caches if null. 337 * 338 * Gets the configuration from the service as the configuration 339 * is not expected to change dynamically. And use it to initialize 340 * rate-limit cache if not yet initialized. 341 * 342 * @return whether the rate-limit cache is enabled. 343 * 344 * @hide 345 */ maybeGetConfigAndInitRateLimitCache(boolean forceReinit)346 private static boolean maybeGetConfigAndInitRateLimitCache(boolean forceReinit) { 347 // Access the service outside the lock to avoid potential deadlocks. This is 348 // especially important when the caller is a system component (e.g., 349 // NetworkPolicyManagerService) that might hold other locks that the service 350 // also needs. 351 // Although this introduces a race condition where multiple threads might 352 // query the service concurrently, it's acceptable in this case because the 353 // configuration doesn't change dynamically. The configuration only needs to 354 // be fetched once before initializing the cache. 355 synchronized (sRateLimitCacheLock) { 356 if (sRateLimitCacheConfig != null && !forceReinit) { 357 return sRateLimitCacheConfig.isCacheEnabled; 358 } 359 } 360 361 final TrafficStatsRateLimitCacheConfig config; 362 try { 363 config = getStatsService().getRateLimitCacheConfig(); 364 } catch (RemoteException e) { 365 throw e.rethrowFromSystemServer(); 366 } 367 368 synchronized (sRateLimitCacheLock) { 369 if (sRateLimitCacheConfig == null || forceReinit) { 370 sRateLimitCacheConfig = config; 371 initRateLimitCacheLocked(); 372 } 373 } 374 return config.isCacheEnabled; 375 } 376 377 @GuardedBy("sRateLimitCacheLock") initRateLimitCacheLocked()378 private static void initRateLimitCacheLocked() { 379 // Set up rate limiting caches. 380 // Use uid cache with UID_ALL to cache total stats. 381 if (sRateLimitCacheConfig.isCacheEnabled) { 382 // A time supplier which is monotonic until device reboots, and counts 383 // time spent in sleep. This is needed to ensure the get*Stats caller 384 // won't get stale value after system time adjustment or waking up from sleep. 385 final LongSupplier realtimeSupplier = (sTimeSupplierForTest != null 386 ? sTimeSupplierForTest : () -> SystemClock.elapsedRealtime()); 387 sRateLimitIfaceCache = new LruCacheWithExpiry<String, StatsResult>( 388 realtimeSupplier, 389 sRateLimitCacheConfig.expiryDurationMs, 390 sRateLimitCacheConfig.maxEntries, 391 (statsResult) -> !isEmpty(statsResult) 392 ); 393 sRateLimitUidCache = new LruCacheWithExpiry<Integer, StatsResult>( 394 realtimeSupplier, 395 sRateLimitCacheConfig.expiryDurationMs, 396 sRateLimitCacheConfig.maxEntries, 397 (statsResult) -> !isEmpty(statsResult) 398 ); 399 } else { 400 sRateLimitIfaceCache = null; 401 sRateLimitUidCache = null; 402 } 403 } 404 405 /** 406 * Attach the socket tagger implementation to the current process, to 407 * get notified when a socket's {@link FileDescriptor} is assigned to 408 * a thread. See {@link SocketTagger#set(SocketTagger)}. 409 * 410 * @hide 411 */ 412 @SystemApi(client = MODULE_LIBRARIES) attachSocketTagger()413 public static void attachSocketTagger() { 414 dalvik.system.SocketTagger.set(new SocketTagger()); 415 } 416 417 private static class SocketTagger extends dalvik.system.SocketTagger { 418 419 // Enable log with `setprop log.tag.TrafficStats DEBUG` and restart the module. 420 private static final boolean LOGD = Log.isLoggable(TAG, Log.DEBUG); 421 SocketTagger()422 SocketTagger() { 423 } 424 425 @Override tag(FileDescriptor fd)426 public void tag(FileDescriptor fd) throws SocketException { 427 final UidTag tagInfo = sThreadUidTag.get(); 428 if (LOGD) { 429 Log.d(TAG, "tagSocket(" + fd.getInt$() + ") with statsTag=0x" 430 + Integer.toHexString(tagInfo.tag) + ", statsUid=" + tagInfo.uid); 431 } 432 if (tagInfo.tag == -1) { 433 StrictMode.noteUntaggedSocket(); 434 } 435 436 if (tagInfo.tag == -1 && tagInfo.uid == -1) return; 437 final int errno = native_tagSocketFd(fd, tagInfo.tag, tagInfo.uid); 438 if (errno < 0) { 439 Log.i(TAG, "tagSocketFd(" + fd.getInt$() + ", " 440 + tagInfo.tag + ", " 441 + tagInfo.uid + ") failed with errno" + errno); 442 } 443 } 444 445 @Override untag(FileDescriptor fd)446 public void untag(FileDescriptor fd) throws SocketException { 447 if (LOGD) { 448 Log.i(TAG, "untagSocket(" + fd.getInt$() + ")"); 449 } 450 451 final UidTag tagInfo = sThreadUidTag.get(); 452 if (tagInfo.tag == -1 && tagInfo.uid == -1) return; 453 454 final int errno = native_untagSocketFd(fd); 455 if (errno < 0) { 456 Log.w(TAG, "untagSocket(" + fd.getInt$() + ") failed with errno " + errno); 457 } 458 } 459 } 460 native_tagSocketFd(FileDescriptor fd, int tag, int uid)461 private static native int native_tagSocketFd(FileDescriptor fd, int tag, int uid); native_untagSocketFd(FileDescriptor fd)462 private static native int native_untagSocketFd(FileDescriptor fd); 463 464 private static class UidTag { 465 public int tag = -1; 466 public int uid = -1; 467 } 468 469 private static ThreadLocal<UidTag> sThreadUidTag = new ThreadLocal<UidTag>() { 470 @Override 471 protected UidTag initialValue() { 472 return new UidTag(); 473 } 474 }; 475 476 /** 477 * Set active tag to use when accounting {@link Socket} traffic originating 478 * from the current thread. Only one active tag per thread is supported. 479 * <p> 480 * Changes only take effect during subsequent calls to 481 * {@link #tagSocket(Socket)}. 482 * <p> 483 * Tags between {@code 0xFFFFFF00} and {@code 0xFFFFFFFF} are reserved and 484 * used internally by system services like {@link DownloadManager} when 485 * performing traffic on behalf of an application. 486 * 487 * @see #clearThreadStatsTag() 488 */ setThreadStatsTag(int tag)489 public static void setThreadStatsTag(int tag) { 490 getAndSetThreadStatsTag(tag); 491 } 492 493 /** 494 * Set active tag to use when accounting {@link Socket} traffic originating 495 * from the current thread. Only one active tag per thread is supported. 496 * <p> 497 * Changes only take effect during subsequent calls to 498 * {@link #tagSocket(Socket)}. 499 * <p> 500 * Tags between {@code 0xFFFFFF00} and {@code 0xFFFFFFFF} are reserved and 501 * used internally by system services like {@link DownloadManager} when 502 * performing traffic on behalf of an application. 503 * 504 * @return the current tag for the calling thread, which can be used to 505 * restore any existing values after a nested operation is finished 506 */ getAndSetThreadStatsTag(int tag)507 public static int getAndSetThreadStatsTag(int tag) { 508 final int old = sThreadUidTag.get().tag; 509 sThreadUidTag.get().tag = tag; 510 return old; 511 } 512 513 /** 514 * Set active tag to use when accounting {@link Socket} traffic originating 515 * from the current thread. The tag used internally is well-defined to 516 * distinguish all backup-related traffic. 517 * 518 * @hide 519 */ 520 @SystemApi setThreadStatsTagBackup()521 public static void setThreadStatsTagBackup() { 522 setThreadStatsTag(TAG_SYSTEM_BACKUP); 523 } 524 525 /** 526 * Set active tag to use when accounting {@link Socket} traffic originating 527 * from the current thread. The tag used internally is well-defined to 528 * distinguish all restore-related traffic. 529 * 530 * @hide 531 */ 532 @SystemApi setThreadStatsTagRestore()533 public static void setThreadStatsTagRestore() { 534 setThreadStatsTag(TAG_SYSTEM_RESTORE); 535 } 536 537 /** 538 * Set active tag to use when accounting {@link Socket} traffic originating 539 * from the current thread. The tag used internally is well-defined to 540 * distinguish all code (typically APKs) downloaded by an app store on 541 * behalf of the app, such as updates. 542 * 543 * @hide 544 */ 545 @SystemApi setThreadStatsTagApp()546 public static void setThreadStatsTagApp() { 547 setThreadStatsTag(TAG_SYSTEM_APP); 548 } 549 550 /** 551 * Set active tag to use when accounting {@link Socket} traffic originating 552 * from the current thread. The tag used internally is well-defined to 553 * distinguish all download provider traffic. 554 * 555 * @hide 556 */ 557 @SystemApi(client = MODULE_LIBRARIES) setThreadStatsTagDownload()558 public static void setThreadStatsTagDownload() { 559 setThreadStatsTag(TAG_SYSTEM_DOWNLOAD); 560 } 561 562 /** 563 * Get the active tag used when accounting {@link Socket} traffic originating 564 * from the current thread. Only one active tag per thread is supported. 565 * {@link #tagSocket(Socket)}. 566 * 567 * @see #setThreadStatsTag(int) 568 */ getThreadStatsTag()569 public static int getThreadStatsTag() { 570 return sThreadUidTag.get().tag; 571 } 572 573 /** 574 * Clear any active tag set to account {@link Socket} traffic originating 575 * from the current thread. 576 * 577 * @see #setThreadStatsTag(int) 578 */ clearThreadStatsTag()579 public static void clearThreadStatsTag() { 580 sThreadUidTag.get().tag = -1; 581 } 582 583 /** 584 * Set specific UID to use when accounting {@link Socket} traffic 585 * originating from the current thread. Designed for use when performing an 586 * operation on behalf of another application, or when another application 587 * is performing operations on your behalf. 588 * <p> 589 * Any app can <em>accept</em> blame for traffic performed on a socket 590 * originally created by another app by calling this method with the 591 * {@link android.system.Os#getuid()} value. However, only apps holding the 592 * {@code android.Manifest.permission#UPDATE_DEVICE_STATS} permission may 593 * <em>assign</em> blame to another UIDs. 594 * <p> 595 * Changes only take effect during subsequent calls to 596 * {@link #tagSocket(Socket)}. 597 */ 598 @SuppressLint("RequiresPermission") setThreadStatsUid(int uid)599 public static void setThreadStatsUid(int uid) { 600 sThreadUidTag.get().uid = uid; 601 } 602 603 /** 604 * Get the active UID used when accounting {@link Socket} traffic originating 605 * from the current thread. Only one active tag per thread is supported. 606 * {@link #tagSocket(Socket)}. 607 * 608 * @see #setThreadStatsUid(int) 609 */ getThreadStatsUid()610 public static int getThreadStatsUid() { 611 return sThreadUidTag.get().uid; 612 } 613 614 /** 615 * Set specific UID to use when accounting {@link Socket} traffic 616 * originating from the current thread as the calling UID. Designed for use 617 * when another application is performing operations on your behalf. 618 * <p> 619 * Changes only take effect during subsequent calls to 620 * {@link #tagSocket(Socket)}. 621 * 622 * @removed 623 * @deprecated use {@link #setThreadStatsUid(int)} instead. 624 */ 625 @Deprecated setThreadStatsUidSelf()626 public static void setThreadStatsUidSelf() { 627 setThreadStatsUid(getMyUid()); 628 } 629 630 /** 631 * Clear any active UID set to account {@link Socket} traffic originating 632 * from the current thread. 633 * 634 * @see #setThreadStatsUid(int) 635 */ 636 @SuppressLint("RequiresPermission") clearThreadStatsUid()637 public static void clearThreadStatsUid() { 638 setThreadStatsUid(-1); 639 } 640 641 /** 642 * Tag the given {@link Socket} with any statistics parameters active for 643 * the current thread. Subsequent calls always replace any existing 644 * parameters. When finished, call {@link #untagSocket(Socket)} to remove 645 * statistics parameters. 646 * 647 * @see #setThreadStatsTag(int) 648 */ tagSocket(@onNull Socket socket)649 public static void tagSocket(@NonNull Socket socket) throws SocketException { 650 SocketTagger.get().tag(socket); 651 } 652 653 /** 654 * Remove any statistics parameters from the given {@link Socket}. 655 * <p> 656 * In Android 8.1 (API level 27) and lower, a socket is automatically 657 * untagged when it's sent to another process using binder IPC with a 658 * {@code ParcelFileDescriptor} container. In Android 9.0 (API level 28) 659 * and higher, the socket tag is kept when the socket is sent to another 660 * process using binder IPC. You can mimic the previous behavior by 661 * calling {@code untagSocket()} before sending the socket to another 662 * process. 663 */ untagSocket(@onNull Socket socket)664 public static void untagSocket(@NonNull Socket socket) throws SocketException { 665 SocketTagger.get().untag(socket); 666 } 667 668 /** 669 * Tag the given {@link DatagramSocket} with any statistics parameters 670 * active for the current thread. Subsequent calls always replace any 671 * existing parameters. When finished, call 672 * {@link #untagDatagramSocket(DatagramSocket)} to remove statistics 673 * parameters. 674 * 675 * @see #setThreadStatsTag(int) 676 */ tagDatagramSocket(@onNull DatagramSocket socket)677 public static void tagDatagramSocket(@NonNull DatagramSocket socket) throws SocketException { 678 SocketTagger.get().tag(socket); 679 } 680 681 /** 682 * Remove any statistics parameters from the given {@link DatagramSocket}. 683 */ untagDatagramSocket(@onNull DatagramSocket socket)684 public static void untagDatagramSocket(@NonNull DatagramSocket socket) throws SocketException { 685 SocketTagger.get().untag(socket); 686 } 687 688 /** 689 * Tag the given {@link FileDescriptor} socket with any statistics 690 * parameters active for the current thread. Subsequent calls always replace 691 * any existing parameters. When finished, call 692 * {@link #untagFileDescriptor(FileDescriptor)} to remove statistics 693 * parameters. 694 * 695 * @see #setThreadStatsTag(int) 696 */ tagFileDescriptor(@onNull FileDescriptor fd)697 public static void tagFileDescriptor(@NonNull FileDescriptor fd) throws IOException { 698 SocketTagger.get().tag(fd); 699 } 700 701 /** 702 * Remove any statistics parameters from the given {@link FileDescriptor} 703 * socket. 704 */ untagFileDescriptor(@onNull FileDescriptor fd)705 public static void untagFileDescriptor(@NonNull FileDescriptor fd) throws IOException { 706 SocketTagger.get().untag(fd); 707 } 708 709 /** 710 * Start profiling data usage for current UID. Only one profiling session 711 * can be active at a time. 712 * 713 * @hide 714 */ startDataProfiling(Context context)715 public static void startDataProfiling(Context context) { 716 synchronized (sProfilingLock) { 717 if (sActiveProfilingStart != null) { 718 throw new IllegalStateException("already profiling data"); 719 } 720 721 // take snapshot in time; we calculate delta later 722 sActiveProfilingStart = getDataLayerSnapshotForUid(context); 723 } 724 } 725 726 /** 727 * Stop profiling data usage for current UID. 728 * 729 * @return Detailed {@link NetworkStats} of data that occurred since last 730 * {@link #startDataProfiling(Context)} call. 731 * @hide 732 */ stopDataProfiling(Context context)733 public static NetworkStats stopDataProfiling(Context context) { 734 synchronized (sProfilingLock) { 735 if (sActiveProfilingStart == null) { 736 throw new IllegalStateException("not profiling data"); 737 } 738 739 // subtract starting values and return delta 740 final NetworkStats profilingStop = getDataLayerSnapshotForUid(context); 741 final NetworkStats profilingDelta = NetworkStats.subtract( 742 profilingStop, sActiveProfilingStart, null, null); 743 sActiveProfilingStart = null; 744 return profilingDelta; 745 } 746 } 747 748 /** 749 * Increment count of network operations performed under the accounting tag 750 * currently active on the calling thread. This can be used to derive 751 * bytes-per-operation. 752 * 753 * @param operationCount Number of operations to increment count by. 754 */ incrementOperationCount(int operationCount)755 public static void incrementOperationCount(int operationCount) { 756 final int tag = getThreadStatsTag(); 757 incrementOperationCount(tag, operationCount); 758 } 759 760 /** 761 * Increment count of network operations performed under the given 762 * accounting tag. This can be used to derive bytes-per-operation. 763 * 764 * @param tag Accounting tag used in {@link #setThreadStatsTag(int)}. 765 * @param operationCount Number of operations to increment count by. 766 */ incrementOperationCount(int tag, int operationCount)767 public static void incrementOperationCount(int tag, int operationCount) { 768 final int uid = getMyUid(); 769 try { 770 getStatsService().incrementOperationCount(uid, tag, operationCount); 771 } catch (RemoteException e) { 772 throw e.rethrowFromSystemServer(); 773 } 774 } 775 776 /** {@hide} */ closeQuietly(INetworkStatsSession session)777 public static void closeQuietly(INetworkStatsSession session) { 778 // TODO: move to NetworkStatsService once it exists 779 if (session != null) { 780 try { 781 session.close(); 782 } catch (RuntimeException rethrown) { 783 throw rethrown; 784 } catch (Exception ignored) { 785 } 786 } 787 } 788 addIfSupported(long stat)789 private static long addIfSupported(long stat) { 790 return (stat == UNSUPPORTED) ? 0 : stat; 791 } 792 793 /** 794 * Return number of packets transmitted across mobile networks since device 795 * boot. Counts packets across all mobile network interfaces, and always 796 * increases monotonically since device boot. Statistics are measured at the 797 * network layer, so they include both TCP and UDP usage. 798 * <p> 799 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may 800 * return {@link #UNSUPPORTED} on devices where statistics aren't available. 801 */ getMobileTxPackets()802 public static long getMobileTxPackets() { 803 long total = 0; 804 for (String iface : getMobileIfaces()) { 805 total += addIfSupported(getTxPackets(iface)); 806 } 807 return total; 808 } 809 810 /** 811 * Return number of packets received across mobile networks since device 812 * boot. Counts packets across all mobile network interfaces, and always 813 * increases monotonically since device boot. Statistics are measured at the 814 * network layer, so they include both TCP and UDP usage. 815 * <p> 816 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may 817 * return {@link #UNSUPPORTED} on devices where statistics aren't available. 818 */ getMobileRxPackets()819 public static long getMobileRxPackets() { 820 long total = 0; 821 for (String iface : getMobileIfaces()) { 822 total += addIfSupported(getRxPackets(iface)); 823 } 824 return total; 825 } 826 827 /** 828 * Return number of bytes transmitted across mobile networks since device 829 * boot. Counts packets across all mobile network interfaces, and always 830 * increases monotonically since device boot. Statistics are measured at the 831 * network layer, so they include both TCP and UDP usage. 832 * <p> 833 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may 834 * return {@link #UNSUPPORTED} on devices where statistics aren't available. 835 */ getMobileTxBytes()836 public static long getMobileTxBytes() { 837 long total = 0; 838 for (String iface : getMobileIfaces()) { 839 total += addIfSupported(getTxBytes(iface)); 840 } 841 return total; 842 } 843 844 /** 845 * Return number of bytes received across mobile networks since device boot. 846 * Counts packets across all mobile network interfaces, and always increases 847 * monotonically since device boot. Statistics are measured at the network 848 * layer, so they include both TCP and UDP usage. 849 * <p> 850 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may 851 * return {@link #UNSUPPORTED} on devices where statistics aren't available. 852 */ getMobileRxBytes()853 public static long getMobileRxBytes() { 854 long total = 0; 855 for (String iface : getMobileIfaces()) { 856 total += addIfSupported(getRxBytes(iface)); 857 } 858 return total; 859 } 860 861 /** {@hide} */ 862 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getMobileTcpRxPackets()863 public static long getMobileTcpRxPackets() { 864 return UNSUPPORTED; 865 } 866 867 /** {@hide} */ 868 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getMobileTcpTxPackets()869 public static long getMobileTcpTxPackets() { 870 return UNSUPPORTED; 871 } 872 873 /** Clear TrafficStats rate-limit caches. 874 * 875 * This is mainly for {@link com.android.server.net.NetworkStatsService} to 876 * clear rate-limit cache to avoid caching for TrafficStats API results. 877 * Tests might get stale values after generating network traffic, which 878 * generally need to wait for cache expiry to get updated values. 879 * 880 * @hide 881 */ 882 @RequiresPermission(anyOf = { 883 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, 884 android.Manifest.permission.NETWORK_STACK, 885 android.Manifest.permission.NETWORK_SETTINGS}) clearRateLimitCaches()886 public static void clearRateLimitCaches() { 887 final LruCacheWithExpiry<String, StatsResult> ifaceCache = maybeGetRateLimitIfaceCache(); 888 if (ifaceCache != null) { 889 ifaceCache.clear(); 890 } 891 final LruCacheWithExpiry<Integer, StatsResult> uidCache = maybeGetRateLimitUidCache(); 892 if (uidCache != null) { 893 uidCache.clear(); 894 } 895 try { 896 getStatsService().clearTrafficStatsRateLimitCaches(); 897 } catch (RemoteException e) { 898 throw e.rethrowFromSystemServer(); 899 } 900 } 901 902 /** 903 * Return the number of packets transmitted on the specified interface since the interface 904 * was created. Statistics are measured at the network layer, so both TCP and 905 * UDP usage are included. 906 * 907 * Note that the returned values are partial statistics that do not count data from several 908 * sources and do not apply several adjustments that are necessary for correctness, such 909 * as adjusting for VPN apps, IPv6-in-IPv4 translation, etc. These values can be used to 910 * determine whether traffic is being transferred on the specific interface but are not a 911 * substitute for the more accurate statistics provided by the {@link NetworkStatsManager} 912 * APIs. 913 * 914 * @param iface The name of the interface. 915 * @return The number of transmitted packets. 916 */ getTxPackets(@onNull String iface)917 public static long getTxPackets(@NonNull String iface) { 918 return getIfaceStats(iface, TYPE_TX_PACKETS); 919 } 920 921 /** 922 * Return the number of packets received on the specified interface since the interface was 923 * created. Statistics are measured at the network layer, so both TCP 924 * and UDP usage are included. 925 * 926 * Note that the returned values are partial statistics that do not count data from several 927 * sources and do not apply several adjustments that are necessary for correctness, such 928 * as adjusting for VPN apps, IPv6-in-IPv4 translation, etc. These values can be used to 929 * determine whether traffic is being transferred on the specific interface but are not a 930 * substitute for the more accurate statistics provided by the {@link NetworkStatsManager} 931 * APIs. 932 * 933 * @param iface The name of the interface. 934 * @return The number of received packets. 935 */ getRxPackets(@onNull String iface)936 public static long getRxPackets(@NonNull String iface) { 937 return getIfaceStats(iface, TYPE_RX_PACKETS); 938 } 939 940 /** 941 * Return the number of bytes transmitted on the specified interface since the interface 942 * was created. Statistics are measured at the network layer, so both TCP and 943 * UDP usage are included. 944 * 945 * Note that the returned values are partial statistics that do not count data from several 946 * sources and do not apply several adjustments that are necessary for correctness, such 947 * as adjusting for VPN apps, IPv6-in-IPv4 translation, etc. These values can be used to 948 * determine whether traffic is being transferred on the specific interface but are not a 949 * substitute for the more accurate statistics provided by the {@link NetworkStatsManager} 950 * APIs. 951 * 952 * @param iface The name of the interface. 953 * @return The number of transmitted bytes. 954 */ getTxBytes(@onNull String iface)955 public static long getTxBytes(@NonNull String iface) { 956 return getIfaceStats(iface, TYPE_TX_BYTES); 957 } 958 959 /** 960 * Return the number of bytes received on the specified interface since the interface 961 * was created. Statistics are measured at the network layer, so both TCP 962 * and UDP usage are included. 963 * 964 * Note that the returned values are partial statistics that do not count data from several 965 * sources and do not apply several adjustments that are necessary for correctness, such 966 * as adjusting for VPN apps, IPv6-in-IPv4 translation, etc. These values can be used to 967 * determine whether traffic is being transferred on the specific interface but are not a 968 * substitute for the more accurate statistics provided by the {@link NetworkStatsManager} 969 * APIs. 970 * 971 * @param iface The name of the interface. 972 * @return The number of received bytes. 973 */ getRxBytes(@onNull String iface)974 public static long getRxBytes(@NonNull String iface) { 975 return getIfaceStats(iface, TYPE_RX_BYTES); 976 } 977 978 /** {@hide} */ 979 @TestApi getLoopbackTxPackets()980 public static long getLoopbackTxPackets() { 981 return getIfaceStats(LOOPBACK_IFACE, TYPE_TX_PACKETS); 982 } 983 984 /** {@hide} */ 985 @TestApi getLoopbackRxPackets()986 public static long getLoopbackRxPackets() { 987 return getIfaceStats(LOOPBACK_IFACE, TYPE_RX_PACKETS); 988 } 989 990 /** {@hide} */ 991 @TestApi getLoopbackTxBytes()992 public static long getLoopbackTxBytes() { 993 return getIfaceStats(LOOPBACK_IFACE, TYPE_TX_BYTES); 994 } 995 996 /** {@hide} */ 997 @TestApi getLoopbackRxBytes()998 public static long getLoopbackRxBytes() { 999 return getIfaceStats(LOOPBACK_IFACE, TYPE_RX_BYTES); 1000 } 1001 1002 /** 1003 * Return number of packets transmitted since device boot. Counts packets 1004 * across all network interfaces, and always increases monotonically since 1005 * device boot. Statistics are measured at the network layer, so they 1006 * include both TCP and UDP usage. 1007 * <p> 1008 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may 1009 * return {@link #UNSUPPORTED} on devices where statistics aren't available. 1010 */ getTotalTxPackets()1011 public static long getTotalTxPackets() { 1012 return getTotalStats(TYPE_TX_PACKETS); 1013 } 1014 1015 /** 1016 * Return number of packets received since device boot. Counts packets 1017 * across all network interfaces, and always increases monotonically since 1018 * device boot. Statistics are measured at the network layer, so they 1019 * include both TCP and UDP usage. 1020 * <p> 1021 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may 1022 * return {@link #UNSUPPORTED} on devices where statistics aren't available. 1023 */ getTotalRxPackets()1024 public static long getTotalRxPackets() { 1025 return getTotalStats(TYPE_RX_PACKETS); 1026 } 1027 1028 /** 1029 * Return number of bytes transmitted since device boot. Counts packets 1030 * across all network interfaces, and always increases monotonically since 1031 * device boot. Statistics are measured at the network layer, so they 1032 * include both TCP and UDP usage. 1033 * <p> 1034 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may 1035 * return {@link #UNSUPPORTED} on devices where statistics aren't available. 1036 */ getTotalTxBytes()1037 public static long getTotalTxBytes() { 1038 return getTotalStats(TYPE_TX_BYTES); 1039 } 1040 1041 /** 1042 * Return number of bytes received since device boot. Counts packets across 1043 * all network interfaces, and always increases monotonically since device 1044 * boot. Statistics are measured at the network layer, so they include both 1045 * TCP and UDP usage. 1046 * <p> 1047 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may 1048 * return {@link #UNSUPPORTED} on devices where statistics aren't available. 1049 */ getTotalRxBytes()1050 public static long getTotalRxBytes() { 1051 return getTotalStats(TYPE_RX_BYTES); 1052 } 1053 1054 /** 1055 * Return number of bytes transmitted by the given UID since device boot. 1056 * Counts packets across all network interfaces, and always increases 1057 * monotonically since device boot. Statistics are measured at the network 1058 * layer, so they include both TCP and UDP usage. 1059 * <p> 1060 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may 1061 * return {@link #UNSUPPORTED} on devices where statistics aren't available. 1062 * <p> 1063 * Starting in {@link android.os.Build.VERSION_CODES#N} this will only 1064 * report traffic statistics for the calling UID. It will return 1065 * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access 1066 * historical network statistics belonging to other UIDs, use 1067 * {@link NetworkStatsManager}. 1068 * 1069 * @see android.os.Process#myUid() 1070 * @see android.content.pm.ApplicationInfo#uid 1071 */ getUidTxBytes(int uid)1072 public static long getUidTxBytes(int uid) { 1073 return getUidStats(uid, TYPE_TX_BYTES); 1074 } 1075 1076 /** 1077 * Return number of bytes received by the given UID since device boot. 1078 * Counts packets across all network interfaces, and always increases 1079 * monotonically since device boot. Statistics are measured at the network 1080 * layer, so they include both TCP and UDP usage. 1081 * <p> 1082 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return 1083 * {@link #UNSUPPORTED} on devices where statistics aren't available. 1084 * <p> 1085 * Starting in {@link android.os.Build.VERSION_CODES#N} this will only 1086 * report traffic statistics for the calling UID. It will return 1087 * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access 1088 * historical network statistics belonging to other UIDs, use 1089 * {@link NetworkStatsManager}. 1090 * 1091 * @see android.os.Process#myUid() 1092 * @see android.content.pm.ApplicationInfo#uid 1093 */ getUidRxBytes(int uid)1094 public static long getUidRxBytes(int uid) { 1095 return getUidStats(uid, TYPE_RX_BYTES); 1096 } 1097 1098 /** 1099 * Return number of packets transmitted by the given UID since device boot. 1100 * Counts packets across all network interfaces, and always increases 1101 * monotonically since device boot. Statistics are measured at the network 1102 * layer, so they include both TCP and UDP usage. 1103 * <p> 1104 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return 1105 * {@link #UNSUPPORTED} on devices where statistics aren't available. 1106 * <p> 1107 * Starting in {@link android.os.Build.VERSION_CODES#N} this will only 1108 * report traffic statistics for the calling UID. It will return 1109 * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access 1110 * historical network statistics belonging to other UIDs, use 1111 * {@link NetworkStatsManager}. 1112 * 1113 * @see android.os.Process#myUid() 1114 * @see android.content.pm.ApplicationInfo#uid 1115 */ getUidTxPackets(int uid)1116 public static long getUidTxPackets(int uid) { 1117 return getUidStats(uid, TYPE_TX_PACKETS); 1118 } 1119 1120 /** 1121 * Return number of packets received by the given UID since device boot. 1122 * Counts packets across all network interfaces, and always increases 1123 * monotonically since device boot. Statistics are measured at the network 1124 * layer, so they include both TCP and UDP usage. 1125 * <p> 1126 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return 1127 * {@link #UNSUPPORTED} on devices where statistics aren't available. 1128 * <p> 1129 * Starting in {@link android.os.Build.VERSION_CODES#N} this will only 1130 * report traffic statistics for the calling UID. It will return 1131 * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access 1132 * historical network statistics belonging to other UIDs, use 1133 * {@link NetworkStatsManager}. 1134 * 1135 * @see android.os.Process#myUid() 1136 * @see android.content.pm.ApplicationInfo#uid 1137 */ getUidRxPackets(int uid)1138 public static long getUidRxPackets(int uid) { 1139 return getUidStats(uid, TYPE_RX_PACKETS); 1140 } 1141 1142 /** @hide */ getUidStats(int uid, int type)1143 public static long getUidStats(int uid, int type) { 1144 return fetchStats(maybeGetRateLimitUidCache(), uid, 1145 () -> getStatsService().getUidStats(uid), type); 1146 } 1147 1148 // Note: This method calls to the service, do not invoke this method with lock held. fetchStats( @ullable LruCacheWithExpiry<K, StatsResult> cache, K key, BinderUtils.ThrowingSupplier<StatsResult, RemoteException> statsFetcher, int type)1149 private static <K> long fetchStats( 1150 @Nullable LruCacheWithExpiry<K, StatsResult> cache, K key, 1151 BinderUtils.ThrowingSupplier<StatsResult, RemoteException> statsFetcher, int type) { 1152 try { 1153 final StatsResult stats; 1154 if (cache != null) { 1155 stats = fetchStatsWithCache(cache, key, statsFetcher); 1156 } else { 1157 // Cache is not enabled, fetch directly from service. 1158 stats = statsFetcher.get(); 1159 } 1160 return getEntryValueForType(stats, type); 1161 } catch (RemoteException e) { 1162 throw e.rethrowFromSystemServer(); 1163 } 1164 } 1165 1166 // Note: This method calls to the service, do not invoke this method with lock held. 1167 @Nullable fetchStatsWithCache(LruCacheWithExpiry<K, StatsResult> cache, K key, BinderUtils.ThrowingSupplier<StatsResult, RemoteException> statsFetcher)1168 private static <K> StatsResult fetchStatsWithCache(LruCacheWithExpiry<K, StatsResult> cache, 1169 K key, BinderUtils.ThrowingSupplier<StatsResult, RemoteException> statsFetcher) 1170 throws RemoteException { 1171 // Attempt to retrieve from the cache first. 1172 StatsResult stats = cache.get(key); 1173 1174 // Although the cache instance is thread-safe, this can still introduce a 1175 // race condition between threads of the same process, potentially 1176 // returning non-monotonic results. This is because there is no lock 1177 // between get, fetch, and put operations. This is considered acceptable 1178 // because varying thread execution speeds can also cause non-monotonic 1179 // results, even with locking. 1180 if (stats == null) { 1181 // Cache miss, fetch from the service. 1182 stats = statsFetcher.get(); 1183 1184 // Update the cache with the fetched result if valid. 1185 if (stats != null && !isEmpty(stats)) { 1186 final StatsResult cachedValue = cache.putIfAbsent(key, stats); 1187 if (cachedValue != null) { 1188 // Some other thread cached a value after this thread 1189 // originally got a cache miss. Return the cached value 1190 // to ensure all returned values after caching are consistent. 1191 return cachedValue; 1192 } 1193 } 1194 } 1195 return stats; 1196 } 1197 isEmpty(StatsResult stats)1198 private static boolean isEmpty(StatsResult stats) { 1199 return stats.equals(EMPTY_STATS); 1200 } 1201 1202 /** @hide */ getTotalStats(int type)1203 public static long getTotalStats(int type) { 1204 // In practice, Bpf doesn't use UID_ALL for storing per-UID stats. 1205 // Use uid cache with UID_ALL to cache total stats. 1206 return fetchStats(maybeGetRateLimitUidCache(), UID_ALL, 1207 () -> getStatsService().getTotalStats(), type); 1208 } 1209 1210 /** @hide */ getIfaceStats(String iface, int type)1211 public static long getIfaceStats(String iface, int type) { 1212 return fetchStats(maybeGetRateLimitIfaceCache(), iface, 1213 () -> getStatsService().getIfaceStats(iface), type); 1214 } 1215 1216 /** 1217 * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, 1218 * transport layer statistics are no longer available, and will 1219 * always return {@link #UNSUPPORTED}. 1220 * @see #getUidTxBytes(int) 1221 */ 1222 @Deprecated getUidTcpTxBytes(int uid)1223 public static long getUidTcpTxBytes(int uid) { 1224 return UNSUPPORTED; 1225 } 1226 1227 /** 1228 * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, 1229 * transport layer statistics are no longer available, and will 1230 * always return {@link #UNSUPPORTED}. 1231 * @see #getUidRxBytes(int) 1232 */ 1233 @Deprecated getUidTcpRxBytes(int uid)1234 public static long getUidTcpRxBytes(int uid) { 1235 return UNSUPPORTED; 1236 } 1237 1238 /** 1239 * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, 1240 * transport layer statistics are no longer available, and will 1241 * always return {@link #UNSUPPORTED}. 1242 * @see #getUidTxBytes(int) 1243 */ 1244 @Deprecated getUidUdpTxBytes(int uid)1245 public static long getUidUdpTxBytes(int uid) { 1246 return UNSUPPORTED; 1247 } 1248 1249 /** 1250 * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, 1251 * transport layer statistics are no longer available, and will 1252 * always return {@link #UNSUPPORTED}. 1253 * @see #getUidRxBytes(int) 1254 */ 1255 @Deprecated getUidUdpRxBytes(int uid)1256 public static long getUidUdpRxBytes(int uid) { 1257 return UNSUPPORTED; 1258 } 1259 1260 /** 1261 * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, 1262 * transport layer statistics are no longer available, and will 1263 * always return {@link #UNSUPPORTED}. 1264 * @see #getUidTxPackets(int) 1265 */ 1266 @Deprecated getUidTcpTxSegments(int uid)1267 public static long getUidTcpTxSegments(int uid) { 1268 return UNSUPPORTED; 1269 } 1270 1271 /** 1272 * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, 1273 * transport layer statistics are no longer available, and will 1274 * always return {@link #UNSUPPORTED}. 1275 * @see #getUidRxPackets(int) 1276 */ 1277 @Deprecated getUidTcpRxSegments(int uid)1278 public static long getUidTcpRxSegments(int uid) { 1279 return UNSUPPORTED; 1280 } 1281 1282 /** 1283 * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, 1284 * transport layer statistics are no longer available, and will 1285 * always return {@link #UNSUPPORTED}. 1286 * @see #getUidTxPackets(int) 1287 */ 1288 @Deprecated getUidUdpTxPackets(int uid)1289 public static long getUidUdpTxPackets(int uid) { 1290 return UNSUPPORTED; 1291 } 1292 1293 /** 1294 * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, 1295 * transport layer statistics are no longer available, and will 1296 * always return {@link #UNSUPPORTED}. 1297 * @see #getUidRxPackets(int) 1298 */ 1299 @Deprecated getUidUdpRxPackets(int uid)1300 public static long getUidUdpRxPackets(int uid) { 1301 return UNSUPPORTED; 1302 } 1303 1304 /** 1305 * Return detailed {@link NetworkStats} for the current UID. Requires no 1306 * special permission. 1307 */ getDataLayerSnapshotForUid(Context context)1308 private static NetworkStats getDataLayerSnapshotForUid(Context context) { 1309 // TODO: take snapshot locally, since proc file is now visible 1310 final int uid = getMyUid(); 1311 try { 1312 return getStatsService().getDataLayerSnapshotForUid(uid); 1313 } catch (RemoteException e) { 1314 throw e.rethrowFromSystemServer(); 1315 } 1316 } 1317 1318 /** 1319 * Return set of any ifaces associated with mobile networks since boot. 1320 * Interfaces are never removed from this list, so counters should always be 1321 * monotonic. 1322 */ 1323 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562) getMobileIfaces()1324 private static String[] getMobileIfaces() { 1325 try { 1326 return getStatsService().getMobileIfaces(); 1327 } catch (RemoteException e) { 1328 throw e.rethrowFromSystemServer(); 1329 } 1330 } 1331 1332 // NOTE: keep these in sync with {@code com_android_server_net_NetworkStatsService.cpp}. 1333 /** {@hide} */ 1334 public static final int TYPE_RX_BYTES = 0; 1335 /** {@hide} */ 1336 public static final int TYPE_RX_PACKETS = 1; 1337 /** {@hide} */ 1338 public static final int TYPE_TX_BYTES = 2; 1339 /** {@hide} */ 1340 public static final int TYPE_TX_PACKETS = 3; 1341 1342 /** @hide */ getEntryValueForType(@ullable StatsResult stats, int type)1343 private static long getEntryValueForType(@Nullable StatsResult stats, int type) { 1344 if (stats == null) return UNSUPPORTED; 1345 if (!isEntryValueTypeValid(type)) return UNSUPPORTED; 1346 switch (type) { 1347 case TYPE_RX_BYTES: 1348 return stats.rxBytes; 1349 case TYPE_RX_PACKETS: 1350 return stats.rxPackets; 1351 case TYPE_TX_BYTES: 1352 return stats.txBytes; 1353 case TYPE_TX_PACKETS: 1354 return stats.txPackets; 1355 default: 1356 throw new IllegalStateException("Bug: Invalid type: " 1357 + type + " should not reach here."); 1358 } 1359 } 1360 1361 /** @hide */ isEntryValueTypeValid(int type)1362 private static boolean isEntryValueTypeValid(int type) { 1363 switch (type) { 1364 case TYPE_RX_BYTES: 1365 case TYPE_RX_PACKETS: 1366 case TYPE_TX_BYTES: 1367 case TYPE_TX_PACKETS: 1368 return true; 1369 default : 1370 return false; 1371 } 1372 } 1373 } 1374 1375