TrafficStats.java revision b52e3e55098c4a6e3dbfe19885895411cfb38911
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 /** 92 * Snapshot of {@link NetworkStats} when the currently active profiling 93 * session started, or {@code null} if no session active. 94 * 95 * @see #startDataProfiling(Context) 96 * @see #stopDataProfiling(Context) 97 */ 98 private static NetworkStats sActiveProfilingStart; 99 100 private static Object sProfilingLock = new Object(); 101 102 /** 103 * Set active tag to use when accounting {@link Socket} traffic originating 104 * from the current thread. Only one active tag per thread is supported. 105 * <p> 106 * Changes only take effect during subsequent calls to 107 * {@link #tagSocket(Socket)}. 108 * <p> 109 * Tags between {@code 0xFFFFFF00} and {@code 0xFFFFFFFF} are reserved and 110 * used internally by system services like {@link DownloadManager} when 111 * performing traffic on behalf of an application. 112 */ 113 public static void setThreadStatsTag(int tag) { 114 NetworkManagementSocketTagger.setThreadSocketStatsTag(tag); 115 } 116 117 /** 118 * Get the active tag used when accounting {@link Socket} traffic originating 119 * from the current thread. Only one active tag per thread is supported. 120 * {@link #tagSocket(Socket)}. 121 */ 122 public static int getThreadStatsTag() { 123 return NetworkManagementSocketTagger.getThreadSocketStatsTag(); 124 } 125 126 public static void clearThreadStatsTag() { 127 NetworkManagementSocketTagger.setThreadSocketStatsTag(-1); 128 } 129 130 /** 131 * Set specific UID to use when accounting {@link Socket} traffic 132 * originating from the current thread. Designed for use when performing an 133 * operation on behalf of another application. 134 * <p> 135 * Changes only take effect during subsequent calls to 136 * {@link #tagSocket(Socket)}. 137 * <p> 138 * To take effect, caller must hold 139 * {@link android.Manifest.permission#UPDATE_DEVICE_STATS} permission. 140 * 141 * {@hide} 142 */ 143 public static void setThreadStatsUid(int uid) { 144 NetworkManagementSocketTagger.setThreadSocketStatsUid(uid); 145 } 146 147 /** {@hide} */ 148 public static void clearThreadStatsUid() { 149 NetworkManagementSocketTagger.setThreadSocketStatsUid(-1); 150 } 151 152 /** 153 * Tag the given {@link Socket} with any statistics parameters active for 154 * the current thread. Subsequent calls always replace any existing 155 * parameters. When finished, call {@link #untagSocket(Socket)} to remove 156 * statistics parameters. 157 * 158 * @see #setThreadStatsTag(int) 159 * @see #setThreadStatsUid(int) 160 */ 161 public static void tagSocket(Socket socket) throws SocketException { 162 SocketTagger.get().tag(socket); 163 } 164 165 /** 166 * Remove any statistics parameters from the given {@link Socket}. 167 */ 168 public static void untagSocket(Socket socket) throws SocketException { 169 SocketTagger.get().untag(socket); 170 } 171 172 /** 173 * Start profiling data usage for current UID. Only one profiling session 174 * can be active at a time. 175 * 176 * @hide 177 */ 178 public static void startDataProfiling(Context context) { 179 synchronized (sProfilingLock) { 180 if (sActiveProfilingStart != null) { 181 throw new IllegalStateException("already profiling data"); 182 } 183 184 // take snapshot in time; we calculate delta later 185 sActiveProfilingStart = getDataLayerSnapshotForUid(context); 186 } 187 } 188 189 /** 190 * Stop profiling data usage for current UID. 191 * 192 * @return Detailed {@link NetworkStats} of data that occurred since last 193 * {@link #startDataProfiling(Context)} call. 194 * @hide 195 */ 196 public static NetworkStats stopDataProfiling(Context context) { 197 synchronized (sProfilingLock) { 198 if (sActiveProfilingStart == null) { 199 throw new IllegalStateException("not profiling data"); 200 } 201 202 // subtract starting values and return delta 203 final NetworkStats profilingStop = getDataLayerSnapshotForUid(context); 204 final NetworkStats profilingDelta = NetworkStats.subtract( 205 profilingStop, sActiveProfilingStart, null, null); 206 sActiveProfilingStart = null; 207 return profilingDelta; 208 } 209 } 210 211 /** 212 * Increment count of network operations performed under the accounting tag 213 * currently active on the calling thread. This can be used to derive 214 * bytes-per-operation. 215 * 216 * @param operationCount Number of operations to increment count by. 217 */ 218 public static void incrementOperationCount(int operationCount) { 219 final int tag = getThreadStatsTag(); 220 incrementOperationCount(tag, operationCount); 221 } 222 223 /** 224 * Increment count of network operations performed under the given 225 * accounting tag. This can be used to derive bytes-per-operation. 226 * 227 * @param tag Accounting tag used in {@link #setThreadStatsTag(int)}. 228 * @param operationCount Number of operations to increment count by. 229 */ 230 public static void incrementOperationCount(int tag, int operationCount) { 231 final INetworkStatsService statsService = INetworkStatsService.Stub.asInterface( 232 ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); 233 final int uid = android.os.Process.myUid(); 234 try { 235 statsService.incrementOperationCount(uid, tag, operationCount); 236 } catch (RemoteException e) { 237 throw new RuntimeException(e); 238 } 239 } 240 241 /** {@hide} */ 242 public static void closeQuietly(INetworkStatsSession session) { 243 // TODO: move to NetworkStatsService once it exists 244 if (session != null) { 245 try { 246 session.close(); 247 } catch (RuntimeException rethrown) { 248 throw rethrown; 249 } catch (Exception ignored) { 250 } 251 } 252 } 253 254 /** 255 * Get the total number of packets transmitted through the mobile interface. 256 * 257 * @return number of packets. If the statistics are not supported by this device, 258 * {@link #UNSUPPORTED} will be returned. 259 */ 260 public static native long getMobileTxPackets(); 261 262 /** 263 * Get the total number of packets received 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 native long getMobileRxPackets(); 269 270 /** 271 * Get the total number of bytes transmitted through the mobile interface. 272 * 273 * @return number of bytes. If the statistics are not supported by this device, 274 * {@link #UNSUPPORTED} will be returned. 275 */ 276 public static native long getMobileTxBytes(); 277 278 /** 279 * Get the total number of bytes received through the mobile interface. 280 * 281 * @return number of bytes. If the statistics are not supported by this device, 282 * {@link #UNSUPPORTED} will be returned. 283 */ 284 public static native long getMobileRxBytes(); 285 286 /** 287 * Get the total number of packets transmitted through the specified interface. 288 * 289 * @return number of packets. If the statistics are not supported by this interface, 290 * {@link #UNSUPPORTED} will be returned. 291 * @hide 292 */ 293 public static native long getTxPackets(String iface); 294 295 /** 296 * Get the total number of packets received through the specified interface. 297 * 298 * @return number of packets. If the statistics are not supported by this interface, 299 * {@link #UNSUPPORTED} will be returned. 300 * @hide 301 */ 302 public static native long getRxPackets(String iface); 303 304 /** 305 * Get the total number of bytes transmitted through the specified interface. 306 * 307 * @return number of bytes. If the statistics are not supported by this interface, 308 * {@link #UNSUPPORTED} will be returned. 309 * @hide 310 */ 311 public static native long getTxBytes(String iface); 312 313 /** 314 * Get the total number of bytes received through the specified interface. 315 * 316 * @return number of bytes. If the statistics are not supported by this interface, 317 * {@link #UNSUPPORTED} will be returned. 318 * @hide 319 */ 320 public static native long getRxBytes(String iface); 321 322 323 /** 324 * Get the total number of packets sent through all network interfaces. 325 * 326 * @return the number of packets. If the statistics are not supported by this device, 327 * {@link #UNSUPPORTED} will be returned. 328 */ 329 public static native long getTotalTxPackets(); 330 331 /** 332 * Get the total number of packets received through all network interfaces. 333 * 334 * @return number of packets. If the statistics are not supported by this device, 335 * {@link #UNSUPPORTED} will be returned. 336 */ 337 public static native long getTotalRxPackets(); 338 339 /** 340 * Get the total number of bytes sent through all network interfaces. 341 * 342 * @return number of bytes. If the statistics are not supported by this device, 343 * {@link #UNSUPPORTED} will be returned. 344 */ 345 public static native long getTotalTxBytes(); 346 347 /** 348 * Get the total number of bytes received through all network interfaces. 349 * 350 * @return number of bytes. If the statistics are not supported by this device, 351 * {@link #UNSUPPORTED} will be returned. 352 */ 353 public static native long getTotalRxBytes(); 354 355 /** 356 * Get the number of bytes sent through the network for this UID. 357 * The statistics are across all interfaces. 358 * 359 * {@see android.os.Process#myUid()}. 360 * 361 * @param uid The UID of the process to examine. 362 * @return number of bytes. If the statistics are not supported by this device, 363 * {@link #UNSUPPORTED} will be returned. 364 */ 365 public static native long getUidTxBytes(int uid); 366 367 /** 368 * Get the number of bytes received through the network for this UID. 369 * The statistics are across all interfaces. 370 * 371 * {@see android.os.Process#myUid()}. 372 * 373 * @param uid The UID of the process to examine. 374 * @return number of bytes 375 */ 376 public static native long getUidRxBytes(int uid); 377 378 /** 379 * Get the number of packets (TCP segments + UDP) sent through 380 * the network for this UID. 381 * The statistics are across all interfaces. 382 * 383 * {@see android.os.Process#myUid()}. 384 * 385 * @param uid The UID of the process to examine. 386 * @return number of packets. 387 * If the statistics are not supported by this device, 388 * {@link #UNSUPPORTED} will be returned. 389 */ 390 public static native long getUidTxPackets(int uid); 391 392 /** 393 * Get the number of packets (TCP segments + UDP) received through 394 * the network for this UID. 395 * The statistics are across all interfaces. 396 * 397 * {@see android.os.Process#myUid()}. 398 * 399 * @param uid The UID of the process to examine. 400 * @return number of packets 401 */ 402 public static native long getUidRxPackets(int uid); 403 404 /** 405 * Get the number of TCP payload bytes sent for this UID. 406 * This total does not include protocol and control overheads at 407 * the transport and the lower layers of the networking stack. 408 * The statistics are across all interfaces. 409 * 410 * {@see android.os.Process#myUid()}. 411 * 412 * @param uid The UID of the process to examine. 413 * @return number of bytes. If the statistics are not supported by this device, 414 * {@link #UNSUPPORTED} will be returned. 415 */ 416 public static native long getUidTcpTxBytes(int uid); 417 418 /** 419 * Get the number of TCP payload bytes received for this UID. 420 * This total does not include protocol and control overheads at 421 * the transport and the lower layers of the networking stack. 422 * The statistics are across all interfaces. 423 * 424 * {@see android.os.Process#myUid()}. 425 * 426 * @param uid The UID of the process to examine. 427 * @return number of bytes. If the statistics are not supported by this device, 428 * {@link #UNSUPPORTED} will be returned. 429 */ 430 public static native long getUidTcpRxBytes(int uid); 431 432 /** 433 * Get the number of UDP payload bytes sent for this UID. 434 * This total does not include protocol and control overheads at 435 * the transport and the lower layers of the networking stack. 436 * The statistics are across all interfaces. 437 * 438 * {@see android.os.Process#myUid()}. 439 * 440 * @param uid The UID of the process to examine. 441 * @return number of bytes. If the statistics are not supported by this device, 442 * {@link #UNSUPPORTED} will be returned. 443 */ 444 public static native long getUidUdpTxBytes(int uid); 445 446 /** 447 * Get the number of UDP payload bytes received for this UID. 448 * This total does not include protocol and control overheads at 449 * the transport and the lower layers of the networking stack. 450 * The statistics are across all interfaces. 451 * 452 * {@see android.os.Process#myUid()}. 453 * 454 * @param uid The UID of the process to examine. 455 * @return number of bytes. If the statistics are not supported by this device, 456 * {@link #UNSUPPORTED} will be returned. 457 */ 458 public static native long getUidUdpRxBytes(int uid); 459 460 /** 461 * Get the number of TCP segments sent for this UID. 462 * Does not include TCP control packets (SYN/ACKs/FIN/..). 463 * The statistics are across all interfaces. 464 * 465 * {@see android.os.Process#myUid()}. 466 * 467 * @param uid The UID of the process to examine. 468 * @return number of TCP segments. If the statistics are not supported by this device, 469 * {@link #UNSUPPORTED} will be returned. 470 */ 471 public static native long getUidTcpTxSegments(int uid); 472 473 /** 474 * Get the number of TCP segments received for this UID. 475 * Does not include TCP control packets (SYN/ACKs/FIN/..). 476 * The statistics are across all interfaces. 477 * 478 * {@see android.os.Process#myUid()}. 479 * 480 * @param uid The UID of the process to examine. 481 * @return number of TCP segments. If the statistics are not supported by this device, 482 * {@link #UNSUPPORTED} will be returned. 483 */ 484 public static native long getUidTcpRxSegments(int uid); 485 486 487 /** 488 * Get the number of UDP packets sent for this UID. 489 * Includes DNS requests. 490 * The statistics are across all interfaces. 491 * 492 * {@see android.os.Process#myUid()}. 493 * 494 * @param uid The UID of the process to examine. 495 * @return number of packets. If the statistics are not supported by this device, 496 * {@link #UNSUPPORTED} will be returned. 497 */ 498 public static native long getUidUdpTxPackets(int uid); 499 500 /** 501 * Get the number of UDP packets received for this UID. 502 * Includes DNS responses. 503 * The statistics are across all interfaces. 504 * 505 * {@see android.os.Process#myUid()}. 506 * 507 * @param uid The UID of the process to examine. 508 * @return number of packets. If the statistics are not supported by this device, 509 * {@link #UNSUPPORTED} will be returned. 510 */ 511 public static native long getUidUdpRxPackets(int uid); 512 513 /** 514 * Return detailed {@link NetworkStats} for the current UID. Requires no 515 * special permission. 516 */ 517 private static NetworkStats getDataLayerSnapshotForUid(Context context) { 518 final INetworkStatsService statsService = INetworkStatsService.Stub.asInterface( 519 ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); 520 final int uid = android.os.Process.myUid(); 521 try { 522 return statsService.getDataLayerSnapshotForUid(uid); 523 } catch (RemoteException e) { 524 throw new RuntimeException(e); 525 } 526 } 527} 528