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