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