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