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