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