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