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 17package android.net; 18 19import android.app.DownloadManager; 20import android.app.backup.BackupManager; 21import android.content.Context; 22import android.media.MediaPlayer; 23import android.os.RemoteException; 24import android.os.ServiceManager; 25 26import com.android.server.NetworkManagementSocketTagger; 27 28import dalvik.system.SocketTagger; 29 30import java.net.Socket; 31import 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 */ 41public 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 public static void setThreadStatsTag(int tag) { 124 NetworkManagementSocketTagger.setThreadSocketStatsTag(tag); 125 } 126 127 /** 128 * Get the active tag used when accounting {@link Socket} traffic originating 129 * from the current thread. Only one active tag per thread is supported. 130 * {@link #tagSocket(Socket)}. 131 */ 132 public static int getThreadStatsTag() { 133 return NetworkManagementSocketTagger.getThreadSocketStatsTag(); 134 } 135 136 public static void clearThreadStatsTag() { 137 NetworkManagementSocketTagger.setThreadSocketStatsTag(-1); 138 } 139 140 /** 141 * Set specific UID to use when accounting {@link Socket} traffic 142 * originating from the current thread. Designed for use when performing an 143 * operation on behalf of another application. 144 * <p> 145 * Changes only take effect during subsequent calls to 146 * {@link #tagSocket(Socket)}. 147 * <p> 148 * To take effect, caller must hold 149 * {@link android.Manifest.permission#UPDATE_DEVICE_STATS} permission. 150 * 151 * {@hide} 152 */ 153 public static void setThreadStatsUid(int uid) { 154 NetworkManagementSocketTagger.setThreadSocketStatsUid(uid); 155 } 156 157 /** {@hide} */ 158 public static void clearThreadStatsUid() { 159 NetworkManagementSocketTagger.setThreadSocketStatsUid(-1); 160 } 161 162 /** 163 * Tag the given {@link Socket} with any statistics parameters active for 164 * the current thread. Subsequent calls always replace any existing 165 * parameters. When finished, call {@link #untagSocket(Socket)} to remove 166 * statistics parameters. 167 * 168 * @see #setThreadStatsTag(int) 169 * @see #setThreadStatsUid(int) 170 */ 171 public static void tagSocket(Socket socket) throws SocketException { 172 SocketTagger.get().tag(socket); 173 } 174 175 /** 176 * Remove any statistics parameters from the given {@link Socket}. 177 */ 178 public static void untagSocket(Socket socket) throws SocketException { 179 SocketTagger.get().untag(socket); 180 } 181 182 /** 183 * Start profiling data usage for current UID. Only one profiling session 184 * can be active at a time. 185 * 186 * @hide 187 */ 188 public static void startDataProfiling(Context context) { 189 synchronized (sProfilingLock) { 190 if (sActiveProfilingStart != null) { 191 throw new IllegalStateException("already profiling data"); 192 } 193 194 // take snapshot in time; we calculate delta later 195 sActiveProfilingStart = getDataLayerSnapshotForUid(context); 196 } 197 } 198 199 /** 200 * Stop profiling data usage for current UID. 201 * 202 * @return Detailed {@link NetworkStats} of data that occurred since last 203 * {@link #startDataProfiling(Context)} call. 204 * @hide 205 */ 206 public static NetworkStats stopDataProfiling(Context context) { 207 synchronized (sProfilingLock) { 208 if (sActiveProfilingStart == null) { 209 throw new IllegalStateException("not profiling data"); 210 } 211 212 // subtract starting values and return delta 213 final NetworkStats profilingStop = getDataLayerSnapshotForUid(context); 214 final NetworkStats profilingDelta = NetworkStats.subtract( 215 profilingStop, sActiveProfilingStart, null, null); 216 sActiveProfilingStart = null; 217 return profilingDelta; 218 } 219 } 220 221 /** 222 * Increment count of network operations performed under the accounting tag 223 * currently active on the calling thread. This can be used to derive 224 * bytes-per-operation. 225 * 226 * @param operationCount Number of operations to increment count by. 227 */ 228 public static void incrementOperationCount(int operationCount) { 229 final int tag = getThreadStatsTag(); 230 incrementOperationCount(tag, operationCount); 231 } 232 233 /** 234 * Increment count of network operations performed under the given 235 * accounting tag. This can be used to derive bytes-per-operation. 236 * 237 * @param tag Accounting tag used in {@link #setThreadStatsTag(int)}. 238 * @param operationCount Number of operations to increment count by. 239 */ 240 public static void incrementOperationCount(int tag, int operationCount) { 241 final int uid = android.os.Process.myUid(); 242 try { 243 getStatsService().incrementOperationCount(uid, tag, operationCount); 244 } catch (RemoteException e) { 245 throw new RuntimeException(e); 246 } 247 } 248 249 /** {@hide} */ 250 public static void closeQuietly(INetworkStatsSession session) { 251 // TODO: move to NetworkStatsService once it exists 252 if (session != null) { 253 try { 254 session.close(); 255 } catch (RuntimeException rethrown) { 256 throw rethrown; 257 } catch (Exception ignored) { 258 } 259 } 260 } 261 262 /** 263 * Get the total number of packets transmitted through the mobile interface. 264 * 265 * @return number of packets. If the statistics are not supported by this device, 266 * {@link #UNSUPPORTED} will be returned. 267 */ 268 public static long getMobileTxPackets() { 269 long total = 0; 270 for (String iface : getMobileIfaces()) { 271 total += getTxPackets(iface); 272 } 273 return total; 274 } 275 276 /** 277 * Get the total number of packets received through the mobile interface. 278 * 279 * @return number of packets. If the statistics are not supported by this device, 280 * {@link #UNSUPPORTED} will be returned. 281 */ 282 public static long getMobileRxPackets() { 283 long total = 0; 284 for (String iface : getMobileIfaces()) { 285 total += getRxPackets(iface); 286 } 287 return total; 288 } 289 290 /** 291 * Get the total number of bytes transmitted through the mobile interface. 292 * 293 * @return number of bytes. If the statistics are not supported by this device, 294 * {@link #UNSUPPORTED} will be returned. 295 */ 296 public static long getMobileTxBytes() { 297 long total = 0; 298 for (String iface : getMobileIfaces()) { 299 total += getTxBytes(iface); 300 } 301 return total; 302 } 303 304 /** 305 * Get the total number of bytes received through the mobile interface. 306 * 307 * @return number of bytes. If the statistics are not supported by this device, 308 * {@link #UNSUPPORTED} will be returned. 309 */ 310 public static long getMobileRxBytes() { 311 long total = 0; 312 for (String iface : getMobileIfaces()) { 313 total += getRxBytes(iface); 314 } 315 return total; 316 } 317 318 /** 319 * Get the total number of packets transmitted through the specified interface. 320 * 321 * @return number of packets. If the statistics are not supported by this interface, 322 * {@link #UNSUPPORTED} will be returned. 323 * @hide 324 */ 325 public static long getTxPackets(String iface) { 326 return nativeGetIfaceStat(iface, TYPE_TX_PACKETS); 327 } 328 329 /** 330 * Get the total number of packets received through the specified interface. 331 * 332 * @return number of packets. If the statistics are not supported by this interface, 333 * {@link #UNSUPPORTED} will be returned. 334 * @hide 335 */ 336 public static long getRxPackets(String iface) { 337 return nativeGetIfaceStat(iface, TYPE_RX_PACKETS); 338 } 339 340 /** 341 * Get the total number of bytes transmitted through the specified interface. 342 * 343 * @return number of bytes. If the statistics are not supported by this interface, 344 * {@link #UNSUPPORTED} will be returned. 345 * @hide 346 */ 347 public static long getTxBytes(String iface) { 348 return nativeGetIfaceStat(iface, TYPE_TX_BYTES); 349 } 350 351 /** 352 * Get the total number of bytes received through the specified interface. 353 * 354 * @return number of bytes. If the statistics are not supported by this interface, 355 * {@link #UNSUPPORTED} will be returned. 356 * @hide 357 */ 358 public static long getRxBytes(String iface) { 359 return nativeGetIfaceStat(iface, TYPE_RX_BYTES); 360 } 361 362 /** 363 * Get the total number of packets sent through all network interfaces. 364 * 365 * @return the number of packets. If the statistics are not supported by this device, 366 * {@link #UNSUPPORTED} will be returned. 367 */ 368 public static long getTotalTxPackets() { 369 return nativeGetTotalStat(TYPE_TX_PACKETS); 370 } 371 372 /** 373 * Get the total number of packets received through all network interfaces. 374 * 375 * @return number of packets. If the statistics are not supported by this device, 376 * {@link #UNSUPPORTED} will be returned. 377 */ 378 public static long getTotalRxPackets() { 379 return nativeGetTotalStat(TYPE_RX_PACKETS); 380 } 381 382 /** 383 * Get the total number of bytes sent through all network interfaces. 384 * 385 * @return number of bytes. If the statistics are not supported by this device, 386 * {@link #UNSUPPORTED} will be returned. 387 */ 388 public static long getTotalTxBytes() { 389 return nativeGetTotalStat(TYPE_TX_BYTES); 390 } 391 392 /** 393 * Get the total number of bytes received through all network interfaces. 394 * 395 * @return number of bytes. If the statistics are not supported by this device, 396 * {@link #UNSUPPORTED} will be returned. 397 */ 398 public static long getTotalRxBytes() { 399 return nativeGetTotalStat(TYPE_RX_BYTES); 400 } 401 402 /** 403 * Get the number of bytes sent through the network for this UID. 404 * The statistics are across all interfaces. 405 * 406 * {@see android.os.Process#myUid()}. 407 * 408 * @param uid The UID of the process to examine. 409 * @return number of bytes. If the statistics are not supported by this device, 410 * {@link #UNSUPPORTED} will be returned. 411 */ 412 public static native long getUidTxBytes(int uid); 413 414 /** 415 * Get the number of bytes received through the network for this UID. 416 * The statistics are across all interfaces. 417 * 418 * {@see android.os.Process#myUid()}. 419 * 420 * @param uid The UID of the process to examine. 421 * @return number of bytes 422 */ 423 public static native long getUidRxBytes(int uid); 424 425 /** 426 * Get the number of packets (TCP segments + UDP) sent through 427 * the network for this UID. 428 * The statistics are across all interfaces. 429 * 430 * {@see android.os.Process#myUid()}. 431 * 432 * @param uid The UID of the process to examine. 433 * @return number of packets. 434 * If the statistics are not supported by this device, 435 * {@link #UNSUPPORTED} will be returned. 436 */ 437 public static native long getUidTxPackets(int uid); 438 439 /** 440 * Get the number of packets (TCP segments + UDP) received through 441 * the network for this UID. 442 * The statistics are across all interfaces. 443 * 444 * {@see android.os.Process#myUid()}. 445 * 446 * @param uid The UID of the process to examine. 447 * @return number of packets 448 */ 449 public static native long getUidRxPackets(int uid); 450 451 /** 452 * Get the number of TCP payload bytes sent for this UID. 453 * This total does not include protocol and control overheads at 454 * the transport and the lower layers of the networking stack. 455 * The statistics are across all interfaces. 456 * 457 * {@see android.os.Process#myUid()}. 458 * 459 * @param uid The UID of the process to examine. 460 * @return number of bytes. If the statistics are not supported by this device, 461 * {@link #UNSUPPORTED} will be returned. 462 */ 463 public static native long getUidTcpTxBytes(int uid); 464 465 /** 466 * Get the number of TCP payload bytes received for this UID. 467 * This total does not include protocol and control overheads at 468 * the transport and the lower layers of the networking stack. 469 * The statistics are across all interfaces. 470 * 471 * {@see android.os.Process#myUid()}. 472 * 473 * @param uid The UID of the process to examine. 474 * @return number of bytes. If the statistics are not supported by this device, 475 * {@link #UNSUPPORTED} will be returned. 476 */ 477 public static native long getUidTcpRxBytes(int uid); 478 479 /** 480 * Get the number of UDP payload bytes sent for this UID. 481 * This total does not include protocol and control overheads at 482 * the transport and the lower layers of the networking stack. 483 * The statistics are across all interfaces. 484 * 485 * {@see android.os.Process#myUid()}. 486 * 487 * @param uid The UID of the process to examine. 488 * @return number of bytes. If the statistics are not supported by this device, 489 * {@link #UNSUPPORTED} will be returned. 490 */ 491 public static native long getUidUdpTxBytes(int uid); 492 493 /** 494 * Get the number of UDP payload bytes received for this UID. 495 * This total does not include protocol and control overheads at 496 * the transport and the lower layers of the networking stack. 497 * The statistics are across all interfaces. 498 * 499 * {@see android.os.Process#myUid()}. 500 * 501 * @param uid The UID of the process to examine. 502 * @return number of bytes. If the statistics are not supported by this device, 503 * {@link #UNSUPPORTED} will be returned. 504 */ 505 public static native long getUidUdpRxBytes(int uid); 506 507 /** 508 * Get the number of TCP segments sent for this UID. 509 * Does not include TCP control packets (SYN/ACKs/FIN/..). 510 * The statistics are across all interfaces. 511 * 512 * {@see android.os.Process#myUid()}. 513 * 514 * @param uid The UID of the process to examine. 515 * @return number of TCP segments. If the statistics are not supported by this device, 516 * {@link #UNSUPPORTED} will be returned. 517 */ 518 public static native long getUidTcpTxSegments(int uid); 519 520 /** 521 * Get the number of TCP segments received for this UID. 522 * Does not include TCP control packets (SYN/ACKs/FIN/..). 523 * The statistics are across all interfaces. 524 * 525 * {@see android.os.Process#myUid()}. 526 * 527 * @param uid The UID of the process to examine. 528 * @return number of TCP segments. If the statistics are not supported by this device, 529 * {@link #UNSUPPORTED} will be returned. 530 */ 531 public static native long getUidTcpRxSegments(int uid); 532 533 /** 534 * Get the number of UDP packets sent for this UID. 535 * Includes DNS requests. 536 * The statistics are across all interfaces. 537 * 538 * {@see android.os.Process#myUid()}. 539 * 540 * @param uid The UID of the process to examine. 541 * @return number of packets. If the statistics are not supported by this device, 542 * {@link #UNSUPPORTED} will be returned. 543 */ 544 public static native long getUidUdpTxPackets(int uid); 545 546 /** 547 * Get the number of UDP packets received for this UID. 548 * Includes DNS responses. 549 * The statistics are across all interfaces. 550 * 551 * {@see android.os.Process#myUid()}. 552 * 553 * @param uid The UID of the process to examine. 554 * @return number of packets. If the statistics are not supported by this device, 555 * {@link #UNSUPPORTED} will be returned. 556 */ 557 public static native long getUidUdpRxPackets(int uid); 558 559 /** 560 * Return detailed {@link NetworkStats} for the current UID. Requires no 561 * special permission. 562 */ 563 private static NetworkStats getDataLayerSnapshotForUid(Context context) { 564 final int uid = android.os.Process.myUid(); 565 try { 566 return getStatsService().getDataLayerSnapshotForUid(uid); 567 } catch (RemoteException e) { 568 throw new RuntimeException(e); 569 } 570 } 571 572 /** 573 * Return set of any ifaces associated with mobile networks since boot. 574 * Interfaces are never removed from this list, so counters should always be 575 * monotonic. 576 */ 577 private static String[] getMobileIfaces() { 578 try { 579 return getStatsService().getMobileIfaces(); 580 } catch (RemoteException e) { 581 throw new RuntimeException(e); 582 } 583 } 584 585 // NOTE: keep these in sync with android_net_TrafficStats.cpp 586 private static final int TYPE_RX_BYTES = 0; 587 private static final int TYPE_RX_PACKETS = 1; 588 private static final int TYPE_TX_BYTES = 2; 589 private static final int TYPE_TX_PACKETS = 3; 590 591 private static native long nativeGetTotalStat(int type); 592 private static native long nativeGetIfaceStat(String iface, int type); 593} 594