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    /** @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
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     */
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
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     */
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     */
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
179    public static void setThreadStatsUid(int uid) {
180        NetworkManagementSocketTagger.setThreadSocketStatsUid(uid);
181    }
182
183    /** {@hide} */
184    @SystemApi
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     */
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     */
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     */
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     */
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     */
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     */
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} */
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     */
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     */
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     */
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     */
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} */
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} */
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} */
382    public static long getTxPackets(String iface) {
383        return nativeGetIfaceStat(iface, TYPE_TX_PACKETS);
384    }
385
386    /** {@hide} */
387    public static long getRxPackets(String iface) {
388        return nativeGetIfaceStat(iface, TYPE_RX_PACKETS);
389    }
390
391    /** {@hide} */
392    public static long getTxBytes(String iface) {
393        return nativeGetIfaceStat(iface, TYPE_TX_BYTES);
394    }
395
396    /** {@hide} */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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
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
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
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
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
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
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
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
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     */
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     */
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
640    private static native long nativeGetTotalStat(int type);
641    private static native long nativeGetIfaceStat(String iface, int type);
642    private static native long nativeGetUidStat(int uid, int type);
643}
644