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