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