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