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.SuppressLint;
20import android.annotation.SystemApi;
21import android.annotation.TestApi;
22import android.app.DownloadManager;
23import android.app.backup.BackupManager;
24import android.app.usage.NetworkStatsManager;
25import android.content.Context;
26import android.media.MediaPlayer;
27import android.os.RemoteException;
28import android.os.ServiceManager;
29import android.util.DataUnit;
30
31import com.android.server.NetworkManagementSocketTagger;
32
33import dalvik.system.SocketTagger;
34
35import java.io.FileDescriptor;
36import java.io.IOException;
37import java.net.DatagramSocket;
38import java.net.Socket;
39import java.net.SocketException;
40
41/**
42 * Class that provides network traffic statistics. These statistics include
43 * bytes transmitted and received and network packets transmitted and received,
44 * over all interfaces, over the mobile interface, and on a per-UID basis.
45 * <p>
46 * These statistics may not be available on all platforms. If the statistics are
47 * not supported by this device, {@link #UNSUPPORTED} will be returned.
48 * <p>
49 * Note that the statistics returned by this class reset and start from zero
50 * after every reboot. To access more robust historical network statistics data,
51 * use {@link NetworkStatsManager} instead.
52 */
53public class TrafficStats {
54    /**
55     * The return value to indicate that the device does not support the statistic.
56     */
57    public final static int UNSUPPORTED = -1;
58
59    /** @hide @deprecated use {@link DataUnit} instead to clarify SI-vs-IEC */
60    @Deprecated
61    public static final long KB_IN_BYTES = 1024;
62    /** @hide @deprecated use {@link DataUnit} instead to clarify SI-vs-IEC */
63    @Deprecated
64    public static final long MB_IN_BYTES = KB_IN_BYTES * 1024;
65    /** @hide @deprecated use {@link DataUnit} instead to clarify SI-vs-IEC */
66    @Deprecated
67    public static final long GB_IN_BYTES = MB_IN_BYTES * 1024;
68    /** @hide @deprecated use {@link DataUnit} instead to clarify SI-vs-IEC */
69    @Deprecated
70    public static final long TB_IN_BYTES = GB_IN_BYTES * 1024;
71    /** @hide @deprecated use {@link DataUnit} instead to clarify SI-vs-IEC */
72    @Deprecated
73    public static final long PB_IN_BYTES = TB_IN_BYTES * 1024;
74
75    /**
76     * Special UID value used when collecting {@link NetworkStatsHistory} for
77     * removed applications.
78     *
79     * @hide
80     */
81    public static final int UID_REMOVED = -4;
82
83    /**
84     * Special UID value used when collecting {@link NetworkStatsHistory} for
85     * tethering traffic.
86     *
87     * @hide
88     */
89    public static final int UID_TETHERING = -5;
90
91    /**
92     * Default tag value for {@link DownloadManager} traffic.
93     *
94     * @hide
95     */
96    public static final int TAG_SYSTEM_DOWNLOAD = 0xFFFFFF01;
97
98    /**
99     * Default tag value for {@link MediaPlayer} traffic.
100     *
101     * @hide
102     */
103    public static final int TAG_SYSTEM_MEDIA = 0xFFFFFF02;
104
105    /**
106     * Default tag value for {@link BackupManager} backup traffic; that is,
107     * traffic from the device to the storage backend.
108     *
109     * @hide
110     */
111    public static final int TAG_SYSTEM_BACKUP = 0xFFFFFF03;
112
113    /**
114     * Default tag value for {@link BackupManager} restore traffic; that is,
115     * app data retrieved from the storage backend at install time.
116     *
117     * @hide
118     */
119    public static final int TAG_SYSTEM_RESTORE = 0xFFFFFF04;
120
121    /**
122     * Default tag value for code (typically APKs) downloaded by an app store on
123     * behalf of the app, such as updates.
124     *
125     * @hide
126     */
127    public static final int TAG_SYSTEM_APP = 0xFFFFFF05;
128
129    /** @hide */
130    public static final int TAG_SYSTEM_DHCP = 0xFFFFFF40;
131    /** @hide */
132    public static final int TAG_SYSTEM_NTP = 0xFFFFFF41;
133    /** @hide */
134    public static final int TAG_SYSTEM_PROBE = 0xFFFFFF42;
135    /** @hide */
136    public static final int TAG_SYSTEM_NEIGHBOR = 0xFFFFFF43;
137    /** @hide */
138    public static final int TAG_SYSTEM_GPS = 0xFFFFFF44;
139    /** @hide */
140    public static final int TAG_SYSTEM_PAC = 0xFFFFFF45;
141
142    private static INetworkStatsService sStatsService;
143
144    private synchronized static INetworkStatsService getStatsService() {
145        if (sStatsService == null) {
146            sStatsService = INetworkStatsService.Stub.asInterface(
147                    ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
148        }
149        return sStatsService;
150    }
151
152    /**
153     * Snapshot of {@link NetworkStats} when the currently active profiling
154     * session started, or {@code null} if no session active.
155     *
156     * @see #startDataProfiling(Context)
157     * @see #stopDataProfiling(Context)
158     */
159    private static NetworkStats sActiveProfilingStart;
160
161    private static Object sProfilingLock = new Object();
162
163    private static final String LOOPBACK_IFACE = "lo";
164
165    /**
166     * Set active tag to use when accounting {@link Socket} traffic originating
167     * from the current thread. Only one active tag per thread is supported.
168     * <p>
169     * Changes only take effect during subsequent calls to
170     * {@link #tagSocket(Socket)}.
171     * <p>
172     * Tags between {@code 0xFFFFFF00} and {@code 0xFFFFFFFF} are reserved and
173     * used internally by system services like {@link DownloadManager} when
174     * performing traffic on behalf of an application.
175     *
176     * @see #clearThreadStatsTag()
177     */
178    public static void setThreadStatsTag(int tag) {
179        NetworkManagementSocketTagger.setThreadSocketStatsTag(tag);
180    }
181
182    /**
183     * Set active tag to use when accounting {@link Socket} traffic originating
184     * from the current thread. Only one active tag per thread is supported.
185     * <p>
186     * Changes only take effect during subsequent calls to
187     * {@link #tagSocket(Socket)}.
188     * <p>
189     * Tags between {@code 0xFFFFFF00} and {@code 0xFFFFFFFF} are reserved and
190     * used internally by system services like {@link DownloadManager} when
191     * performing traffic on behalf of an application.
192     *
193     * @return the current tag for the calling thread, which can be used to
194     *         restore any existing values after a nested operation is finished
195     */
196    public static int getAndSetThreadStatsTag(int tag) {
197        return NetworkManagementSocketTagger.setThreadSocketStatsTag(tag);
198    }
199
200    /**
201     * Set active tag to use when accounting {@link Socket} traffic originating
202     * from the current thread. The tag used internally is well-defined to
203     * distinguish all backup-related traffic.
204     *
205     * @hide
206     */
207    @SystemApi
208    public static void setThreadStatsTagBackup() {
209        setThreadStatsTag(TAG_SYSTEM_BACKUP);
210    }
211
212    /**
213     * Set active tag to use when accounting {@link Socket} traffic originating
214     * from the current thread. The tag used internally is well-defined to
215     * distinguish all restore-related traffic.
216     *
217     * @hide
218     */
219    @SystemApi
220    public static void setThreadStatsTagRestore() {
221        setThreadStatsTag(TAG_SYSTEM_RESTORE);
222    }
223
224    /**
225     * Set active tag to use when accounting {@link Socket} traffic originating
226     * from the current thread. The tag used internally is well-defined to
227     * distinguish all code (typically APKs) downloaded by an app store on
228     * behalf of the app, such as updates.
229     *
230     * @hide
231     */
232    @SystemApi
233    public static void setThreadStatsTagApp() {
234        setThreadStatsTag(TAG_SYSTEM_APP);
235    }
236
237    /**
238     * Get the active tag used when accounting {@link Socket} traffic originating
239     * from the current thread. Only one active tag per thread is supported.
240     * {@link #tagSocket(Socket)}.
241     *
242     * @see #setThreadStatsTag(int)
243     */
244    public static int getThreadStatsTag() {
245        return NetworkManagementSocketTagger.getThreadSocketStatsTag();
246    }
247
248    /**
249     * Clear any active tag set to account {@link Socket} traffic originating
250     * from the current thread.
251     *
252     * @see #setThreadStatsTag(int)
253     */
254    public static void clearThreadStatsTag() {
255        NetworkManagementSocketTagger.setThreadSocketStatsTag(-1);
256    }
257
258    /**
259     * Set specific UID to use when accounting {@link Socket} traffic
260     * originating from the current thread. Designed for use when performing an
261     * operation on behalf of another application, or when another application
262     * is performing operations on your behalf.
263     * <p>
264     * Any app can <em>accept</em> blame for traffic performed on a socket
265     * originally created by another app by calling this method with the
266     * {@link android.system.Os#getuid()} value. However, only apps holding the
267     * {@code android.Manifest.permission#UPDATE_DEVICE_STATS} permission may
268     * <em>assign</em> blame to another UIDs.
269     * <p>
270     * Changes only take effect during subsequent calls to
271     * {@link #tagSocket(Socket)}.
272     */
273    @SystemApi
274    @SuppressLint("Doclava125")
275    public static void setThreadStatsUid(int uid) {
276        NetworkManagementSocketTagger.setThreadSocketStatsUid(uid);
277    }
278
279    /**
280     * Get the active UID used when accounting {@link Socket} traffic originating
281     * from the current thread. Only one active tag per thread is supported.
282     * {@link #tagSocket(Socket)}.
283     *
284     * @see #setThreadStatsUid(int)
285     */
286    public static int getThreadStatsUid() {
287        return NetworkManagementSocketTagger.getThreadSocketStatsUid();
288    }
289
290    /**
291     * Set specific UID to use when accounting {@link Socket} traffic
292     * originating from the current thread as the calling UID. Designed for use
293     * when another application is performing operations on your behalf.
294     * <p>
295     * Changes only take effect during subsequent calls to
296     * {@link #tagSocket(Socket)}.
297     *
298     * @removed
299     * @deprecated use {@link #setThreadStatsUid(int)} instead.
300     */
301    @Deprecated
302    public static void setThreadStatsUidSelf() {
303        setThreadStatsUid(android.os.Process.myUid());
304    }
305
306    /**
307     * Clear any active UID set to account {@link Socket} traffic originating
308     * from the current thread.
309     *
310     * @see #setThreadStatsUid(int)
311     */
312    @SystemApi
313    @SuppressLint("Doclava125")
314    public static void clearThreadStatsUid() {
315        NetworkManagementSocketTagger.setThreadSocketStatsUid(-1);
316    }
317
318    /**
319     * Tag the given {@link Socket} with any statistics parameters active for
320     * the current thread. Subsequent calls always replace any existing
321     * parameters. When finished, call {@link #untagSocket(Socket)} to remove
322     * statistics parameters.
323     *
324     * @see #setThreadStatsTag(int)
325     */
326    public static void tagSocket(Socket socket) throws SocketException {
327        SocketTagger.get().tag(socket);
328    }
329
330    /**
331     * Remove any statistics parameters from the given {@link Socket}.
332     */
333    public static void untagSocket(Socket socket) throws SocketException {
334        SocketTagger.get().untag(socket);
335    }
336
337    /**
338     * Tag the given {@link DatagramSocket} with any statistics parameters
339     * active for the current thread. Subsequent calls always replace any
340     * existing parameters. When finished, call
341     * {@link #untagDatagramSocket(DatagramSocket)} to remove statistics
342     * parameters.
343     *
344     * @see #setThreadStatsTag(int)
345     */
346    public static void tagDatagramSocket(DatagramSocket socket) throws SocketException {
347        SocketTagger.get().tag(socket);
348    }
349
350    /**
351     * Remove any statistics parameters from the given {@link DatagramSocket}.
352     */
353    public static void untagDatagramSocket(DatagramSocket socket) throws SocketException {
354        SocketTagger.get().untag(socket);
355    }
356
357    /**
358     * Tag the given {@link FileDescriptor} socket with any statistics
359     * parameters active for the current thread. Subsequent calls always replace
360     * any existing parameters. When finished, call
361     * {@link #untagFileDescriptor(FileDescriptor)} to remove statistics
362     * parameters.
363     *
364     * @see #setThreadStatsTag(int)
365     */
366    public static void tagFileDescriptor(FileDescriptor fd) throws IOException {
367        SocketTagger.get().tag(fd);
368    }
369
370    /**
371     * Remove any statistics parameters from the given {@link FileDescriptor}
372     * socket.
373     */
374    public static void untagFileDescriptor(FileDescriptor fd) throws IOException {
375        SocketTagger.get().untag(fd);
376    }
377
378    /**
379     * Start profiling data usage for current UID. Only one profiling session
380     * can be active at a time.
381     *
382     * @hide
383     */
384    public static void startDataProfiling(Context context) {
385        synchronized (sProfilingLock) {
386            if (sActiveProfilingStart != null) {
387                throw new IllegalStateException("already profiling data");
388            }
389
390            // take snapshot in time; we calculate delta later
391            sActiveProfilingStart = getDataLayerSnapshotForUid(context);
392        }
393    }
394
395    /**
396     * Stop profiling data usage for current UID.
397     *
398     * @return Detailed {@link NetworkStats} of data that occurred since last
399     *         {@link #startDataProfiling(Context)} call.
400     * @hide
401     */
402    public static NetworkStats stopDataProfiling(Context context) {
403        synchronized (sProfilingLock) {
404            if (sActiveProfilingStart == null) {
405                throw new IllegalStateException("not profiling data");
406            }
407
408            // subtract starting values and return delta
409            final NetworkStats profilingStop = getDataLayerSnapshotForUid(context);
410            final NetworkStats profilingDelta = NetworkStats.subtract(
411                    profilingStop, sActiveProfilingStart, null, null);
412            sActiveProfilingStart = null;
413            return profilingDelta;
414        }
415    }
416
417    /**
418     * Increment count of network operations performed under the accounting tag
419     * currently active on the calling thread. This can be used to derive
420     * bytes-per-operation.
421     *
422     * @param operationCount Number of operations to increment count by.
423     */
424    public static void incrementOperationCount(int operationCount) {
425        final int tag = getThreadStatsTag();
426        incrementOperationCount(tag, operationCount);
427    }
428
429    /**
430     * Increment count of network operations performed under the given
431     * accounting tag. This can be used to derive bytes-per-operation.
432     *
433     * @param tag Accounting tag used in {@link #setThreadStatsTag(int)}.
434     * @param operationCount Number of operations to increment count by.
435     */
436    public static void incrementOperationCount(int tag, int operationCount) {
437        final int uid = android.os.Process.myUid();
438        try {
439            getStatsService().incrementOperationCount(uid, tag, operationCount);
440        } catch (RemoteException e) {
441            throw e.rethrowFromSystemServer();
442        }
443    }
444
445    /** {@hide} */
446    public static void closeQuietly(INetworkStatsSession session) {
447        // TODO: move to NetworkStatsService once it exists
448        if (session != null) {
449            try {
450                session.close();
451            } catch (RuntimeException rethrown) {
452                throw rethrown;
453            } catch (Exception ignored) {
454            }
455        }
456    }
457
458    private static long addIfSupported(long stat) {
459        return (stat == UNSUPPORTED) ? 0 : stat;
460    }
461
462    /**
463     * Return number of packets transmitted across mobile networks since device
464     * boot. Counts packets across all mobile network interfaces, and always
465     * increases monotonically since device boot. Statistics are measured at the
466     * network layer, so they include both TCP and UDP usage.
467     * <p>
468     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
469     * return {@link #UNSUPPORTED} on devices where statistics aren't available.
470     */
471    public static long getMobileTxPackets() {
472        long total = 0;
473        for (String iface : getMobileIfaces()) {
474            total += addIfSupported(getTxPackets(iface));
475        }
476        return total;
477    }
478
479    /**
480     * Return number of packets received across mobile networks since device
481     * boot. Counts packets across all mobile network interfaces, and always
482     * increases monotonically since device boot. Statistics are measured at the
483     * network layer, so they include both TCP and UDP usage.
484     * <p>
485     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
486     * return {@link #UNSUPPORTED} on devices where statistics aren't available.
487     */
488    public static long getMobileRxPackets() {
489        long total = 0;
490        for (String iface : getMobileIfaces()) {
491            total += addIfSupported(getRxPackets(iface));
492        }
493        return total;
494    }
495
496    /**
497     * Return number of bytes transmitted across mobile networks since device
498     * boot. Counts packets across all mobile network interfaces, and always
499     * increases monotonically since device boot. Statistics are measured at the
500     * network layer, so they include both TCP and UDP usage.
501     * <p>
502     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
503     * return {@link #UNSUPPORTED} on devices where statistics aren't available.
504     */
505    public static long getMobileTxBytes() {
506        long total = 0;
507        for (String iface : getMobileIfaces()) {
508            total += addIfSupported(getTxBytes(iface));
509        }
510        return total;
511    }
512
513    /**
514     * Return number of bytes received across mobile networks since device boot.
515     * Counts packets across all mobile network interfaces, and always increases
516     * monotonically since device boot. Statistics are measured at the network
517     * layer, so they include both TCP and UDP usage.
518     * <p>
519     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
520     * return {@link #UNSUPPORTED} on devices where statistics aren't available.
521     */
522    public static long getMobileRxBytes() {
523        long total = 0;
524        for (String iface : getMobileIfaces()) {
525            total += addIfSupported(getRxBytes(iface));
526        }
527        return total;
528    }
529
530    /** {@hide} */
531    public static long getMobileTcpRxPackets() {
532        long total = 0;
533        for (String iface : getMobileIfaces()) {
534            long stat = UNSUPPORTED;
535            try {
536                stat = getStatsService().getIfaceStats(iface, TYPE_TCP_RX_PACKETS);
537            } catch (RemoteException e) {
538                throw e.rethrowFromSystemServer();
539            }
540            total += addIfSupported(stat);
541        }
542        return total;
543    }
544
545    /** {@hide} */
546    public static long getMobileTcpTxPackets() {
547        long total = 0;
548        for (String iface : getMobileIfaces()) {
549            long stat = UNSUPPORTED;
550            try {
551                stat = getStatsService().getIfaceStats(iface, TYPE_TCP_TX_PACKETS);
552            } catch (RemoteException e) {
553                throw e.rethrowFromSystemServer();
554            }
555            total += addIfSupported(stat);
556        }
557        return total;
558    }
559
560    /** {@hide} */
561    public static long getTxPackets(String iface) {
562        try {
563            return getStatsService().getIfaceStats(iface, TYPE_TX_PACKETS);
564        } catch (RemoteException e) {
565            throw e.rethrowFromSystemServer();
566        }
567    }
568
569    /** {@hide} */
570    public static long getRxPackets(String iface) {
571        try {
572            return getStatsService().getIfaceStats(iface, TYPE_RX_PACKETS);
573        } catch (RemoteException e) {
574            throw e.rethrowFromSystemServer();
575        }
576    }
577
578    /** {@hide} */
579    public static long getTxBytes(String iface) {
580        try {
581            return getStatsService().getIfaceStats(iface, TYPE_TX_BYTES);
582        } catch (RemoteException e) {
583            throw e.rethrowFromSystemServer();
584        }
585    }
586
587    /** {@hide} */
588    public static long getRxBytes(String iface) {
589        try {
590            return getStatsService().getIfaceStats(iface, TYPE_RX_BYTES);
591        } catch (RemoteException e) {
592            throw e.rethrowFromSystemServer();
593        }
594    }
595
596    /** {@hide} */
597    @TestApi
598    public static long getLoopbackTxPackets() {
599        try {
600            return getStatsService().getIfaceStats(LOOPBACK_IFACE, TYPE_TX_PACKETS);
601        } catch (RemoteException e) {
602            throw e.rethrowFromSystemServer();
603        }
604    }
605
606    /** {@hide} */
607    @TestApi
608    public static long getLoopbackRxPackets() {
609        try {
610            return getStatsService().getIfaceStats(LOOPBACK_IFACE, TYPE_RX_PACKETS);
611        } catch (RemoteException e) {
612            throw e.rethrowFromSystemServer();
613        }
614    }
615
616    /** {@hide} */
617    @TestApi
618    public static long getLoopbackTxBytes() {
619        try {
620            return getStatsService().getIfaceStats(LOOPBACK_IFACE, TYPE_TX_BYTES);
621        } catch (RemoteException e) {
622            throw e.rethrowFromSystemServer();
623        }
624    }
625
626    /** {@hide} */
627    @TestApi
628    public static long getLoopbackRxBytes() {
629        try {
630            return getStatsService().getIfaceStats(LOOPBACK_IFACE, TYPE_RX_BYTES);
631        } catch (RemoteException e) {
632            throw e.rethrowFromSystemServer();
633        }
634    }
635
636    /**
637     * Return number of packets transmitted since device boot. Counts packets
638     * across all network interfaces, and always increases monotonically since
639     * device boot. Statistics are measured at the network layer, so they
640     * include both TCP and UDP usage.
641     * <p>
642     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
643     * return {@link #UNSUPPORTED} on devices where statistics aren't available.
644     */
645    public static long getTotalTxPackets() {
646        try {
647            return getStatsService().getTotalStats(TYPE_TX_PACKETS);
648        } catch (RemoteException e) {
649            throw e.rethrowFromSystemServer();
650        }
651    }
652
653    /**
654     * Return number of packets received since device boot. Counts packets
655     * across all network interfaces, and always increases monotonically since
656     * device boot. Statistics are measured at the network layer, so they
657     * include both TCP and UDP usage.
658     * <p>
659     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
660     * return {@link #UNSUPPORTED} on devices where statistics aren't available.
661     */
662    public static long getTotalRxPackets() {
663        try {
664            return getStatsService().getTotalStats(TYPE_RX_PACKETS);
665        } catch (RemoteException e) {
666            throw e.rethrowFromSystemServer();
667        }
668    }
669
670    /**
671     * Return number of bytes transmitted since device boot. Counts packets
672     * across all network interfaces, and always increases monotonically since
673     * device boot. Statistics are measured at the network layer, so they
674     * include both TCP and UDP usage.
675     * <p>
676     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
677     * return {@link #UNSUPPORTED} on devices where statistics aren't available.
678     */
679    public static long getTotalTxBytes() {
680        try {
681            return getStatsService().getTotalStats(TYPE_TX_BYTES);
682        } catch (RemoteException e) {
683            throw e.rethrowFromSystemServer();
684        }
685    }
686
687    /**
688     * Return number of bytes received since device boot. Counts packets across
689     * all network interfaces, and always increases monotonically since device
690     * boot. Statistics are measured at the network layer, so they include both
691     * TCP and UDP usage.
692     * <p>
693     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
694     * return {@link #UNSUPPORTED} on devices where statistics aren't available.
695     */
696    public static long getTotalRxBytes() {
697        try {
698            return getStatsService().getTotalStats(TYPE_RX_BYTES);
699        } catch (RemoteException e) {
700            throw e.rethrowFromSystemServer();
701        }
702    }
703
704    /**
705     * Return number of bytes transmitted by the given UID since device boot.
706     * Counts packets across all network interfaces, and always increases
707     * monotonically since device boot. Statistics are measured at the network
708     * layer, so they include both TCP and UDP usage.
709     * <p>
710     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may
711     * return {@link #UNSUPPORTED} on devices where statistics aren't available.
712     * <p>
713     * Starting in {@link android.os.Build.VERSION_CODES#N} this will only
714     * report traffic statistics for the calling UID. It will return
715     * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access
716     * historical network statistics belonging to other UIDs, use
717     * {@link NetworkStatsManager}.
718     *
719     * @see android.os.Process#myUid()
720     * @see android.content.pm.ApplicationInfo#uid
721     */
722    public static long getUidTxBytes(int uid) {
723        // This isn't actually enforcing any security; it just returns the
724        // unsupported value. The real filtering is done at the kernel level.
725        final int callingUid = android.os.Process.myUid();
726        if (callingUid == android.os.Process.SYSTEM_UID || callingUid == uid) {
727            try {
728                return getStatsService().getUidStats(uid, TYPE_TX_BYTES);
729            } catch (RemoteException e) {
730                throw e.rethrowFromSystemServer();
731            }
732        } else {
733            return UNSUPPORTED;
734        }
735    }
736
737    /**
738     * Return number of bytes received by the given UID since device boot.
739     * Counts packets across all network interfaces, and always increases
740     * monotonically since device boot. Statistics are measured at the network
741     * layer, so they include both TCP and UDP usage.
742     * <p>
743     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return
744     * {@link #UNSUPPORTED} on devices where statistics aren't available.
745     * <p>
746     * Starting in {@link android.os.Build.VERSION_CODES#N} this will only
747     * report traffic statistics for the calling UID. It will return
748     * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access
749     * historical network statistics belonging to other UIDs, use
750     * {@link NetworkStatsManager}.
751     *
752     * @see android.os.Process#myUid()
753     * @see android.content.pm.ApplicationInfo#uid
754     */
755    public static long getUidRxBytes(int uid) {
756        // This isn't actually enforcing any security; it just returns the
757        // unsupported value. The real filtering is done at the kernel level.
758        final int callingUid = android.os.Process.myUid();
759        if (callingUid == android.os.Process.SYSTEM_UID || callingUid == uid) {
760            try {
761                return getStatsService().getUidStats(uid, TYPE_RX_BYTES);
762            } catch (RemoteException e) {
763                throw e.rethrowFromSystemServer();
764            }
765        } else {
766            return UNSUPPORTED;
767        }
768    }
769
770    /**
771     * Return number of packets transmitted by the given UID since device boot.
772     * Counts packets across all network interfaces, and always increases
773     * monotonically since device boot. Statistics are measured at the network
774     * layer, so they include both TCP and UDP usage.
775     * <p>
776     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return
777     * {@link #UNSUPPORTED} on devices where statistics aren't available.
778     * <p>
779     * Starting in {@link android.os.Build.VERSION_CODES#N} this will only
780     * report traffic statistics for the calling UID. It will return
781     * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access
782     * historical network statistics belonging to other UIDs, use
783     * {@link NetworkStatsManager}.
784     *
785     * @see android.os.Process#myUid()
786     * @see android.content.pm.ApplicationInfo#uid
787     */
788    public static long getUidTxPackets(int uid) {
789        // This isn't actually enforcing any security; it just returns the
790        // unsupported value. The real filtering is done at the kernel level.
791        final int callingUid = android.os.Process.myUid();
792        if (callingUid == android.os.Process.SYSTEM_UID || callingUid == uid) {
793            try {
794                return getStatsService().getUidStats(uid, TYPE_TX_PACKETS);
795            } catch (RemoteException e) {
796                throw e.rethrowFromSystemServer();
797            }
798        } else {
799            return UNSUPPORTED;
800        }
801    }
802
803    /**
804     * Return number of packets received by the given UID since device boot.
805     * Counts packets across all network interfaces, and always increases
806     * monotonically since device boot. Statistics are measured at the network
807     * layer, so they include both TCP and UDP usage.
808     * <p>
809     * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return
810     * {@link #UNSUPPORTED} on devices where statistics aren't available.
811     * <p>
812     * Starting in {@link android.os.Build.VERSION_CODES#N} this will only
813     * report traffic statistics for the calling UID. It will return
814     * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access
815     * historical network statistics belonging to other UIDs, use
816     * {@link NetworkStatsManager}.
817     *
818     * @see android.os.Process#myUid()
819     * @see android.content.pm.ApplicationInfo#uid
820     */
821    public static long getUidRxPackets(int uid) {
822        // This isn't actually enforcing any security; it just returns the
823        // unsupported value. The real filtering is done at the kernel level.
824        final int callingUid = android.os.Process.myUid();
825        if (callingUid == android.os.Process.SYSTEM_UID || callingUid == uid) {
826            try {
827                return getStatsService().getUidStats(uid, TYPE_RX_PACKETS);
828            } catch (RemoteException e) {
829                throw e.rethrowFromSystemServer();
830            }
831        } else {
832            return UNSUPPORTED;
833        }
834    }
835
836    /**
837     * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
838     *             transport layer statistics are no longer available, and will
839     *             always return {@link #UNSUPPORTED}.
840     * @see #getUidTxBytes(int)
841     */
842    @Deprecated
843    public static long getUidTcpTxBytes(int uid) {
844        return UNSUPPORTED;
845    }
846
847    /**
848     * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
849     *             transport layer statistics are no longer available, and will
850     *             always return {@link #UNSUPPORTED}.
851     * @see #getUidRxBytes(int)
852     */
853    @Deprecated
854    public static long getUidTcpRxBytes(int uid) {
855        return UNSUPPORTED;
856    }
857
858    /**
859     * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
860     *             transport layer statistics are no longer available, and will
861     *             always return {@link #UNSUPPORTED}.
862     * @see #getUidTxBytes(int)
863     */
864    @Deprecated
865    public static long getUidUdpTxBytes(int uid) {
866        return UNSUPPORTED;
867    }
868
869    /**
870     * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
871     *             transport layer statistics are no longer available, and will
872     *             always return {@link #UNSUPPORTED}.
873     * @see #getUidRxBytes(int)
874     */
875    @Deprecated
876    public static long getUidUdpRxBytes(int uid) {
877        return UNSUPPORTED;
878    }
879
880    /**
881     * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
882     *             transport layer statistics are no longer available, and will
883     *             always return {@link #UNSUPPORTED}.
884     * @see #getUidTxPackets(int)
885     */
886    @Deprecated
887    public static long getUidTcpTxSegments(int uid) {
888        return UNSUPPORTED;
889    }
890
891    /**
892     * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
893     *             transport layer statistics are no longer available, and will
894     *             always return {@link #UNSUPPORTED}.
895     * @see #getUidRxPackets(int)
896     */
897    @Deprecated
898    public static long getUidTcpRxSegments(int uid) {
899        return UNSUPPORTED;
900    }
901
902    /**
903     * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
904     *             transport layer statistics are no longer available, and will
905     *             always return {@link #UNSUPPORTED}.
906     * @see #getUidTxPackets(int)
907     */
908    @Deprecated
909    public static long getUidUdpTxPackets(int uid) {
910        return UNSUPPORTED;
911    }
912
913    /**
914     * @deprecated Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
915     *             transport layer statistics are no longer available, and will
916     *             always return {@link #UNSUPPORTED}.
917     * @see #getUidRxPackets(int)
918     */
919    @Deprecated
920    public static long getUidUdpRxPackets(int uid) {
921        return UNSUPPORTED;
922    }
923
924    /**
925     * Return detailed {@link NetworkStats} for the current UID. Requires no
926     * special permission.
927     */
928    private static NetworkStats getDataLayerSnapshotForUid(Context context) {
929        // TODO: take snapshot locally, since proc file is now visible
930        final int uid = android.os.Process.myUid();
931        try {
932            return getStatsService().getDataLayerSnapshotForUid(uid);
933        } catch (RemoteException e) {
934            throw e.rethrowFromSystemServer();
935        }
936    }
937
938    /**
939     * Return set of any ifaces associated with mobile networks since boot.
940     * Interfaces are never removed from this list, so counters should always be
941     * monotonic.
942     */
943    private static String[] getMobileIfaces() {
944        try {
945            return getStatsService().getMobileIfaces();
946        } catch (RemoteException e) {
947            throw e.rethrowFromSystemServer();
948        }
949    }
950
951    // NOTE: keep these in sync with android_net_TrafficStats.cpp
952    private static final int TYPE_RX_BYTES = 0;
953    private static final int TYPE_RX_PACKETS = 1;
954    private static final int TYPE_TX_BYTES = 2;
955    private static final int TYPE_TX_PACKETS = 3;
956    private static final int TYPE_TCP_RX_PACKETS = 4;
957    private static final int TYPE_TCP_TX_PACKETS = 5;
958}
959