• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getStatsService()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      */
setThreadStatsTag(int tag)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      */
getThreadStatsTag()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      */
clearThreadStatsTag()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      */
setThreadStatsUid(int uid)163     public static void setThreadStatsUid(int uid) {
164         NetworkManagementSocketTagger.setThreadSocketStatsUid(uid);
165     }
166 
167     /** {@hide} */
clearThreadStatsUid()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      */
tagSocket(Socket socket)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      */
untagSocket(Socket socket)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      */
startDataProfiling(Context context)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      */
stopDataProfiling(Context context)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      */
incrementOperationCount(int operationCount)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      */
incrementOperationCount(int tag, int operationCount)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} */
closeQuietly(INetworkStatsSession session)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      */
getMobileTxPackets()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      */
getMobileRxPackets()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      */
getMobileTxBytes()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      */
getMobileRxBytes()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} */
getMobileTcpRxPackets()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} */
getMobileTcpTxPackets()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} */
getTxPackets(String iface)365     public static long getTxPackets(String iface) {
366         return nativeGetIfaceStat(iface, TYPE_TX_PACKETS);
367     }
368 
369     /** {@hide} */
getRxPackets(String iface)370     public static long getRxPackets(String iface) {
371         return nativeGetIfaceStat(iface, TYPE_RX_PACKETS);
372     }
373 
374     /** {@hide} */
getTxBytes(String iface)375     public static long getTxBytes(String iface) {
376         return nativeGetIfaceStat(iface, TYPE_TX_BYTES);
377     }
378 
379     /** {@hide} */
getRxBytes(String iface)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      */
getTotalTxPackets()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      */
getTotalRxPackets()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      */
getTotalTxBytes()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      */
getTotalRxBytes()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      */
getUidTxBytes(int uid)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      */
getUidRxBytes(int uid)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      */
getUidTxPackets(int uid)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      */
getUidRxPackets(int uid)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
getUidTcpTxBytes(int uid)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
getUidTcpRxBytes(int uid)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
getUidUdpTxBytes(int uid)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
getUidUdpRxBytes(int uid)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
getUidTcpTxSegments(int uid)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
getUidTcpRxSegments(int uid)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
getUidUdpTxPackets(int uid)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
getUidUdpRxPackets(int uid)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      */
getDataLayerSnapshotForUid(Context context)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      */
getMobileIfaces()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 
nativeGetTotalStat(int type)623     private static native long nativeGetTotalStat(int type);
nativeGetIfaceStat(String iface, int type)624     private static native long nativeGetIfaceStat(String iface, int type);
nativeGetUidStat(int uid, int type)625     private static native long nativeGetUidStat(int uid, int type);
626 }
627