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 android.annotation.SystemApi; 20 import android.app.DownloadManager; 21 import android.app.backup.BackupManager; 22 import android.content.Context; 23 import android.media.MediaPlayer; 24 import android.os.RemoteException; 25 import android.os.ServiceManager; 26 27 import com.android.server.NetworkManagementSocketTagger; 28 29 import dalvik.system.SocketTagger; 30 31 import java.net.Socket; 32 import java.net.SocketException; 33 34 /** 35 * Class that provides network traffic statistics. These statistics include 36 * bytes transmitted and received and network packets transmitted and received, 37 * over all interfaces, over the mobile interface, and on a per-UID basis. 38 * <p> 39 * These statistics may not be available on all platforms. If the statistics 40 * are not supported by this device, {@link #UNSUPPORTED} will be returned. 41 */ 42 public class TrafficStats { 43 /** 44 * The return value to indicate that the device does not support the statistic. 45 */ 46 public final static int UNSUPPORTED = -1; 47 48 /** @hide */ 49 public static final long KB_IN_BYTES = 1024; 50 /** @hide */ 51 public static final long MB_IN_BYTES = KB_IN_BYTES * 1024; 52 /** @hide */ 53 public static final long GB_IN_BYTES = MB_IN_BYTES * 1024; 54 /** @hide */ 55 public static final long TB_IN_BYTES = GB_IN_BYTES * 1024; 56 /** @hide */ 57 public static final long PB_IN_BYTES = TB_IN_BYTES * 1024; 58 59 /** 60 * Special UID value used when collecting {@link NetworkStatsHistory} for 61 * removed applications. 62 * 63 * @hide 64 */ 65 public static final int UID_REMOVED = -4; 66 67 /** 68 * Special UID value used when collecting {@link NetworkStatsHistory} for 69 * tethering traffic. 70 * 71 * @hide 72 */ 73 public static final int UID_TETHERING = -5; 74 75 /** 76 * Default tag value for {@link DownloadManager} traffic. 77 * 78 * @hide 79 */ 80 public static final int TAG_SYSTEM_DOWNLOAD = 0xFFFFFF01; 81 82 /** 83 * Default tag value for {@link MediaPlayer} traffic. 84 * 85 * @hide 86 */ 87 public static final int TAG_SYSTEM_MEDIA = 0xFFFFFF02; 88 89 /** 90 * Default tag value for {@link BackupManager} traffic. 91 * 92 * @hide 93 */ 94 public static final int TAG_SYSTEM_BACKUP = 0xFFFFFF03; 95 96 private static INetworkStatsService sStatsService; 97 98 private synchronized static INetworkStatsService getStatsService() { 99 if (sStatsService == null) { 100 sStatsService = INetworkStatsService.Stub.asInterface( 101 ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); 102 } 103 return sStatsService; 104 } 105 106 /** 107 * Snapshot of {@link NetworkStats} when the currently active profiling 108 * session started, or {@code null} if no session active. 109 * 110 * @see #startDataProfiling(Context) 111 * @see #stopDataProfiling(Context) 112 */ 113 private static NetworkStats sActiveProfilingStart; 114 115 private static Object sProfilingLock = new Object(); 116 117 /** 118 * Set active tag to use when accounting {@link Socket} traffic originating 119 * from the current thread. Only one active tag per thread is supported. 120 * <p> 121 * Changes only take effect during subsequent calls to 122 * {@link #tagSocket(Socket)}. 123 * <p> 124 * Tags between {@code 0xFFFFFF00} and {@code 0xFFFFFFFF} are reserved and 125 * used internally by system services like {@link DownloadManager} when 126 * performing traffic on behalf of an application. 127 * 128 * @see #clearThreadStatsTag() 129 */ 130 public static void setThreadStatsTag(int tag) { 131 NetworkManagementSocketTagger.setThreadSocketStatsTag(tag); 132 } 133 134 /** 135 * System API for backup-related support components to tag network traffic 136 * appropriately. 137 * @hide 138 */ 139 @SystemApi 140 public static void setThreadStatsTagBackup() { 141 setThreadStatsTag(TAG_SYSTEM_BACKUP); 142 } 143 144 /** 145 * Get the active tag used when accounting {@link Socket} traffic originating 146 * from the current thread. Only one active tag per thread is supported. 147 * {@link #tagSocket(Socket)}. 148 * 149 * @see #setThreadStatsTag(int) 150 */ 151 public static int getThreadStatsTag() { 152 return NetworkManagementSocketTagger.getThreadSocketStatsTag(); 153 } 154 155 /** 156 * Clear any active tag set to account {@link Socket} traffic originating 157 * from the current thread. 158 * 159 * @see #setThreadStatsTag(int) 160 */ 161 public static void clearThreadStatsTag() { 162 NetworkManagementSocketTagger.setThreadSocketStatsTag(-1); 163 } 164 165 /** 166 * Set specific UID to use when accounting {@link Socket} traffic 167 * originating from the current thread. Designed for use when performing an 168 * operation on behalf of another application. 169 * <p> 170 * Changes only take effect during subsequent calls to 171 * {@link #tagSocket(Socket)}. 172 * <p> 173 * To take effect, caller must hold 174 * {@link android.Manifest.permission#UPDATE_DEVICE_STATS} permission. 175 * 176 * @hide 177 */ 178 @SystemApi 179 public static void setThreadStatsUid(int uid) { 180 NetworkManagementSocketTagger.setThreadSocketStatsUid(uid); 181 } 182 183 /** {@hide} */ 184 @SystemApi 185 public static void clearThreadStatsUid() { 186 NetworkManagementSocketTagger.setThreadSocketStatsUid(-1); 187 } 188 189 /** 190 * Tag the given {@link Socket} with any statistics parameters active for 191 * the current thread. Subsequent calls always replace any existing 192 * parameters. When finished, call {@link #untagSocket(Socket)} to remove 193 * statistics parameters. 194 * 195 * @see #setThreadStatsTag(int) 196 * @see #setThreadStatsUid(int) 197 */ 198 public static void tagSocket(Socket socket) throws SocketException { 199 SocketTagger.get().tag(socket); 200 } 201 202 /** 203 * Remove any statistics parameters from the given {@link Socket}. 204 */ 205 public static void untagSocket(Socket socket) throws SocketException { 206 SocketTagger.get().untag(socket); 207 } 208 209 /** 210 * Start profiling data usage for current UID. Only one profiling session 211 * can be active at a time. 212 * 213 * @hide 214 */ 215 public static void startDataProfiling(Context context) { 216 synchronized (sProfilingLock) { 217 if (sActiveProfilingStart != null) { 218 throw new IllegalStateException("already profiling data"); 219 } 220 221 // take snapshot in time; we calculate delta later 222 sActiveProfilingStart = getDataLayerSnapshotForUid(context); 223 } 224 } 225 226 /** 227 * Stop profiling data usage for current UID. 228 * 229 * @return Detailed {@link NetworkStats} of data that occurred since last 230 * {@link #startDataProfiling(Context)} call. 231 * @hide 232 */ 233 public static NetworkStats stopDataProfiling(Context context) { 234 synchronized (sProfilingLock) { 235 if (sActiveProfilingStart == null) { 236 throw new IllegalStateException("not profiling data"); 237 } 238 239 // subtract starting values and return delta 240 final NetworkStats profilingStop = getDataLayerSnapshotForUid(context); 241 final NetworkStats profilingDelta = NetworkStats.subtract( 242 profilingStop, sActiveProfilingStart, null, null); 243 sActiveProfilingStart = null; 244 return profilingDelta; 245 } 246 } 247 248 /** 249 * Increment count of network operations performed under the accounting tag 250 * currently active on the calling thread. This can be used to derive 251 * bytes-per-operation. 252 * 253 * @param operationCount Number of operations to increment count by. 254 */ 255 public static void incrementOperationCount(int operationCount) { 256 final int tag = getThreadStatsTag(); 257 incrementOperationCount(tag, operationCount); 258 } 259 260 /** 261 * Increment count of network operations performed under the given 262 * accounting tag. This can be used to derive bytes-per-operation. 263 * 264 * @param tag Accounting tag used in {@link #setThreadStatsTag(int)}. 265 * @param operationCount Number of operations to increment count by. 266 */ 267 public static void incrementOperationCount(int tag, int operationCount) { 268 final int uid = android.os.Process.myUid(); 269 try { 270 getStatsService().incrementOperationCount(uid, tag, operationCount); 271 } catch (RemoteException e) { 272 throw new RuntimeException(e); 273 } 274 } 275 276 /** {@hide} */ 277 public static void closeQuietly(INetworkStatsSession session) { 278 // TODO: move to NetworkStatsService once it exists 279 if (session != null) { 280 try { 281 session.close(); 282 } catch (RuntimeException rethrown) { 283 throw rethrown; 284 } catch (Exception ignored) { 285 } 286 } 287 } 288 289 /** 290 * Return number of packets transmitted across mobile networks since device 291 * boot. Counts packets across all mobile network interfaces, and always 292 * increases monotonically since device boot. Statistics are measured at the 293 * network layer, so they include both TCP and UDP usage. 294 * <p> 295 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may 296 * return {@link #UNSUPPORTED} on devices where statistics aren't available. 297 */ 298 public static long getMobileTxPackets() { 299 long total = 0; 300 for (String iface : getMobileIfaces()) { 301 total += getTxPackets(iface); 302 } 303 return total; 304 } 305 306 /** 307 * Return number of packets received across mobile networks since device 308 * boot. Counts packets across all mobile network interfaces, and always 309 * increases monotonically since device boot. Statistics are measured at the 310 * network layer, so they include both TCP and UDP usage. 311 * <p> 312 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may 313 * return {@link #UNSUPPORTED} on devices where statistics aren't available. 314 */ 315 public static long getMobileRxPackets() { 316 long total = 0; 317 for (String iface : getMobileIfaces()) { 318 total += getRxPackets(iface); 319 } 320 return total; 321 } 322 323 /** 324 * Return number of bytes transmitted across mobile networks since device 325 * boot. Counts packets across all mobile network interfaces, and always 326 * increases monotonically since device boot. Statistics are measured at the 327 * network layer, so they include both TCP and UDP usage. 328 * <p> 329 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may 330 * return {@link #UNSUPPORTED} on devices where statistics aren't available. 331 */ 332 public static long getMobileTxBytes() { 333 long total = 0; 334 for (String iface : getMobileIfaces()) { 335 total += getTxBytes(iface); 336 } 337 return total; 338 } 339 340 /** 341 * Return number of bytes received across mobile networks since device boot. 342 * Counts packets across all mobile network interfaces, and always increases 343 * monotonically since device boot. Statistics are measured at the network 344 * layer, so they include both TCP and UDP usage. 345 * <p> 346 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may 347 * return {@link #UNSUPPORTED} on devices where statistics aren't available. 348 */ 349 public static long getMobileRxBytes() { 350 long total = 0; 351 for (String iface : getMobileIfaces()) { 352 total += getRxBytes(iface); 353 } 354 return total; 355 } 356 357 /** {@hide} */ 358 public static long getMobileTcpRxPackets() { 359 long total = 0; 360 for (String iface : getMobileIfaces()) { 361 final long stat = nativeGetIfaceStat(iface, TYPE_TCP_RX_PACKETS); 362 if (stat != UNSUPPORTED) { 363 total += stat; 364 } 365 } 366 return total; 367 } 368 369 /** {@hide} */ 370 public static long getMobileTcpTxPackets() { 371 long total = 0; 372 for (String iface : getMobileIfaces()) { 373 final long stat = nativeGetIfaceStat(iface, TYPE_TCP_TX_PACKETS); 374 if (stat != UNSUPPORTED) { 375 total += stat; 376 } 377 } 378 return total; 379 } 380 381 /** {@hide} */ 382 public static long getTxPackets(String iface) { 383 return nativeGetIfaceStat(iface, TYPE_TX_PACKETS); 384 } 385 386 /** {@hide} */ 387 public static long getRxPackets(String iface) { 388 return nativeGetIfaceStat(iface, TYPE_RX_PACKETS); 389 } 390 391 /** {@hide} */ 392 public static long getTxBytes(String iface) { 393 return nativeGetIfaceStat(iface, TYPE_TX_BYTES); 394 } 395 396 /** {@hide} */ 397 public static long getRxBytes(String iface) { 398 return nativeGetIfaceStat(iface, TYPE_RX_BYTES); 399 } 400 401 /** 402 * Return number of packets transmitted since device boot. Counts packets 403 * across all network interfaces, and always increases monotonically since 404 * device boot. Statistics are measured at the network layer, so they 405 * include both TCP and UDP usage. 406 * <p> 407 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may 408 * return {@link #UNSUPPORTED} on devices where statistics aren't available. 409 */ 410 public static long getTotalTxPackets() { 411 return nativeGetTotalStat(TYPE_TX_PACKETS); 412 } 413 414 /** 415 * Return number of packets received since device boot. Counts packets 416 * across all network interfaces, and always increases monotonically since 417 * device boot. Statistics are measured at the network layer, so they 418 * include both TCP and UDP usage. 419 * <p> 420 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may 421 * return {@link #UNSUPPORTED} on devices where statistics aren't available. 422 */ 423 public static long getTotalRxPackets() { 424 return nativeGetTotalStat(TYPE_RX_PACKETS); 425 } 426 427 /** 428 * Return number of bytes transmitted since device boot. Counts packets 429 * across all network interfaces, and always increases monotonically since 430 * device boot. Statistics are measured at the network layer, so they 431 * include both TCP and UDP usage. 432 * <p> 433 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may 434 * return {@link #UNSUPPORTED} on devices where statistics aren't available. 435 */ 436 public static long getTotalTxBytes() { 437 return nativeGetTotalStat(TYPE_TX_BYTES); 438 } 439 440 /** 441 * Return number of bytes received since device boot. Counts packets across 442 * all network interfaces, and always increases monotonically since device 443 * boot. Statistics are measured at the network layer, so they include both 444 * TCP and UDP usage. 445 * <p> 446 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may 447 * return {@link #UNSUPPORTED} on devices where statistics aren't available. 448 */ 449 public static long getTotalRxBytes() { 450 return nativeGetTotalStat(TYPE_RX_BYTES); 451 } 452 453 /** 454 * Return number of bytes transmitted by the given UID since device boot. 455 * Counts packets across all network interfaces, and always increases 456 * monotonically since device boot. Statistics are measured at the network 457 * layer, so they include both TCP and UDP usage. 458 * <p> 459 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return 460 * {@link #UNSUPPORTED} on devices where statistics aren't available. 461 * 462 * @see android.os.Process#myUid() 463 * @see android.content.pm.ApplicationInfo#uid 464 */ 465 public static long getUidTxBytes(int uid) { 466 return nativeGetUidStat(uid, TYPE_TX_BYTES); 467 } 468 469 /** 470 * Return number of bytes received by the given UID since device boot. 471 * Counts packets across all network interfaces, and always increases 472 * monotonically since device boot. Statistics are measured at the network 473 * layer, so they include both TCP and UDP usage. 474 * <p> 475 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return 476 * {@link #UNSUPPORTED} on devices where statistics aren't available. 477 * 478 * @see android.os.Process#myUid() 479 * @see android.content.pm.ApplicationInfo#uid 480 */ 481 public static long getUidRxBytes(int uid) { 482 return nativeGetUidStat(uid, TYPE_RX_BYTES); 483 } 484 485 /** 486 * Return number of packets transmitted by the given UID since device boot. 487 * Counts packets across all network interfaces, and always increases 488 * monotonically since device boot. Statistics are measured at the network 489 * layer, so they include both TCP and UDP usage. 490 * <p> 491 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return 492 * {@link #UNSUPPORTED} on devices where statistics aren't available. 493 * 494 * @see android.os.Process#myUid() 495 * @see android.content.pm.ApplicationInfo#uid 496 */ 497 public static long getUidTxPackets(int uid) { 498 return nativeGetUidStat(uid, TYPE_TX_PACKETS); 499 } 500 501 /** 502 * Return number of packets received by the given UID since device boot. 503 * Counts packets across all network interfaces, and always increases 504 * monotonically since device boot. Statistics are measured at the network 505 * layer, so they include both TCP and UDP usage. 506 * <p> 507 * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return 508 * {@link #UNSUPPORTED} on devices where statistics aren't available. 509 * 510 * @see android.os.Process#myUid() 511 * @see android.content.pm.ApplicationInfo#uid 512 */ 513 public static long getUidRxPackets(int uid) { 514 return nativeGetUidStat(uid, TYPE_RX_PACKETS); 515 } 516 517 /** 518 * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, 519 * transport layer statistics are no longer available, and will 520 * always return {@link #UNSUPPORTED}. 521 * @see #getUidTxBytes(int) 522 */ 523 @Deprecated 524 public static long getUidTcpTxBytes(int uid) { 525 return UNSUPPORTED; 526 } 527 528 /** 529 * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, 530 * transport layer statistics are no longer available, and will 531 * always return {@link #UNSUPPORTED}. 532 * @see #getUidRxBytes(int) 533 */ 534 @Deprecated 535 public static long getUidTcpRxBytes(int uid) { 536 return UNSUPPORTED; 537 } 538 539 /** 540 * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, 541 * transport layer statistics are no longer available, and will 542 * always return {@link #UNSUPPORTED}. 543 * @see #getUidTxBytes(int) 544 */ 545 @Deprecated 546 public static long getUidUdpTxBytes(int uid) { 547 return UNSUPPORTED; 548 } 549 550 /** 551 * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, 552 * transport layer statistics are no longer available, and will 553 * always return {@link #UNSUPPORTED}. 554 * @see #getUidRxBytes(int) 555 */ 556 @Deprecated 557 public static long getUidUdpRxBytes(int uid) { 558 return UNSUPPORTED; 559 } 560 561 /** 562 * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, 563 * transport layer statistics are no longer available, and will 564 * always return {@link #UNSUPPORTED}. 565 * @see #getUidTxPackets(int) 566 */ 567 @Deprecated 568 public static long getUidTcpTxSegments(int uid) { 569 return UNSUPPORTED; 570 } 571 572 /** 573 * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, 574 * transport layer statistics are no longer available, and will 575 * always return {@link #UNSUPPORTED}. 576 * @see #getUidRxPackets(int) 577 */ 578 @Deprecated 579 public static long getUidTcpRxSegments(int uid) { 580 return UNSUPPORTED; 581 } 582 583 /** 584 * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, 585 * transport layer statistics are no longer available, and will 586 * always return {@link #UNSUPPORTED}. 587 * @see #getUidTxPackets(int) 588 */ 589 @Deprecated 590 public static long getUidUdpTxPackets(int uid) { 591 return UNSUPPORTED; 592 } 593 594 /** 595 * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, 596 * transport layer statistics are no longer available, and will 597 * always return {@link #UNSUPPORTED}. 598 * @see #getUidRxPackets(int) 599 */ 600 @Deprecated 601 public static long getUidUdpRxPackets(int uid) { 602 return UNSUPPORTED; 603 } 604 605 /** 606 * Return detailed {@link NetworkStats} for the current UID. Requires no 607 * special permission. 608 */ 609 private static NetworkStats getDataLayerSnapshotForUid(Context context) { 610 // TODO: take snapshot locally, since proc file is now visible 611 final int uid = android.os.Process.myUid(); 612 try { 613 return getStatsService().getDataLayerSnapshotForUid(uid); 614 } catch (RemoteException e) { 615 throw new RuntimeException(e); 616 } 617 } 618 619 /** 620 * Return set of any ifaces associated with mobile networks since boot. 621 * Interfaces are never removed from this list, so counters should always be 622 * monotonic. 623 */ 624 private static String[] getMobileIfaces() { 625 try { 626 return getStatsService().getMobileIfaces(); 627 } catch (RemoteException e) { 628 throw new RuntimeException(e); 629 } 630 } 631 632 // NOTE: keep these in sync with android_net_TrafficStats.cpp 633 private static final int TYPE_RX_BYTES = 0; 634 private static final int TYPE_RX_PACKETS = 1; 635 private static final int TYPE_TX_BYTES = 2; 636 private static final int TYPE_TX_PACKETS = 3; 637 private static final int TYPE_TCP_RX_PACKETS = 4; 638 private static final int TYPE_TCP_TX_PACKETS = 5; 639 640 private static native long nativeGetTotalStat(int type); 641 private static native long nativeGetIfaceStat(String iface, int type); 642 private static native long nativeGetUidStat(int uid, int type); 643 } 644