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