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.annotation.SystemApi;
20import android.app.DownloadManager;
21import android.app.backup.BackupManager;
22import android.content.Context;
23import android.media.MediaPlayer;
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    /** @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
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     */
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
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     */
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     */
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
175    public static void setThreadStatsUid(int uid) {
176        NetworkManagementSocketTagger.setThreadSocketStatsUid(uid);
177    }
178
179    /** {@hide} */
180    @SystemApi
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     */
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     */
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     */
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     */
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     */
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     */
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} */
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     */
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     */
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     */
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     */
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} */
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} */
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} */
378    public static long getTxPackets(String iface) {
379        return nativeGetIfaceStat(iface, TYPE_TX_PACKETS);
380    }
381
382    /** {@hide} */
383    public static long getRxPackets(String iface) {
384        return nativeGetIfaceStat(iface, TYPE_RX_PACKETS);
385    }
386
387    /** {@hide} */
388    public static long getTxBytes(String iface) {
389        return nativeGetIfaceStat(iface, TYPE_TX_BYTES);
390    }
391
392    /** {@hide} */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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
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
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
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
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
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
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
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
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     */
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     */
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
636    private static native long nativeGetTotalStat(int type);
637    private static native long nativeGetIfaceStat(String iface, int type);
638    private static native long nativeGetUidStat(int uid, int type);
639}
640