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