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