1 /*
2  * Copyright (C) 2011 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 com.android.server.net;
18 
19 import static android.Manifest.permission.ACCESS_NETWORK_STATE;
20 import static android.Manifest.permission.NETWORK_STATS_PROVIDER;
21 import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
22 import static android.Manifest.permission.UPDATE_DEVICE_STATS;
23 import static android.content.Intent.ACTION_SHUTDOWN;
24 import static android.content.Intent.ACTION_UID_REMOVED;
25 import static android.content.Intent.ACTION_USER_REMOVED;
26 import static android.content.Intent.EXTRA_UID;
27 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
28 import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
29 import static android.net.ConnectivityManager.isNetworkTypeMobile;
30 import static android.net.NetworkIdentity.SUBTYPE_COMBINED;
31 import static android.net.NetworkStack.checkNetworkStackPermission;
32 import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
33 import static android.net.NetworkStats.IFACE_ALL;
34 import static android.net.NetworkStats.IFACE_VT;
35 import static android.net.NetworkStats.INTERFACES_ALL;
36 import static android.net.NetworkStats.METERED_ALL;
37 import static android.net.NetworkStats.ROAMING_ALL;
38 import static android.net.NetworkStats.SET_ALL;
39 import static android.net.NetworkStats.SET_DEFAULT;
40 import static android.net.NetworkStats.SET_FOREGROUND;
41 import static android.net.NetworkStats.STATS_PER_IFACE;
42 import static android.net.NetworkStats.STATS_PER_UID;
43 import static android.net.NetworkStats.TAG_ALL;
44 import static android.net.NetworkStats.TAG_NONE;
45 import static android.net.NetworkStats.UID_ALL;
46 import static android.net.NetworkStatsHistory.FIELD_ALL;
47 import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
48 import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
49 import static android.net.TrafficStats.KB_IN_BYTES;
50 import static android.net.TrafficStats.MB_IN_BYTES;
51 import static android.os.Trace.TRACE_TAG_NETWORK;
52 import static android.provider.Settings.Global.NETSTATS_AUGMENT_ENABLED;
53 import static android.provider.Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED;
54 import static android.provider.Settings.Global.NETSTATS_DEV_BUCKET_DURATION;
55 import static android.provider.Settings.Global.NETSTATS_DEV_DELETE_AGE;
56 import static android.provider.Settings.Global.NETSTATS_DEV_PERSIST_BYTES;
57 import static android.provider.Settings.Global.NETSTATS_DEV_ROTATE_AGE;
58 import static android.provider.Settings.Global.NETSTATS_GLOBAL_ALERT_BYTES;
59 import static android.provider.Settings.Global.NETSTATS_POLL_INTERVAL;
60 import static android.provider.Settings.Global.NETSTATS_SAMPLE_ENABLED;
61 import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION;
62 import static android.provider.Settings.Global.NETSTATS_UID_DELETE_AGE;
63 import static android.provider.Settings.Global.NETSTATS_UID_PERSIST_BYTES;
64 import static android.provider.Settings.Global.NETSTATS_UID_ROTATE_AGE;
65 import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION;
66 import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
67 import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
68 import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
69 import static android.text.format.DateUtils.DAY_IN_MILLIS;
70 import static android.text.format.DateUtils.HOUR_IN_MILLIS;
71 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
72 import static android.text.format.DateUtils.SECOND_IN_MILLIS;
73 
74 import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
75 import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
76 import static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet;
77 
78 import android.annotation.NonNull;
79 import android.annotation.Nullable;
80 import android.app.AlarmManager;
81 import android.app.PendingIntent;
82 import android.app.usage.NetworkStatsManager;
83 import android.content.BroadcastReceiver;
84 import android.content.ContentResolver;
85 import android.content.Context;
86 import android.content.Intent;
87 import android.content.IntentFilter;
88 import android.content.pm.ApplicationInfo;
89 import android.content.pm.PackageManager;
90 import android.database.ContentObserver;
91 import android.net.DataUsageRequest;
92 import android.net.INetworkManagementEventObserver;
93 import android.net.INetworkStatsService;
94 import android.net.INetworkStatsSession;
95 import android.net.LinkProperties;
96 import android.net.Network;
97 import android.net.NetworkCapabilities;
98 import android.net.NetworkIdentity;
99 import android.net.NetworkInfo;
100 import android.net.NetworkStack;
101 import android.net.NetworkState;
102 import android.net.NetworkStats;
103 import android.net.NetworkStats.NonMonotonicObserver;
104 import android.net.NetworkStatsHistory;
105 import android.net.NetworkTemplate;
106 import android.net.TrafficStats;
107 import android.net.Uri;
108 import android.net.netstats.provider.INetworkStatsProvider;
109 import android.net.netstats.provider.INetworkStatsProviderCallback;
110 import android.net.netstats.provider.NetworkStatsProvider;
111 import android.os.BestClock;
112 import android.os.Binder;
113 import android.os.DropBoxManager;
114 import android.os.Environment;
115 import android.os.Handler;
116 import android.os.HandlerExecutor;
117 import android.os.HandlerThread;
118 import android.os.IBinder;
119 import android.os.INetworkManagementService;
120 import android.os.Looper;
121 import android.os.Message;
122 import android.os.Messenger;
123 import android.os.PowerManager;
124 import android.os.RemoteException;
125 import android.os.SystemClock;
126 import android.os.Trace;
127 import android.os.UserHandle;
128 import android.provider.Settings;
129 import android.provider.Settings.Global;
130 import android.service.NetworkInterfaceProto;
131 import android.service.NetworkStatsServiceDumpProto;
132 import android.telephony.PhoneStateListener;
133 import android.telephony.SubscriptionPlan;
134 import android.text.format.DateUtils;
135 import android.util.ArrayMap;
136 import android.util.ArraySet;
137 import android.util.EventLog;
138 import android.util.Log;
139 import android.util.MathUtils;
140 import android.util.Slog;
141 import android.util.SparseIntArray;
142 import android.util.proto.ProtoOutputStream;
143 
144 import com.android.internal.annotations.GuardedBy;
145 import com.android.internal.annotations.VisibleForTesting;
146 import com.android.internal.net.VpnInfo;
147 import com.android.internal.util.ArrayUtils;
148 import com.android.internal.util.DumpUtils;
149 import com.android.internal.util.FileRotator;
150 import com.android.internal.util.IndentingPrintWriter;
151 import com.android.server.EventLogTags;
152 import com.android.server.LocalServices;
153 
154 import java.io.File;
155 import java.io.FileDescriptor;
156 import java.io.IOException;
157 import java.io.PrintWriter;
158 import java.time.Clock;
159 import java.time.ZoneOffset;
160 import java.util.Arrays;
161 import java.util.HashSet;
162 import java.util.List;
163 import java.util.Objects;
164 import java.util.concurrent.CopyOnWriteArrayList;
165 import java.util.concurrent.Executor;
166 import java.util.concurrent.Semaphore;
167 import java.util.concurrent.TimeUnit;
168 
169 /**
170  * Collect and persist detailed network statistics, and provide this data to
171  * other system services.
172  */
173 public class NetworkStatsService extends INetworkStatsService.Stub {
174     static final String TAG = "NetworkStats";
175     static final boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
176     static final boolean LOGV = Log.isLoggable(TAG, Log.VERBOSE);
177 
178     // Perform polling and persist all (FLAG_PERSIST_ALL).
179     private static final int MSG_PERFORM_POLL = 1;
180     // Perform polling, persist network, and register the global alert again.
181     private static final int MSG_PERFORM_POLL_REGISTER_ALERT = 2;
182     private static final int MSG_UPDATE_IFACES = 3;
183     // A message for broadcasting ACTION_NETWORK_STATS_UPDATED in handler thread to prevent
184     // deadlock.
185     private static final int MSG_BROADCAST_NETWORK_STATS_UPDATED = 4;
186 
187     /** Flags to control detail level of poll event. */
188     private static final int FLAG_PERSIST_NETWORK = 0x1;
189     private static final int FLAG_PERSIST_UID = 0x2;
190     private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID;
191     private static final int FLAG_PERSIST_FORCE = 0x100;
192 
193     /**
194      * When global alert quota is high, wait for this delay before processing each polling,
195      * and do not schedule further polls once there is already one queued.
196      * This avoids firing the global alert too often on devices with high transfer speeds and
197      * high quota.
198      */
199     private static final int DEFAULT_PERFORM_POLL_DELAY_MS = 1000;
200 
201     private static final String TAG_NETSTATS_ERROR = "netstats_error";
202 
203     private final Context mContext;
204     private final INetworkManagementService mNetworkManager;
205     private final NetworkStatsFactory mStatsFactory;
206     private final AlarmManager mAlarmManager;
207     private final Clock mClock;
208     private final NetworkStatsSettings mSettings;
209     private final NetworkStatsObservers mStatsObservers;
210 
211     private final File mSystemDir;
212     private final File mBaseDir;
213 
214     private final PowerManager.WakeLock mWakeLock;
215 
216     private final boolean mUseBpfTrafficStats;
217 
218     private final ContentObserver mContentObserver;
219     private final ContentResolver mContentResolver;
220 
221     @VisibleForTesting
222     public static final String ACTION_NETWORK_STATS_POLL =
223             "com.android.server.action.NETWORK_STATS_POLL";
224     public static final String ACTION_NETWORK_STATS_UPDATED =
225             "com.android.server.action.NETWORK_STATS_UPDATED";
226 
227     private PendingIntent mPollIntent;
228 
229     private static final String PREFIX_DEV = "dev";
230     private static final String PREFIX_XT = "xt";
231     private static final String PREFIX_UID = "uid";
232     private static final String PREFIX_UID_TAG = "uid_tag";
233 
234     /**
235      * Settings that can be changed externally.
236      */
237     public interface NetworkStatsSettings {
getPollInterval()238         long getPollInterval();
getPollDelay()239         long getPollDelay();
getSampleEnabled()240         boolean getSampleEnabled();
getAugmentEnabled()241         boolean getAugmentEnabled();
242         /**
243          * When enabled, all mobile data is reported under {@link NetworkIdentity#SUBTYPE_COMBINED}.
244          * When disabled, mobile data is broken down by a granular subtype representative of the
245          * actual subtype. {@see NetworkTemplate#getCollapsedRatType}.
246          * Enabling this decreases the level of detail but saves performance, disk space and
247          * amount of data logged.
248          */
getCombineSubtypeEnabled()249         boolean getCombineSubtypeEnabled();
250 
251         class Config {
252             public final long bucketDuration;
253             public final long rotateAgeMillis;
254             public final long deleteAgeMillis;
255 
Config(long bucketDuration, long rotateAgeMillis, long deleteAgeMillis)256             public Config(long bucketDuration, long rotateAgeMillis, long deleteAgeMillis) {
257                 this.bucketDuration = bucketDuration;
258                 this.rotateAgeMillis = rotateAgeMillis;
259                 this.deleteAgeMillis = deleteAgeMillis;
260             }
261         }
262 
getDevConfig()263         Config getDevConfig();
getXtConfig()264         Config getXtConfig();
getUidConfig()265         Config getUidConfig();
getUidTagConfig()266         Config getUidTagConfig();
267 
getGlobalAlertBytes(long def)268         long getGlobalAlertBytes(long def);
getDevPersistBytes(long def)269         long getDevPersistBytes(long def);
getXtPersistBytes(long def)270         long getXtPersistBytes(long def);
getUidPersistBytes(long def)271         long getUidPersistBytes(long def);
getUidTagPersistBytes(long def)272         long getUidTagPersistBytes(long def);
273     }
274 
275     private final Object mStatsLock = new Object();
276 
277     /** Set of currently active ifaces. */
278     @GuardedBy("mStatsLock")
279     private final ArrayMap<String, NetworkIdentitySet> mActiveIfaces = new ArrayMap<>();
280 
281     /** Set of currently active ifaces for UID stats. */
282     @GuardedBy("mStatsLock")
283     private final ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces = new ArrayMap<>();
284 
285     /** Current default active iface. */
286     @GuardedBy("mStatsLock")
287     private String mActiveIface;
288 
289     /** Set of any ifaces associated with mobile networks since boot. */
290     @GuardedBy("mStatsLock")
291     private String[] mMobileIfaces = new String[0];
292 
293     /** Set of all ifaces currently used by traffic that does not explicitly specify a Network. */
294     @GuardedBy("mStatsLock")
295     private Network[] mDefaultNetworks = new Network[0];
296 
297     /** Last states of all networks sent from ConnectivityService. */
298     @GuardedBy("mStatsLock")
299     @Nullable
300     private NetworkState[] mLastNetworkStates = null;
301 
302     private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
303             new DropBoxNonMonotonicObserver();
304 
305     private static final int MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS = 100;
306     private final CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList =
307             new CopyOnWriteArrayList<>();
308     /** Semaphore used to wait for stats provider to respond to request stats update. */
309     private final Semaphore mStatsProviderSem = new Semaphore(0, true);
310 
311     @GuardedBy("mStatsLock")
312     private NetworkStatsRecorder mDevRecorder;
313     @GuardedBy("mStatsLock")
314     private NetworkStatsRecorder mXtRecorder;
315     @GuardedBy("mStatsLock")
316     private NetworkStatsRecorder mUidRecorder;
317     @GuardedBy("mStatsLock")
318     private NetworkStatsRecorder mUidTagRecorder;
319 
320     /** Cached {@link #mXtRecorder} stats. */
321     @GuardedBy("mStatsLock")
322     private NetworkStatsCollection mXtStatsCached;
323 
324     /** Current counter sets for each UID. */
325     private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
326 
327     /** Data layer operation counters for splicing into other structures. */
328     private NetworkStats mUidOperations = new NetworkStats(0L, 10);
329 
330     @NonNull
331     private final Handler mHandler;
332 
333     private volatile boolean mSystemReady;
334     private long mPersistThreshold = 2 * MB_IN_BYTES;
335     private long mGlobalAlertBytes;
336 
337     private static final long POLL_RATE_LIMIT_MS = 15_000;
338 
339     private long mLastStatsSessionPoll;
340 
341     /** Map from UID to number of opened sessions */
342     @GuardedBy("mOpenSessionCallsPerUid")
343     private final SparseIntArray mOpenSessionCallsPerUid = new SparseIntArray();
344 
345     private final static int DUMP_STATS_SESSION_COUNT = 20;
346 
347     @NonNull
348     private final Dependencies mDeps;
349 
350     @NonNull
351     private final NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor;
352 
getDefaultSystemDir()353     private static @NonNull File getDefaultSystemDir() {
354         return new File(Environment.getDataDirectory(), "system");
355     }
356 
getDefaultBaseDir()357     private static @NonNull File getDefaultBaseDir() {
358         File baseDir = new File(getDefaultSystemDir(), "netstats");
359         baseDir.mkdirs();
360         return baseDir;
361     }
362 
getDefaultClock()363     private static @NonNull Clock getDefaultClock() {
364         return new BestClock(ZoneOffset.UTC, SystemClock.currentNetworkTimeClock(),
365                 Clock.systemUTC());
366     }
367 
368     private final class NetworkStatsHandler extends Handler {
NetworkStatsHandler(@onNull Looper looper)369         NetworkStatsHandler(@NonNull Looper looper) {
370             super(looper);
371         }
372 
373         @Override
handleMessage(Message msg)374         public void handleMessage(Message msg) {
375             switch (msg.what) {
376                 case MSG_PERFORM_POLL: {
377                     performPoll(FLAG_PERSIST_ALL);
378                     break;
379                 }
380                 case MSG_UPDATE_IFACES: {
381                     // If no cached states, ignore.
382                     if (mLastNetworkStates == null) break;
383                     updateIfaces(mDefaultNetworks, mLastNetworkStates, mActiveIface);
384                     break;
385                 }
386                 case MSG_PERFORM_POLL_REGISTER_ALERT: {
387                     performPoll(FLAG_PERSIST_NETWORK);
388                     registerGlobalAlert();
389                     break;
390                 }
391                 case MSG_BROADCAST_NETWORK_STATS_UPDATED: {
392                     final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
393                     updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
394                     mContext.sendBroadcastAsUser(updatedIntent, UserHandle.ALL,
395                             READ_NETWORK_USAGE_HISTORY);
396                     break;
397                 }
398             }
399         }
400     }
401 
create(Context context, INetworkManagementService networkManager)402     public static NetworkStatsService create(Context context,
403                 INetworkManagementService networkManager) {
404         AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
405         PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
406         PowerManager.WakeLock wakeLock =
407                 powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
408 
409         final NetworkStatsService service = new NetworkStatsService(context, networkManager,
410                 alarmManager, wakeLock, getDefaultClock(),
411                 new DefaultNetworkStatsSettings(context), new NetworkStatsFactory(),
412                 new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir(),
413                 new Dependencies());
414         service.registerLocalService();
415 
416         return service;
417     }
418 
419     // This must not be called outside of tests, even within the same package, as this constructor
420     // does not register the local service. Use the create() helper above.
421     @VisibleForTesting
NetworkStatsService(Context context, INetworkManagementService networkManager, AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock, NetworkStatsSettings settings, NetworkStatsFactory factory, NetworkStatsObservers statsObservers, File systemDir, File baseDir, @NonNull Dependencies deps)422     NetworkStatsService(Context context, INetworkManagementService networkManager,
423             AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock,
424             NetworkStatsSettings settings, NetworkStatsFactory factory,
425             NetworkStatsObservers statsObservers, File systemDir, File baseDir,
426             @NonNull Dependencies deps) {
427         mContext = Objects.requireNonNull(context, "missing Context");
428         mNetworkManager = Objects.requireNonNull(networkManager,
429                 "missing INetworkManagementService");
430         mAlarmManager = Objects.requireNonNull(alarmManager, "missing AlarmManager");
431         mClock = Objects.requireNonNull(clock, "missing Clock");
432         mSettings = Objects.requireNonNull(settings, "missing NetworkStatsSettings");
433         mWakeLock = Objects.requireNonNull(wakeLock, "missing WakeLock");
434         mStatsFactory = Objects.requireNonNull(factory, "missing factory");
435         mStatsObservers = Objects.requireNonNull(statsObservers, "missing NetworkStatsObservers");
436         mSystemDir = Objects.requireNonNull(systemDir, "missing systemDir");
437         mBaseDir = Objects.requireNonNull(baseDir, "missing baseDir");
438         mUseBpfTrafficStats = new File("/sys/fs/bpf/map_netd_app_uid_stats_map").exists();
439         mDeps = Objects.requireNonNull(deps, "missing Dependencies");
440 
441         final HandlerThread handlerThread = mDeps.makeHandlerThread();
442         handlerThread.start();
443         mHandler = new NetworkStatsHandler(handlerThread.getLooper());
444         mNetworkStatsSubscriptionsMonitor = deps.makeSubscriptionsMonitor(mContext,
445                 mHandler.getLooper(), new HandlerExecutor(mHandler), this);
446         mContentResolver = mContext.getContentResolver();
447         mContentObserver = mDeps.makeContentObserver(mHandler, mSettings,
448                 mNetworkStatsSubscriptionsMonitor);
449     }
450 
451     /**
452      * Dependencies of NetworkStatsService, for injection in tests.
453      */
454     // TODO: Move more stuff into dependencies object.
455     @VisibleForTesting
456     public static class Dependencies {
457         /**
458          * Create a HandlerThread to use in NetworkStatsService.
459          */
460         @NonNull
makeHandlerThread()461         public HandlerThread makeHandlerThread() {
462             return new HandlerThread(TAG);
463         }
464 
465         /**
466          * Create a {@link NetworkStatsSubscriptionsMonitor}, can be used to monitor RAT change
467          * event in NetworkStatsService.
468          */
469         @NonNull
makeSubscriptionsMonitor(@onNull Context context, @NonNull Looper looper, @NonNull Executor executor, @NonNull NetworkStatsService service)470         public NetworkStatsSubscriptionsMonitor makeSubscriptionsMonitor(@NonNull Context context,
471                 @NonNull Looper looper, @NonNull Executor executor,
472                 @NonNull NetworkStatsService service) {
473             // TODO: Update RatType passively in NSS, instead of querying into the monitor
474             //  when forceUpdateIface.
475             return new NetworkStatsSubscriptionsMonitor(context, looper, executor,
476                     (subscriberId, type) -> service.handleOnCollapsedRatTypeChanged());
477         }
478 
479         /**
480          * Create a ContentObserver instance which is used to observe settings changes,
481          * and dispatch onChange events on handler thread.
482          */
makeContentObserver(@onNull Handler handler, @NonNull NetworkStatsSettings settings, @NonNull NetworkStatsSubscriptionsMonitor monitor)483         public @NonNull ContentObserver makeContentObserver(@NonNull Handler handler,
484                 @NonNull NetworkStatsSettings settings,
485                 @NonNull NetworkStatsSubscriptionsMonitor monitor) {
486             return new ContentObserver(handler) {
487                 @Override
488                 public void onChange(boolean selfChange, @NonNull Uri uri) {
489                     if (!settings.getCombineSubtypeEnabled()) {
490                         monitor.start();
491                     } else {
492                         monitor.stop();
493                     }
494                 }
495             };
496         }
497     }
498 
499     private void registerLocalService() {
500         LocalServices.addService(NetworkStatsManagerInternal.class,
501                 new NetworkStatsManagerInternalImpl());
502     }
503 
504     public void systemReady() {
505         synchronized (mStatsLock) {
506             mSystemReady = true;
507 
508             // create data recorders along with historical rotators
509             mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
510             mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false);
511             mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
512             mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
513 
514             updatePersistThresholdsLocked();
515 
516             // upgrade any legacy stats, migrating them to rotated files
517             maybeUpgradeLegacyStatsLocked();
518 
519             // read historical network stats from disk, since policy service
520             // might need them right away.
521             mXtStatsCached = mXtRecorder.getOrLoadCompleteLocked();
522 
523             // bootstrap initial stats to prevent double-counting later
524             bootstrapStatsLocked();
525         }
526 
527         // watch for tethering changes
528         final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED);
529         mContext.registerReceiver(mTetherReceiver, tetherFilter, null, mHandler);
530 
531         // listen for periodic polling events
532         final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL);
533         mContext.registerReceiver(mPollReceiver, pollFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
534 
535         // listen for uid removal to clean stats
536         final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED);
537         mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler);
538 
539         // listen for user changes to clean stats
540         final IntentFilter userFilter = new IntentFilter(ACTION_USER_REMOVED);
541         mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
542 
543         // persist stats during clean shutdown
544         final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN);
545         mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
546 
547         try {
548             mNetworkManager.registerObserver(mAlertObserver);
549         } catch (RemoteException e) {
550             // ignored; service lives in system_server
551         }
552 
553         //  schedule periodic pall alarm based on {@link NetworkStatsSettings#getPollInterval()}.
554         final PendingIntent pollIntent =
555                 PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
556 
557         final long currentRealtime = SystemClock.elapsedRealtime();
558         mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
559                 mSettings.getPollInterval(), pollIntent);
560 
561         mContentResolver.registerContentObserver(Settings.Global
562                 .getUriFor(Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED),
563                         false /* notifyForDescendants */, mContentObserver);
564 
565         // Post a runnable on handler thread to call onChange(). It's for getting current value of
566         // NETSTATS_COMBINE_SUBTYPE_ENABLED to decide start or stop monitoring RAT type changes.
567         mHandler.post(() -> mContentObserver.onChange(false, Settings.Global
568                 .getUriFor(Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED)));
569 
570         registerGlobalAlert();
571     }
572 
573     private NetworkStatsRecorder buildRecorder(
574             String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
575         final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
576                 Context.DROPBOX_SERVICE);
577         return new NetworkStatsRecorder(new FileRotator(
578                 mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
579                 mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags);
580     }
581 
582     @GuardedBy("mStatsLock")
583     private void shutdownLocked() {
584         mContext.unregisterReceiver(mTetherReceiver);
585         mContext.unregisterReceiver(mPollReceiver);
586         mContext.unregisterReceiver(mRemovedReceiver);
587         mContext.unregisterReceiver(mUserReceiver);
588         mContext.unregisterReceiver(mShutdownReceiver);
589 
590         if (!mSettings.getCombineSubtypeEnabled()) {
591             mNetworkStatsSubscriptionsMonitor.stop();
592         }
593 
594         mContentResolver.unregisterContentObserver(mContentObserver);
595 
596         final long currentTime = mClock.millis();
597 
598         // persist any pending stats
599         mDevRecorder.forcePersistLocked(currentTime);
600         mXtRecorder.forcePersistLocked(currentTime);
601         mUidRecorder.forcePersistLocked(currentTime);
602         mUidTagRecorder.forcePersistLocked(currentTime);
603 
604         mSystemReady = false;
605     }
606 
607     @GuardedBy("mStatsLock")
608     private void maybeUpgradeLegacyStatsLocked() {
609         File file;
610         try {
611             file = new File(mSystemDir, "netstats.bin");
612             if (file.exists()) {
613                 mDevRecorder.importLegacyNetworkLocked(file);
614                 file.delete();
615             }
616 
617             file = new File(mSystemDir, "netstats_xt.bin");
618             if (file.exists()) {
619                 file.delete();
620             }
621 
622             file = new File(mSystemDir, "netstats_uid.bin");
623             if (file.exists()) {
624                 mUidRecorder.importLegacyUidLocked(file);
625                 mUidTagRecorder.importLegacyUidLocked(file);
626                 file.delete();
627             }
628         } catch (IOException e) {
629             Log.wtf(TAG, "problem during legacy upgrade", e);
630         } catch (OutOfMemoryError e) {
631             Log.wtf(TAG, "problem during legacy upgrade", e);
632         }
633     }
634 
635     /**
636      * Register for a global alert that is delivered through {@link INetworkManagementEventObserver}
637      * or {@link NetworkStatsProviderCallback#onAlertReached()} once a threshold amount of data has
638      * been transferred.
639      */
640     private void registerGlobalAlert() {
641         try {
642             mNetworkManager.setGlobalAlert(mGlobalAlertBytes);
643         } catch (IllegalStateException e) {
644             Slog.w(TAG, "problem registering for global alert: " + e);
645         } catch (RemoteException e) {
646             // ignored; service lives in system_server
647         }
648         invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetAlert(mGlobalAlertBytes));
649     }
650 
651     @Override
652     public INetworkStatsSession openSession() {
653         // NOTE: if callers want to get non-augmented data, they should go
654         // through the public API
655         return openSessionInternal(NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, null);
656     }
657 
658     @Override
659     public INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage) {
660         return openSessionInternal(flags, callingPackage);
661     }
662 
663     private boolean isRateLimitedForPoll(int callingUid) {
664         if (callingUid == android.os.Process.SYSTEM_UID) {
665             return false;
666         }
667 
668         final long lastCallTime;
669         final long now = SystemClock.elapsedRealtime();
670         synchronized (mOpenSessionCallsPerUid) {
671             int calls = mOpenSessionCallsPerUid.get(callingUid, 0);
672             mOpenSessionCallsPerUid.put(callingUid, calls + 1);
673             lastCallTime = mLastStatsSessionPoll;
674             mLastStatsSessionPoll = now;
675         }
676 
677         return now - lastCallTime < POLL_RATE_LIMIT_MS;
678     }
679 
680     private INetworkStatsSession openSessionInternal(final int flags, final String callingPackage) {
681         final int callingUid = Binder.getCallingUid();
682         final int usedFlags = isRateLimitedForPoll(callingUid)
683                 ? flags & (~NetworkStatsManager.FLAG_POLL_ON_OPEN)
684                 : flags;
685         if ((usedFlags & (NetworkStatsManager.FLAG_POLL_ON_OPEN
686                 | NetworkStatsManager.FLAG_POLL_FORCE)) != 0) {
687             final long ident = Binder.clearCallingIdentity();
688             try {
689                 performPoll(FLAG_PERSIST_ALL);
690             } finally {
691                 Binder.restoreCallingIdentity(ident);
692             }
693         }
694 
695         // return an IBinder which holds strong references to any loaded stats
696         // for its lifetime; when caller closes only weak references remain.
697 
698         return new INetworkStatsSession.Stub() {
699             private final int mCallingUid = callingUid;
700             private final String mCallingPackage = callingPackage;
701             private final @NetworkStatsAccess.Level int mAccessLevel = checkAccessLevel(
702                     callingPackage);
703 
704             private NetworkStatsCollection mUidComplete;
705             private NetworkStatsCollection mUidTagComplete;
706 
707             private NetworkStatsCollection getUidComplete() {
708                 synchronized (mStatsLock) {
709                     if (mUidComplete == null) {
710                         mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
711                     }
712                     return mUidComplete;
713                 }
714             }
715 
716             private NetworkStatsCollection getUidTagComplete() {
717                 synchronized (mStatsLock) {
718                     if (mUidTagComplete == null) {
719                         mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
720                     }
721                     return mUidTagComplete;
722                 }
723             }
724 
725             @Override
726             public int[] getRelevantUids() {
727                 return getUidComplete().getRelevantUids(mAccessLevel);
728             }
729 
730             @Override
731             public NetworkStats getDeviceSummaryForNetwork(
732                     NetworkTemplate template, long start, long end) {
733                 return internalGetSummaryForNetwork(template, usedFlags, start, end, mAccessLevel,
734                         mCallingUid);
735             }
736 
737             @Override
738             public NetworkStats getSummaryForNetwork(
739                     NetworkTemplate template, long start, long end) {
740                 return internalGetSummaryForNetwork(template, usedFlags, start, end, mAccessLevel,
741                         mCallingUid);
742             }
743 
744             @Override
745             public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
746                 return internalGetHistoryForNetwork(template, usedFlags, fields, mAccessLevel,
747                         mCallingUid);
748             }
749 
750             @Override
751             public NetworkStats getSummaryForAllUid(
752                     NetworkTemplate template, long start, long end, boolean includeTags) {
753                 try {
754                     final NetworkStats stats = getUidComplete()
755                             .getSummary(template, start, end, mAccessLevel, mCallingUid);
756                     if (includeTags) {
757                         final NetworkStats tagStats = getUidTagComplete()
758                                 .getSummary(template, start, end, mAccessLevel, mCallingUid);
759                         stats.combineAllValues(tagStats);
760                     }
761                     return stats;
762                 } catch (NullPointerException e) {
763                     // TODO: Track down and fix the cause of this crash and remove this catch block.
764                     Slog.wtf(TAG, "NullPointerException in getSummaryForAllUid", e);
765                     throw e;
766                 }
767             }
768 
769             @Override
770             public NetworkStatsHistory getHistoryForUid(
771                     NetworkTemplate template, int uid, int set, int tag, int fields) {
772                 // NOTE: We don't augment UID-level statistics
773                 if (tag == TAG_NONE) {
774                     return getUidComplete().getHistory(template, null, uid, set, tag, fields,
775                             Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
776                 } else {
777                     return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
778                             Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
779                 }
780             }
781 
782             @Override
783             public NetworkStatsHistory getHistoryIntervalForUid(
784                     NetworkTemplate template, int uid, int set, int tag, int fields,
785                     long start, long end) {
786                 // NOTE: We don't augment UID-level statistics
787                 if (tag == TAG_NONE) {
788                     return getUidComplete().getHistory(template, null, uid, set, tag, fields,
789                             start, end, mAccessLevel, mCallingUid);
790                 } else if (uid == Binder.getCallingUid()) {
791                     return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
792                             start, end, mAccessLevel, mCallingUid);
793                 } else {
794                     throw new SecurityException("Calling package " + mCallingPackage
795                             + " cannot access tag information from a different uid");
796                 }
797             }
798 
799             @Override
800             public void close() {
801                 mUidComplete = null;
802                 mUidTagComplete = null;
803             }
804         };
805     }
806 
807     private @NetworkStatsAccess.Level int checkAccessLevel(String callingPackage) {
808         return NetworkStatsAccess.checkAccessLevel(
809                 mContext, Binder.getCallingUid(), callingPackage);
810     }
811 
812     /**
813      * Find the most relevant {@link SubscriptionPlan} for the given
814      * {@link NetworkTemplate} and flags. This is typically used to augment
815      * local measurement results to match a known anchor from the carrier.
816      */
817     private SubscriptionPlan resolveSubscriptionPlan(NetworkTemplate template, int flags) {
818         SubscriptionPlan plan = null;
819         if ((flags & NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN) != 0
820                 && mSettings.getAugmentEnabled()) {
821             if (LOGD) Slog.d(TAG, "Resolving plan for " + template);
822             final long token = Binder.clearCallingIdentity();
823             try {
824                 plan = LocalServices.getService(NetworkPolicyManagerInternal.class)
825                         .getSubscriptionPlan(template);
826             } finally {
827                 Binder.restoreCallingIdentity(token);
828             }
829             if (LOGD) Slog.d(TAG, "Resolved to plan " + plan);
830         }
831         return plan;
832     }
833 
834     /**
835      * Return network summary, splicing between DEV and XT stats when
836      * appropriate.
837      */
838     private NetworkStats internalGetSummaryForNetwork(NetworkTemplate template, int flags,
839             long start, long end, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
840         // We've been using pure XT stats long enough that we no longer need to
841         // splice DEV and XT together.
842         final NetworkStatsHistory history = internalGetHistoryForNetwork(template, flags, FIELD_ALL,
843                 accessLevel, callingUid);
844 
845         final long now = System.currentTimeMillis();
846         final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null);
847 
848         final NetworkStats stats = new NetworkStats(end - start, 1);
849         stats.insertEntry(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE,
850                 METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, entry.rxBytes, entry.rxPackets,
851                 entry.txBytes, entry.txPackets, entry.operations));
852         return stats;
853     }
854 
855     /**
856      * Return network history, splicing between DEV and XT stats when
857      * appropriate.
858      */
859     private NetworkStatsHistory internalGetHistoryForNetwork(NetworkTemplate template,
860             int flags, int fields, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
861         // We've been using pure XT stats long enough that we no longer need to
862         // splice DEV and XT together.
863         final SubscriptionPlan augmentPlan = resolveSubscriptionPlan(template, flags);
864         synchronized (mStatsLock) {
865             return mXtStatsCached.getHistory(template, augmentPlan,
866                     UID_ALL, SET_ALL, TAG_NONE, fields, Long.MIN_VALUE, Long.MAX_VALUE,
867                     accessLevel, callingUid);
868         }
869     }
870 
871     private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
872         assertSystemReady();
873 
874         // NOTE: if callers want to get non-augmented data, they should go
875         // through the public API
876         return internalGetSummaryForNetwork(template,
877                 NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, start, end,
878                 NetworkStatsAccess.Level.DEVICE, Binder.getCallingUid()).getTotalBytes();
879     }
880 
881     private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
882         assertSystemReady();
883 
884         final NetworkStatsCollection uidComplete;
885         synchronized (mStatsLock) {
886             uidComplete = mUidRecorder.getOrLoadCompleteLocked();
887         }
888         return uidComplete.getSummary(template, start, end, NetworkStatsAccess.Level.DEVICE,
889                 android.os.Process.SYSTEM_UID);
890     }
891 
892     @Override
893     public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
894         if (Binder.getCallingUid() != uid) {
895             mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
896         }
897 
898         // TODO: switch to data layer stats once kernel exports
899         // for now, read network layer stats and flatten across all ifaces
900         final NetworkStats networkLayer = readNetworkStatsUidDetail(uid, INTERFACES_ALL, TAG_ALL);
901 
902         // splice in operation counts
903         networkLayer.spliceOperationsFrom(mUidOperations);
904 
905         final NetworkStats dataLayer = new NetworkStats(
906                 networkLayer.getElapsedRealtime(), networkLayer.size());
907 
908         NetworkStats.Entry entry = null;
909         for (int i = 0; i < networkLayer.size(); i++) {
910             entry = networkLayer.getValues(i, entry);
911             entry.iface = IFACE_ALL;
912             dataLayer.combineValues(entry);
913         }
914 
915         return dataLayer;
916     }
917 
918     @Override
919     public NetworkStats getDetailedUidStats(String[] requiredIfaces) {
920         try {
921             final String[] ifacesToQuery =
922                     mStatsFactory.augmentWithStackedInterfaces(requiredIfaces);
923             return getNetworkStatsUidDetail(ifacesToQuery);
924         } catch (RemoteException e) {
925             Log.wtf(TAG, "Error compiling UID stats", e);
926             return new NetworkStats(0L, 0);
927         }
928     }
929 
930     @Override
931     public String[] getMobileIfaces() {
932         return mMobileIfaces;
933     }
934 
935     @Override
936     public void incrementOperationCount(int uid, int tag, int operationCount) {
937         if (Binder.getCallingUid() != uid) {
938             mContext.enforceCallingOrSelfPermission(UPDATE_DEVICE_STATS, TAG);
939         }
940 
941         if (operationCount < 0) {
942             throw new IllegalArgumentException("operation count can only be incremented");
943         }
944         if (tag == TAG_NONE) {
945             throw new IllegalArgumentException("operation count must have specific tag");
946         }
947 
948         synchronized (mStatsLock) {
949             final int set = mActiveUidCounterSet.get(uid, SET_DEFAULT);
950             mUidOperations.combineValues(
951                     mActiveIface, uid, set, tag, 0L, 0L, 0L, 0L, operationCount);
952             mUidOperations.combineValues(
953                     mActiveIface, uid, set, TAG_NONE, 0L, 0L, 0L, 0L, operationCount);
954         }
955     }
956 
957     @VisibleForTesting
958     void setUidForeground(int uid, boolean uidForeground) {
959         synchronized (mStatsLock) {
960             final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT;
961             final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT);
962             if (oldSet != set) {
963                 mActiveUidCounterSet.put(uid, set);
964                 setKernelCounterSet(uid, set);
965             }
966         }
967     }
968 
969     @Override
970     public void forceUpdateIfaces(
971             Network[] defaultNetworks,
972             NetworkState[] networkStates,
973             String activeIface,
974             VpnInfo[] vpnInfos) {
975         checkNetworkStackPermission(mContext);
976 
977         final long token = Binder.clearCallingIdentity();
978         try {
979             updateIfaces(defaultNetworks, networkStates, activeIface);
980         } finally {
981             Binder.restoreCallingIdentity(token);
982         }
983 
984         // Update the VPN underlying interfaces only after the poll is made and tun data has been
985         // migrated. Otherwise the migration would use the new interfaces instead of the ones that
986         // were current when the polled data was transferred.
987         mStatsFactory.updateVpnInfos(vpnInfos);
988     }
989 
990     @Override
991     public void forceUpdate() {
992         mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
993 
994         final long token = Binder.clearCallingIdentity();
995         try {
996             performPoll(FLAG_PERSIST_ALL);
997         } finally {
998             Binder.restoreCallingIdentity(token);
999         }
1000     }
1001 
1002     private void advisePersistThreshold(long thresholdBytes) {
1003         // clamp threshold into safe range
1004         mPersistThreshold = MathUtils.constrain(thresholdBytes, 128 * KB_IN_BYTES, 2 * MB_IN_BYTES);
1005         if (LOGV) {
1006             Slog.v(TAG, "advisePersistThreshold() given " + thresholdBytes + ", clamped to "
1007                     + mPersistThreshold);
1008         }
1009 
1010         final long oldGlobalAlertBytes = mGlobalAlertBytes;
1011 
1012         // update and persist if beyond new thresholds
1013         final long currentTime = mClock.millis();
1014         synchronized (mStatsLock) {
1015             if (!mSystemReady) return;
1016 
1017             updatePersistThresholdsLocked();
1018 
1019             mDevRecorder.maybePersistLocked(currentTime);
1020             mXtRecorder.maybePersistLocked(currentTime);
1021             mUidRecorder.maybePersistLocked(currentTime);
1022             mUidTagRecorder.maybePersistLocked(currentTime);
1023         }
1024 
1025         if (oldGlobalAlertBytes != mGlobalAlertBytes) {
1026             registerGlobalAlert();
1027         }
1028     }
1029 
1030     @Override
1031     public DataUsageRequest registerUsageCallback(String callingPackage,
1032                 DataUsageRequest request, Messenger messenger, IBinder binder) {
1033         Objects.requireNonNull(callingPackage, "calling package is null");
1034         Objects.requireNonNull(request, "DataUsageRequest is null");
1035         Objects.requireNonNull(request.template, "NetworkTemplate is null");
1036         Objects.requireNonNull(messenger, "messenger is null");
1037         Objects.requireNonNull(binder, "binder is null");
1038 
1039         int callingUid = Binder.getCallingUid();
1040         @NetworkStatsAccess.Level int accessLevel = checkAccessLevel(callingPackage);
1041         DataUsageRequest normalizedRequest;
1042         final long token = Binder.clearCallingIdentity();
1043         try {
1044             normalizedRequest = mStatsObservers.register(request, messenger, binder,
1045                     callingUid, accessLevel);
1046         } finally {
1047             Binder.restoreCallingIdentity(token);
1048         }
1049 
1050         // Create baseline stats
1051         mHandler.sendMessage(mHandler.obtainMessage(MSG_PERFORM_POLL));
1052 
1053         return normalizedRequest;
1054    }
1055 
1056     @Override
1057     public void unregisterUsageRequest(DataUsageRequest request) {
1058         Objects.requireNonNull(request, "DataUsageRequest is null");
1059 
1060         int callingUid = Binder.getCallingUid();
1061         final long token = Binder.clearCallingIdentity();
1062         try {
1063             mStatsObservers.unregister(request, callingUid);
1064         } finally {
1065             Binder.restoreCallingIdentity(token);
1066         }
1067     }
1068 
1069     @Override
1070     public long getUidStats(int uid, int type) {
1071         return nativeGetUidStat(uid, type, checkBpfStatsEnable());
1072     }
1073 
1074     @Override
1075     public long getIfaceStats(String iface, int type) {
1076         long nativeIfaceStats = nativeGetIfaceStat(iface, type, checkBpfStatsEnable());
1077         if (nativeIfaceStats == -1) {
1078             return nativeIfaceStats;
1079         } else {
1080             // When tethering offload is in use, nativeIfaceStats does not contain usage from
1081             // offload, add it back here.
1082             // When tethering offload is not in use, nativeIfaceStats contains tethering usage.
1083             // this does not cause double-counting of tethering traffic, because
1084             // NetdTetheringStatsProvider returns zero NetworkStats
1085             // when called with STATS_PER_IFACE.
1086             return nativeIfaceStats + getTetherStats(iface, type);
1087         }
1088     }
1089 
1090     @Override
1091     public long getTotalStats(int type) {
1092         long nativeTotalStats = nativeGetTotalStat(type, checkBpfStatsEnable());
1093         if (nativeTotalStats == -1) {
1094             return nativeTotalStats;
1095         } else {
1096             // Refer to comment in getIfaceStats
1097             return nativeTotalStats + getTetherStats(IFACE_ALL, type);
1098         }
1099     }
1100 
1101     private long getTetherStats(String iface, int type) {
1102         final NetworkStats tetherSnapshot;
1103         final long token = Binder.clearCallingIdentity();
1104         try {
1105             tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
1106         } catch (RemoteException e) {
1107             Slog.w(TAG, "Error get TetherStats: " + e);
1108             return 0;
1109         } finally {
1110             Binder.restoreCallingIdentity(token);
1111         }
1112         HashSet<String> limitIfaces;
1113         if (iface == IFACE_ALL) {
1114             limitIfaces = null;
1115         } else {
1116             limitIfaces = new HashSet<String>();
1117             limitIfaces.add(iface);
1118         }
1119         NetworkStats.Entry entry = tetherSnapshot.getTotal(null, limitIfaces);
1120         if (LOGD) Slog.d(TAG, "TetherStats: iface=" + iface + " type=" + type +
1121                 " entry=" + entry);
1122         switch (type) {
1123             case 0: // TYPE_RX_BYTES
1124                 return entry.rxBytes;
1125             case 1: // TYPE_RX_PACKETS
1126                 return entry.rxPackets;
1127             case 2: // TYPE_TX_BYTES
1128                 return entry.txBytes;
1129             case 3: // TYPE_TX_PACKETS
1130                 return entry.txPackets;
1131             default:
1132                 return 0;
1133         }
1134     }
1135 
1136     private boolean checkBpfStatsEnable() {
1137         return mUseBpfTrafficStats;
1138     }
1139 
1140     /**
1141      * Update {@link NetworkStatsRecorder} and {@link #mGlobalAlertBytes} to
1142      * reflect current {@link #mPersistThreshold} value. Always defers to
1143      * {@link Global} values when defined.
1144      */
1145     @GuardedBy("mStatsLock")
1146     private void updatePersistThresholdsLocked() {
1147         mDevRecorder.setPersistThreshold(mSettings.getDevPersistBytes(mPersistThreshold));
1148         mXtRecorder.setPersistThreshold(mSettings.getXtPersistBytes(mPersistThreshold));
1149         mUidRecorder.setPersistThreshold(mSettings.getUidPersistBytes(mPersistThreshold));
1150         mUidTagRecorder.setPersistThreshold(mSettings.getUidTagPersistBytes(mPersistThreshold));
1151         mGlobalAlertBytes = mSettings.getGlobalAlertBytes(mPersistThreshold);
1152     }
1153 
1154     /**
1155      * Receiver that watches for {@link Tethering} to claim interface pairs.
1156      */
1157     private BroadcastReceiver mTetherReceiver = new BroadcastReceiver() {
1158         @Override
1159         public void onReceive(Context context, Intent intent) {
1160             performPoll(FLAG_PERSIST_NETWORK);
1161         }
1162     };
1163 
1164     private BroadcastReceiver mPollReceiver = new BroadcastReceiver() {
1165         @Override
1166         public void onReceive(Context context, Intent intent) {
1167             // on background handler thread, and verified UPDATE_DEVICE_STATS
1168             // permission above.
1169             performPoll(FLAG_PERSIST_ALL);
1170 
1171             // verify that we're watching global alert
1172             registerGlobalAlert();
1173         }
1174     };
1175 
1176     private BroadcastReceiver mRemovedReceiver = new BroadcastReceiver() {
1177         @Override
1178         public void onReceive(Context context, Intent intent) {
1179             // on background handler thread, and UID_REMOVED is protected
1180             // broadcast.
1181 
1182             final int uid = intent.getIntExtra(EXTRA_UID, -1);
1183             if (uid == -1) return;
1184 
1185             synchronized (mStatsLock) {
1186                 mWakeLock.acquire();
1187                 try {
1188                     removeUidsLocked(uid);
1189                 } finally {
1190                     mWakeLock.release();
1191                 }
1192             }
1193         }
1194     };
1195 
1196     private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
1197         @Override
1198         public void onReceive(Context context, Intent intent) {
1199             // On background handler thread, and USER_REMOVED is protected
1200             // broadcast.
1201 
1202             final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
1203             if (userId == -1) return;
1204 
1205             synchronized (mStatsLock) {
1206                 mWakeLock.acquire();
1207                 try {
1208                     removeUserLocked(userId);
1209                 } finally {
1210                     mWakeLock.release();
1211                 }
1212             }
1213         }
1214     };
1215 
1216     private BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() {
1217         @Override
1218         public void onReceive(Context context, Intent intent) {
1219             // SHUTDOWN is protected broadcast.
1220             synchronized (mStatsLock) {
1221                 shutdownLocked();
1222             }
1223         }
1224     };
1225 
1226     /**
1227      * Observer that watches for {@link INetworkManagementService} alerts.
1228      */
1229     private final INetworkManagementEventObserver mAlertObserver = new BaseNetworkObserver() {
1230         @Override
1231         public void limitReached(String limitName, String iface) {
1232             // only someone like NMS should be calling us
1233             NetworkStack.checkNetworkStackPermission(mContext);
1234 
1235             if (LIMIT_GLOBAL_ALERT.equals(limitName)) {
1236                 // kick off background poll to collect network stats unless there is already
1237                 // such a call pending; UID stats are handled during normal polling interval.
1238                 if (!mHandler.hasMessages(MSG_PERFORM_POLL_REGISTER_ALERT)) {
1239                     mHandler.sendEmptyMessageDelayed(MSG_PERFORM_POLL_REGISTER_ALERT,
1240                             mSettings.getPollDelay());
1241                 }
1242             }
1243         }
1244     };
1245 
1246     /**
1247      * Handle collapsed RAT type changed event.
1248      */
1249     @VisibleForTesting
1250     public void handleOnCollapsedRatTypeChanged() {
1251         // Protect service from frequently updating. Remove pending messages if any.
1252         mHandler.removeMessages(MSG_UPDATE_IFACES);
1253         mHandler.sendMessageDelayed(
1254                 mHandler.obtainMessage(MSG_UPDATE_IFACES), mSettings.getPollDelay());
1255     }
1256 
1257     private void updateIfaces(
1258             Network[] defaultNetworks,
1259             NetworkState[] networkStates,
1260             String activeIface) {
1261         synchronized (mStatsLock) {
1262             mWakeLock.acquire();
1263             try {
1264                 mActiveIface = activeIface;
1265                 updateIfacesLocked(defaultNetworks, networkStates);
1266             } finally {
1267                 mWakeLock.release();
1268             }
1269         }
1270     }
1271 
1272     /**
1273      * Inspect all current {@link NetworkState} to derive mapping from {@code iface} to {@link
1274      * NetworkStatsHistory}. When multiple {@link NetworkInfo} are active on a single {@code iface},
1275      * they are combined under a single {@link NetworkIdentitySet}.
1276      */
1277     @GuardedBy("mStatsLock")
1278     private void updateIfacesLocked(@Nullable Network[] defaultNetworks,
1279             @NonNull NetworkState[] states) {
1280         if (!mSystemReady) return;
1281         if (LOGV) Slog.v(TAG, "updateIfacesLocked()");
1282 
1283         // take one last stats snapshot before updating iface mapping. this
1284         // isn't perfect, since the kernel may already be counting traffic from
1285         // the updated network.
1286 
1287         // poll, but only persist network stats to keep codepath fast. UID stats
1288         // will be persisted during next alarm poll event.
1289         performPollLocked(FLAG_PERSIST_NETWORK);
1290 
1291         // Rebuild active interfaces based on connected networks
1292         mActiveIfaces.clear();
1293         mActiveUidIfaces.clear();
1294         if (defaultNetworks != null) {
1295             // Caller is ConnectivityService. Update the list of default networks.
1296             mDefaultNetworks = defaultNetworks;
1297         }
1298 
1299         mLastNetworkStates = states;
1300 
1301         final boolean combineSubtypeEnabled = mSettings.getCombineSubtypeEnabled();
1302         final ArraySet<String> mobileIfaces = new ArraySet<>();
1303         for (NetworkState state : states) {
1304             if (state.networkInfo.isConnected()) {
1305                 final boolean isMobile = isNetworkTypeMobile(state.networkInfo.getType());
1306                 final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, state.network);
1307                 final int subType = combineSubtypeEnabled ? SUBTYPE_COMBINED
1308                         : getSubTypeForState(state);
1309                 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state,
1310                         isDefault, subType);
1311 
1312                 // Traffic occurring on the base interface is always counted for
1313                 // both total usage and UID details.
1314                 final String baseIface = state.linkProperties.getInterfaceName();
1315                 if (baseIface != null) {
1316                     findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident);
1317                     findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident);
1318 
1319                     // Build a separate virtual interface for VT (Video Telephony) data usage.
1320                     // Only do this when IMS is not metered, but VT is metered.
1321                     // If IMS is metered, then the IMS network usage has already included VT usage.
1322                     // VT is considered always metered in framework's layer. If VT is not metered
1323                     // per carrier's policy, modem will report 0 usage for VT calls.
1324                     if (state.networkCapabilities.hasCapability(
1325                             NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.getMetered()) {
1326 
1327                         // Copy the identify from IMS one but mark it as metered.
1328                         NetworkIdentity vtIdent = new NetworkIdentity(ident.getType(),
1329                                 ident.getSubType(), ident.getSubscriberId(), ident.getNetworkId(),
1330                                 ident.getRoaming(), true /* metered */,
1331                                 true /* onDefaultNetwork */);
1332                         findOrCreateNetworkIdentitySet(mActiveIfaces, IFACE_VT).add(vtIdent);
1333                         findOrCreateNetworkIdentitySet(mActiveUidIfaces, IFACE_VT).add(vtIdent);
1334                     }
1335 
1336                     if (isMobile) {
1337                         mobileIfaces.add(baseIface);
1338                     }
1339                 }
1340 
1341                 // Traffic occurring on stacked interfaces is usually clatd.
1342                 //
1343                 // UID stats are always counted on the stacked interface and never on the base
1344                 // interface, because the packets on the base interface do not actually match
1345                 // application sockets (they're not IPv4) and thus the app uid is not known.
1346                 // For receive this is obvious: packets must be translated from IPv6 to IPv4
1347                 // before the application socket can be found.
1348                 // For transmit: either they go through the clat daemon which by virtue of going
1349                 // through userspace strips the original socket association during the IPv4 to
1350                 // IPv6 translation process, or they are offloaded by eBPF, which doesn't:
1351                 // However, on an ebpf device the accounting is done in cgroup ebpf hooks,
1352                 // which don't trigger again post ebpf translation.
1353                 // (as such stats accounted to the clat uid are ignored)
1354                 //
1355                 // Interface stats are more complicated.
1356                 //
1357                 // eBPF offloaded 464xlat'ed packets never hit base interface ip6tables, and thus
1358                 // *all* statistics are collected by iptables on the stacked v4-* interface.
1359                 //
1360                 // Additionally for ingress all packets bound for the clat IPv6 address are dropped
1361                 // in ip6tables raw prerouting and thus even non-offloaded packets are only
1362                 // accounted for on the stacked interface.
1363                 //
1364                 // For egress, packets subject to eBPF offload never appear on the base interface
1365                 // and only appear on the stacked interface. Thus to ensure packets increment
1366                 // interface stats, we must collate data from stacked interfaces. For xt_qtaguid
1367                 // (or non eBPF offloaded) TX they would appear on both, however egress interface
1368                 // accounting is explicitly bypassed for traffic from the clat uid.
1369                 //
1370                 final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks();
1371                 for (LinkProperties stackedLink : stackedLinks) {
1372                     final String stackedIface = stackedLink.getInterfaceName();
1373                     if (stackedIface != null) {
1374                         findOrCreateNetworkIdentitySet(mActiveIfaces, stackedIface).add(ident);
1375                         findOrCreateNetworkIdentitySet(mActiveUidIfaces, stackedIface).add(ident);
1376                         if (isMobile) {
1377                             mobileIfaces.add(stackedIface);
1378                         }
1379 
1380                         mStatsFactory.noteStackedIface(stackedIface, baseIface);
1381                     }
1382                 }
1383             }
1384         }
1385 
1386         mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]);
1387     }
1388 
1389     /**
1390      * For networks with {@code TRANSPORT_CELLULAR}, get subType that was obtained through
1391      * {@link PhoneStateListener}. Otherwise, return 0 given that other networks with different
1392      * transport types do not actually fill this value.
1393      */
1394     private int getSubTypeForState(@NonNull NetworkState state) {
1395         if (!state.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
1396             return 0;
1397         }
1398 
1399         return mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(state.subscriberId);
1400     }
1401 
1402     private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet(
1403             ArrayMap<K, NetworkIdentitySet> map, K key) {
1404         NetworkIdentitySet ident = map.get(key);
1405         if (ident == null) {
1406             ident = new NetworkIdentitySet();
1407             map.put(key, ident);
1408         }
1409         return ident;
1410     }
1411 
1412     @GuardedBy("mStatsLock")
1413     private void recordSnapshotLocked(long currentTime) throws RemoteException {
1414         // snapshot and record current counters; read UID stats first to
1415         // avoid over counting dev stats.
1416         Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotUid");
1417         final NetworkStats uidSnapshot = getNetworkStatsUidDetail(INTERFACES_ALL);
1418         Trace.traceEnd(TRACE_TAG_NETWORK);
1419         Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotXt");
1420         final NetworkStats xtSnapshot = readNetworkStatsSummaryXt();
1421         Trace.traceEnd(TRACE_TAG_NETWORK);
1422         Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotDev");
1423         final NetworkStats devSnapshot = readNetworkStatsSummaryDev();
1424         Trace.traceEnd(TRACE_TAG_NETWORK);
1425 
1426         // Tethering snapshot for dev and xt stats. Counts per-interface data from tethering stats
1427         // providers that isn't already counted by dev and XT stats.
1428         Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotTether");
1429         final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
1430         Trace.traceEnd(TRACE_TAG_NETWORK);
1431         xtSnapshot.combineAllValues(tetherSnapshot);
1432         devSnapshot.combineAllValues(tetherSnapshot);
1433 
1434         // Snapshot for dev/xt stats from all custom stats providers. Counts per-interface data
1435         // from stats providers that isn't already counted by dev and XT stats.
1436         Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotStatsProvider");
1437         final NetworkStats providersnapshot = getNetworkStatsFromProviders(STATS_PER_IFACE);
1438         Trace.traceEnd(TRACE_TAG_NETWORK);
1439         xtSnapshot.combineAllValues(providersnapshot);
1440         devSnapshot.combineAllValues(providersnapshot);
1441 
1442         // For xt/dev, we pass a null VPN array because usage is aggregated by UID, so VPN traffic
1443         // can't be reattributed to responsible apps.
1444         Trace.traceBegin(TRACE_TAG_NETWORK, "recordDev");
1445         mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
1446         Trace.traceEnd(TRACE_TAG_NETWORK);
1447         Trace.traceBegin(TRACE_TAG_NETWORK, "recordXt");
1448         mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, currentTime);
1449         Trace.traceEnd(TRACE_TAG_NETWORK);
1450 
1451         // For per-UID stats, pass the VPN info so VPN traffic is reattributed to responsible apps.
1452         Trace.traceBegin(TRACE_TAG_NETWORK, "recordUid");
1453         mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
1454         Trace.traceEnd(TRACE_TAG_NETWORK);
1455         Trace.traceBegin(TRACE_TAG_NETWORK, "recordUidTag");
1456         mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
1457         Trace.traceEnd(TRACE_TAG_NETWORK);
1458 
1459         // We need to make copies of member fields that are sent to the observer to avoid
1460         // a race condition between the service handler thread and the observer's
1461         mStatsObservers.updateStats(xtSnapshot, uidSnapshot, new ArrayMap<>(mActiveIfaces),
1462                 new ArrayMap<>(mActiveUidIfaces), currentTime);
1463     }
1464 
1465     /**
1466      * Bootstrap initial stats snapshot, usually during {@link #systemReady()}
1467      * so we have baseline values without double-counting.
1468      */
1469     @GuardedBy("mStatsLock")
1470     private void bootstrapStatsLocked() {
1471         final long currentTime = mClock.millis();
1472 
1473         try {
1474             recordSnapshotLocked(currentTime);
1475         } catch (IllegalStateException e) {
1476             Slog.w(TAG, "problem reading network stats: " + e);
1477         } catch (RemoteException e) {
1478             // ignored; service lives in system_server
1479         }
1480     }
1481 
1482     private void performPoll(int flags) {
1483         synchronized (mStatsLock) {
1484             mWakeLock.acquire();
1485 
1486             try {
1487                 performPollLocked(flags);
1488             } finally {
1489                 mWakeLock.release();
1490             }
1491         }
1492     }
1493 
1494     /**
1495      * Periodic poll operation, reading current statistics and recording into
1496      * {@link NetworkStatsHistory}.
1497      */
1498     @GuardedBy("mStatsLock")
1499     private void performPollLocked(int flags) {
1500         if (!mSystemReady) return;
1501         if (LOGV) Slog.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")");
1502         Trace.traceBegin(TRACE_TAG_NETWORK, "performPollLocked");
1503 
1504         final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0;
1505         final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
1506         final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
1507 
1508         // Request asynchronous stats update from all providers for next poll. And wait a bit of
1509         // time to allow providers report-in given that normally binder call should be fast. Note
1510         // that size of list might be changed because addition/removing at the same time. For
1511         // addition, the stats of the missed provider can only be collected in next poll;
1512         // for removal, wait might take up to MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS
1513         // once that happened.
1514         // TODO: request with a valid token.
1515         Trace.traceBegin(TRACE_TAG_NETWORK, "provider.requestStatsUpdate");
1516         final int registeredCallbackCount = mStatsProviderCbList.size();
1517         mStatsProviderSem.drainPermits();
1518         invokeForAllStatsProviderCallbacks(
1519                 (cb) -> cb.mProvider.onRequestStatsUpdate(0 /* unused */));
1520         try {
1521             mStatsProviderSem.tryAcquire(registeredCallbackCount,
1522                     MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS, TimeUnit.MILLISECONDS);
1523         } catch (InterruptedException e) {
1524             // Strictly speaking it's possible a provider happened to deliver between the timeout
1525             // and the log, and that doesn't matter too much as this is just a debug log.
1526             Log.d(TAG, "requestStatsUpdate - providers responded "
1527                     + mStatsProviderSem.availablePermits()
1528                     + "/" + registeredCallbackCount + " : " + e);
1529         }
1530         Trace.traceEnd(TRACE_TAG_NETWORK);
1531 
1532         // TODO: consider marking "untrusted" times in historical stats
1533         final long currentTime = mClock.millis();
1534 
1535         try {
1536             recordSnapshotLocked(currentTime);
1537         } catch (IllegalStateException e) {
1538             Log.wtf(TAG, "problem reading network stats", e);
1539             return;
1540         } catch (RemoteException e) {
1541             // ignored; service lives in system_server
1542             return;
1543         }
1544 
1545         // persist any pending data depending on requested flags
1546         Trace.traceBegin(TRACE_TAG_NETWORK, "[persisting]");
1547         if (persistForce) {
1548             mDevRecorder.forcePersistLocked(currentTime);
1549             mXtRecorder.forcePersistLocked(currentTime);
1550             mUidRecorder.forcePersistLocked(currentTime);
1551             mUidTagRecorder.forcePersistLocked(currentTime);
1552         } else {
1553             if (persistNetwork) {
1554                 mDevRecorder.maybePersistLocked(currentTime);
1555                 mXtRecorder.maybePersistLocked(currentTime);
1556             }
1557             if (persistUid) {
1558                 mUidRecorder.maybePersistLocked(currentTime);
1559                 mUidTagRecorder.maybePersistLocked(currentTime);
1560             }
1561         }
1562         Trace.traceEnd(TRACE_TAG_NETWORK);
1563 
1564         if (mSettings.getSampleEnabled()) {
1565             // sample stats after each full poll
1566             performSampleLocked();
1567         }
1568 
1569         // finally, dispatch updated event to any listeners
1570         mHandler.sendMessage(mHandler.obtainMessage(MSG_BROADCAST_NETWORK_STATS_UPDATED));
1571 
1572         Trace.traceEnd(TRACE_TAG_NETWORK);
1573     }
1574 
1575     /**
1576      * Sample recent statistics summary into {@link EventLog}.
1577      */
1578     @GuardedBy("mStatsLock")
1579     private void performSampleLocked() {
1580         // TODO: migrate trustedtime fixes to separate binary log events
1581         final long currentTime = mClock.millis();
1582 
1583         NetworkTemplate template;
1584         NetworkStats.Entry devTotal;
1585         NetworkStats.Entry xtTotal;
1586         NetworkStats.Entry uidTotal;
1587 
1588         // collect mobile sample
1589         template = buildTemplateMobileWildcard();
1590         devTotal = mDevRecorder.getTotalSinceBootLocked(template);
1591         xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
1592         uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
1593 
1594         EventLogTags.writeNetstatsMobileSample(
1595                 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
1596                 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
1597                 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
1598                 currentTime);
1599 
1600         // collect wifi sample
1601         template = buildTemplateWifiWildcard();
1602         devTotal = mDevRecorder.getTotalSinceBootLocked(template);
1603         xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
1604         uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
1605 
1606         EventLogTags.writeNetstatsWifiSample(
1607                 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
1608                 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
1609                 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
1610                 currentTime);
1611     }
1612 
1613     /**
1614      * Clean up {@link #mUidRecorder} after UID is removed.
1615      */
1616     @GuardedBy("mStatsLock")
1617     private void removeUidsLocked(int... uids) {
1618         if (LOGV) Slog.v(TAG, "removeUidsLocked() for UIDs " + Arrays.toString(uids));
1619 
1620         // Perform one last poll before removing
1621         performPollLocked(FLAG_PERSIST_ALL);
1622 
1623         mUidRecorder.removeUidsLocked(uids);
1624         mUidTagRecorder.removeUidsLocked(uids);
1625 
1626         // Clear kernel stats associated with UID
1627         for (int uid : uids) {
1628             resetKernelUidStats(uid);
1629         }
1630     }
1631 
1632     /**
1633      * Clean up {@link #mUidRecorder} after user is removed.
1634      */
1635     @GuardedBy("mStatsLock")
1636     private void removeUserLocked(int userId) {
1637         if (LOGV) Slog.v(TAG, "removeUserLocked() for userId=" + userId);
1638 
1639         // Build list of UIDs that we should clean up
1640         int[] uids = new int[0];
1641         final List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
1642                 PackageManager.MATCH_ANY_USER
1643                 | PackageManager.MATCH_DISABLED_COMPONENTS);
1644         for (ApplicationInfo app : apps) {
1645             final int uid = UserHandle.getUid(userId, app.uid);
1646             uids = ArrayUtils.appendInt(uids, uid);
1647         }
1648 
1649         removeUidsLocked(uids);
1650     }
1651 
1652     private class NetworkStatsManagerInternalImpl extends NetworkStatsManagerInternal {
1653         @Override
1654         public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
1655             Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkTotalBytes");
1656             try {
1657                 return NetworkStatsService.this.getNetworkTotalBytes(template, start, end);
1658             } finally {
1659                 Trace.traceEnd(TRACE_TAG_NETWORK);
1660             }
1661         }
1662 
1663         @Override
1664         public NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
1665             Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkUidBytes");
1666             try {
1667                 return NetworkStatsService.this.getNetworkUidBytes(template, start, end);
1668             } finally {
1669                 Trace.traceEnd(TRACE_TAG_NETWORK);
1670             }
1671         }
1672 
1673         @Override
1674         public void setUidForeground(int uid, boolean uidForeground) {
1675             NetworkStatsService.this.setUidForeground(uid, uidForeground);
1676         }
1677 
1678         @Override
1679         public void advisePersistThreshold(long thresholdBytes) {
1680             NetworkStatsService.this.advisePersistThreshold(thresholdBytes);
1681         }
1682 
1683         @Override
1684         public void forceUpdate() {
1685             NetworkStatsService.this.forceUpdate();
1686         }
1687 
1688         @Override
1689         public void setStatsProviderLimitAsync(@NonNull String iface, long quota) {
1690             if (LOGV) Slog.v(TAG, "setStatsProviderLimitAsync(" + iface + "," + quota + ")");
1691             invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetLimit(iface, quota));
1692         }
1693     }
1694 
1695     @Override
1696     protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) {
1697         if (!DumpUtils.checkDumpPermission(mContext, TAG, rawWriter)) return;
1698 
1699         long duration = DateUtils.DAY_IN_MILLIS;
1700         final HashSet<String> argSet = new HashSet<String>();
1701         for (String arg : args) {
1702             argSet.add(arg);
1703 
1704             if (arg.startsWith("--duration=")) {
1705                 try {
1706                     duration = Long.parseLong(arg.substring(11));
1707                 } catch (NumberFormatException ignored) {
1708                 }
1709             }
1710         }
1711 
1712         // usage: dumpsys netstats --full --uid --tag --poll --checkin
1713         final boolean poll = argSet.contains("--poll") || argSet.contains("poll");
1714         final boolean checkin = argSet.contains("--checkin");
1715         final boolean fullHistory = argSet.contains("--full") || argSet.contains("full");
1716         final boolean includeUid = argSet.contains("--uid") || argSet.contains("detail");
1717         final boolean includeTag = argSet.contains("--tag") || argSet.contains("detail");
1718 
1719         final IndentingPrintWriter pw = new IndentingPrintWriter(rawWriter, "  ");
1720 
1721         synchronized (mStatsLock) {
1722             if (args.length > 0 && "--proto".equals(args[0])) {
1723                 // In this case ignore all other arguments.
1724                 dumpProtoLocked(fd);
1725                 return;
1726             }
1727 
1728             if (poll) {
1729                 performPollLocked(FLAG_PERSIST_ALL | FLAG_PERSIST_FORCE);
1730                 pw.println("Forced poll");
1731                 return;
1732             }
1733 
1734             if (checkin) {
1735                 final long end = System.currentTimeMillis();
1736                 final long start = end - duration;
1737 
1738                 pw.print("v1,");
1739                 pw.print(start / SECOND_IN_MILLIS); pw.print(',');
1740                 pw.print(end / SECOND_IN_MILLIS); pw.println();
1741 
1742                 pw.println("xt");
1743                 mXtRecorder.dumpCheckin(rawWriter, start, end);
1744 
1745                 if (includeUid) {
1746                     pw.println("uid");
1747                     mUidRecorder.dumpCheckin(rawWriter, start, end);
1748                 }
1749                 if (includeTag) {
1750                     pw.println("tag");
1751                     mUidTagRecorder.dumpCheckin(rawWriter, start, end);
1752                 }
1753                 return;
1754             }
1755 
1756             pw.println("Configs:");
1757             pw.increaseIndent();
1758             pw.printPair(NETSTATS_COMBINE_SUBTYPE_ENABLED, mSettings.getCombineSubtypeEnabled());
1759             pw.println();
1760             pw.decreaseIndent();
1761 
1762             pw.println("Active interfaces:");
1763             pw.increaseIndent();
1764             for (int i = 0; i < mActiveIfaces.size(); i++) {
1765                 pw.printPair("iface", mActiveIfaces.keyAt(i));
1766                 pw.printPair("ident", mActiveIfaces.valueAt(i));
1767                 pw.println();
1768             }
1769             pw.decreaseIndent();
1770 
1771             pw.println("Active UID interfaces:");
1772             pw.increaseIndent();
1773             for (int i = 0; i < mActiveUidIfaces.size(); i++) {
1774                 pw.printPair("iface", mActiveUidIfaces.keyAt(i));
1775                 pw.printPair("ident", mActiveUidIfaces.valueAt(i));
1776                 pw.println();
1777             }
1778             pw.decreaseIndent();
1779 
1780             // Get the top openSession callers
1781             final SparseIntArray calls;
1782             synchronized (mOpenSessionCallsPerUid) {
1783                 calls = mOpenSessionCallsPerUid.clone();
1784             }
1785 
1786             final int N = calls.size();
1787             final long[] values = new long[N];
1788             for (int j = 0; j < N; j++) {
1789                 values[j] = ((long) calls.valueAt(j) << 32) | calls.keyAt(j);
1790             }
1791             Arrays.sort(values);
1792 
1793             pw.println("Top openSession callers (uid=count):");
1794             pw.increaseIndent();
1795             final int end = Math.max(0, N - DUMP_STATS_SESSION_COUNT);
1796             for (int j = N - 1; j >= end; j--) {
1797                 final int uid = (int) (values[j] & 0xffffffff);
1798                 final int count = (int) (values[j] >> 32);
1799                 pw.print(uid); pw.print("="); pw.println(count);
1800             }
1801             pw.decreaseIndent();
1802             pw.println();
1803 
1804             pw.println("Stats Providers:");
1805             pw.increaseIndent();
1806             invokeForAllStatsProviderCallbacks((cb) -> {
1807                 pw.println(cb.mTag + " Xt:");
1808                 pw.increaseIndent();
1809                 pw.print(cb.getCachedStats(STATS_PER_IFACE).toString());
1810                 pw.decreaseIndent();
1811                 if (includeUid) {
1812                     pw.println(cb.mTag + " Uid:");
1813                     pw.increaseIndent();
1814                     pw.print(cb.getCachedStats(STATS_PER_UID).toString());
1815                     pw.decreaseIndent();
1816                 }
1817             });
1818             pw.decreaseIndent();
1819 
1820             pw.println("Dev stats:");
1821             pw.increaseIndent();
1822             mDevRecorder.dumpLocked(pw, fullHistory);
1823             pw.decreaseIndent();
1824 
1825             pw.println("Xt stats:");
1826             pw.increaseIndent();
1827             mXtRecorder.dumpLocked(pw, fullHistory);
1828             pw.decreaseIndent();
1829 
1830             if (includeUid) {
1831                 pw.println("UID stats:");
1832                 pw.increaseIndent();
1833                 mUidRecorder.dumpLocked(pw, fullHistory);
1834                 pw.decreaseIndent();
1835             }
1836 
1837             if (includeTag) {
1838                 pw.println("UID tag stats:");
1839                 pw.increaseIndent();
1840                 mUidTagRecorder.dumpLocked(pw, fullHistory);
1841                 pw.decreaseIndent();
1842             }
1843         }
1844     }
1845 
1846     @GuardedBy("mStatsLock")
1847     private void dumpProtoLocked(FileDescriptor fd) {
1848         final ProtoOutputStream proto = new ProtoOutputStream(fd);
1849 
1850         // TODO Right now it writes all history.  Should it limit to the "since-boot" log?
1851 
1852         dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES, mActiveIfaces);
1853         dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES, mActiveUidIfaces);
1854         mDevRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS);
1855         mXtRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.XT_STATS);
1856         mUidRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.UID_STATS);
1857         mUidTagRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.UID_TAG_STATS);
1858 
1859         proto.flush();
1860     }
1861 
1862     private static void dumpInterfaces(ProtoOutputStream proto, long tag,
1863             ArrayMap<String, NetworkIdentitySet> ifaces) {
1864         for (int i = 0; i < ifaces.size(); i++) {
1865             final long start = proto.start(tag);
1866 
1867             proto.write(NetworkInterfaceProto.INTERFACE, ifaces.keyAt(i));
1868             ifaces.valueAt(i).writeToProto(proto, NetworkInterfaceProto.IDENTITIES);
1869 
1870             proto.end(start);
1871         }
1872     }
1873 
1874     private NetworkStats readNetworkStatsSummaryDev() {
1875         try {
1876             return mStatsFactory.readNetworkStatsSummaryDev();
1877         } catch (IOException e) {
1878             throw new IllegalStateException(e);
1879         }
1880     }
1881 
1882     private NetworkStats readNetworkStatsSummaryXt() {
1883         try {
1884             return mStatsFactory.readNetworkStatsSummaryXt();
1885         } catch (IOException e) {
1886             throw new IllegalStateException(e);
1887         }
1888     }
1889 
1890     private NetworkStats readNetworkStatsUidDetail(int uid, String[] ifaces, int tag) {
1891         try {
1892             return mStatsFactory.readNetworkStatsDetail(uid, ifaces, tag);
1893         } catch (IOException e) {
1894             throw new IllegalStateException(e);
1895         }
1896     }
1897 
1898     /**
1899      * Return snapshot of current UID statistics, including any
1900      * {@link TrafficStats#UID_TETHERING}, video calling data usage, and {@link #mUidOperations}
1901      * values.
1902      *
1903      * @param ifaces A list of interfaces the stats should be restricted to, or
1904      *               {@link NetworkStats#INTERFACES_ALL}.
1905      */
1906     private NetworkStats getNetworkStatsUidDetail(String[] ifaces)
1907             throws RemoteException {
1908         final NetworkStats uidSnapshot = readNetworkStatsUidDetail(UID_ALL,  ifaces, TAG_ALL);
1909 
1910         // fold tethering stats and operations into uid snapshot
1911         final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_UID);
1912         tetherSnapshot.filter(UID_ALL, ifaces, TAG_ALL);
1913         mStatsFactory.apply464xlatAdjustments(uidSnapshot, tetherSnapshot);
1914         uidSnapshot.combineAllValues(tetherSnapshot);
1915 
1916         // get a stale copy of uid stats snapshot provided by providers.
1917         final NetworkStats providerStats = getNetworkStatsFromProviders(STATS_PER_UID);
1918         providerStats.filter(UID_ALL, ifaces, TAG_ALL);
1919         mStatsFactory.apply464xlatAdjustments(uidSnapshot, providerStats);
1920         uidSnapshot.combineAllValues(providerStats);
1921 
1922         uidSnapshot.combineAllValues(mUidOperations);
1923 
1924         return uidSnapshot;
1925     }
1926 
1927     /**
1928      * Return snapshot of current tethering statistics. Will return empty
1929      * {@link NetworkStats} if any problems are encountered.
1930      */
1931     private NetworkStats getNetworkStatsTethering(int how) throws RemoteException {
1932         try {
1933             return mNetworkManager.getNetworkStatsTethering(how);
1934         } catch (IllegalStateException e) {
1935             Log.wtf(TAG, "problem reading network stats", e);
1936             return new NetworkStats(0L, 10);
1937         }
1938     }
1939 
1940     // TODO: It is copied from ConnectivityService, consider refactor these check permission
1941     //  functions to a proper util.
1942     private boolean checkAnyPermissionOf(String... permissions) {
1943         for (String permission : permissions) {
1944             if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
1945                 return true;
1946             }
1947         }
1948         return false;
1949     }
1950 
1951     private void enforceAnyPermissionOf(String... permissions) {
1952         if (!checkAnyPermissionOf(permissions)) {
1953             throw new SecurityException("Requires one of the following permissions: "
1954                     + String.join(", ", permissions) + ".");
1955         }
1956     }
1957 
1958     /**
1959      * Registers a custom provider of {@link android.net.NetworkStats} to combine the network
1960      * statistics that cannot be seen by the kernel to system. To unregister, invoke the
1961      * {@code unregister()} of the returned callback.
1962      *
1963      * @param tag a human readable identifier of the custom network stats provider.
1964      * @param provider the {@link INetworkStatsProvider} binder corresponding to the
1965      *                 {@link NetworkStatsProvider} to be registered.
1966      *
1967      * @return a {@link INetworkStatsProviderCallback} binder
1968      *         interface, which can be used to report events to the system.
1969      */
1970     public @NonNull INetworkStatsProviderCallback registerNetworkStatsProvider(
1971             @NonNull String tag, @NonNull INetworkStatsProvider provider) {
1972         enforceAnyPermissionOf(NETWORK_STATS_PROVIDER,
1973                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
1974         Objects.requireNonNull(provider, "provider is null");
1975         Objects.requireNonNull(tag, "tag is null");
1976         try {
1977             NetworkStatsProviderCallbackImpl callback = new NetworkStatsProviderCallbackImpl(
1978                     tag, provider, mStatsProviderSem, mAlertObserver,
1979                     mStatsProviderCbList);
1980             mStatsProviderCbList.add(callback);
1981             Log.d(TAG, "registerNetworkStatsProvider from " + callback.mTag + " uid/pid="
1982                     + getCallingUid() + "/" + getCallingPid());
1983             return callback;
1984         } catch (RemoteException e) {
1985             Log.e(TAG, "registerNetworkStatsProvider failed", e);
1986         }
1987         return null;
1988     }
1989 
1990     // Collect stats from local cache of providers.
1991     private @NonNull NetworkStats getNetworkStatsFromProviders(int how) {
1992         final NetworkStats ret = new NetworkStats(0L, 0);
1993         invokeForAllStatsProviderCallbacks((cb) -> ret.combineAllValues(cb.getCachedStats(how)));
1994         return ret;
1995     }
1996 
1997     @FunctionalInterface
1998     private interface ThrowingConsumer<S, T extends Throwable> {
1999         void accept(S s) throws T;
2000     }
2001 
2002     private void invokeForAllStatsProviderCallbacks(
2003             @NonNull ThrowingConsumer<NetworkStatsProviderCallbackImpl, RemoteException> task) {
2004         for (final NetworkStatsProviderCallbackImpl cb : mStatsProviderCbList) {
2005             try {
2006                 task.accept(cb);
2007             } catch (RemoteException e) {
2008                 Log.e(TAG, "Fail to broadcast to provider: " + cb.mTag, e);
2009             }
2010         }
2011     }
2012 
2013     private static class NetworkStatsProviderCallbackImpl extends INetworkStatsProviderCallback.Stub
2014             implements IBinder.DeathRecipient {
2015         @NonNull final String mTag;
2016 
2017         @NonNull final INetworkStatsProvider mProvider;
2018         @NonNull private final Semaphore mSemaphore;
2019         @NonNull final INetworkManagementEventObserver mAlertObserver;
2020         @NonNull final CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList;
2021 
2022         @NonNull private final Object mProviderStatsLock = new Object();
2023 
2024         @GuardedBy("mProviderStatsLock")
2025         // Track STATS_PER_IFACE and STATS_PER_UID separately.
2026         private final NetworkStats mIfaceStats = new NetworkStats(0L, 0);
2027         @GuardedBy("mProviderStatsLock")
2028         private final NetworkStats mUidStats = new NetworkStats(0L, 0);
2029 
2030         NetworkStatsProviderCallbackImpl(
2031                 @NonNull String tag, @NonNull INetworkStatsProvider provider,
2032                 @NonNull Semaphore semaphore,
2033                 @NonNull INetworkManagementEventObserver alertObserver,
2034                 @NonNull CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> cbList)
2035                 throws RemoteException {
2036             mTag = tag;
2037             mProvider = provider;
2038             mProvider.asBinder().linkToDeath(this, 0);
2039             mSemaphore = semaphore;
2040             mAlertObserver = alertObserver;
2041             mStatsProviderCbList = cbList;
2042         }
2043 
2044         @NonNull
2045         public NetworkStats getCachedStats(int how) {
2046             synchronized (mProviderStatsLock) {
2047                 NetworkStats stats;
2048                 switch (how) {
2049                     case STATS_PER_IFACE:
2050                         stats = mIfaceStats;
2051                         break;
2052                     case STATS_PER_UID:
2053                         stats = mUidStats;
2054                         break;
2055                     default:
2056                         throw new IllegalArgumentException("Invalid type: " + how);
2057                 }
2058                 // Callers might be able to mutate the returned object. Return a defensive copy
2059                 // instead of local reference.
2060                 return stats.clone();
2061             }
2062         }
2063 
2064         @Override
2065         public void notifyStatsUpdated(int token, @Nullable NetworkStats ifaceStats,
2066                 @Nullable NetworkStats uidStats) {
2067             // TODO: 1. Use token to map ifaces to correct NetworkIdentity.
2068             //       2. Store the difference and store it directly to the recorder.
2069             synchronized (mProviderStatsLock) {
2070                 if (ifaceStats != null) mIfaceStats.combineAllValues(ifaceStats);
2071                 if (uidStats != null) mUidStats.combineAllValues(uidStats);
2072             }
2073             mSemaphore.release();
2074         }
2075 
2076         @Override
2077         public void notifyAlertReached() throws RemoteException {
2078             mAlertObserver.limitReached(LIMIT_GLOBAL_ALERT, null /* unused */);
2079         }
2080 
2081         @Override
2082         public void notifyLimitReached() {
2083             Log.d(TAG, mTag + ": onLimitReached");
2084             LocalServices.getService(NetworkPolicyManagerInternal.class)
2085                     .onStatsProviderLimitReached(mTag);
2086         }
2087 
2088         @Override
2089         public void binderDied() {
2090             Log.d(TAG, mTag + ": binderDied");
2091             mStatsProviderCbList.remove(this);
2092         }
2093 
2094         @Override
2095         public void unregister() {
2096             Log.d(TAG, mTag + ": unregister");
2097             mStatsProviderCbList.remove(this);
2098         }
2099 
2100     }
2101 
2102     private void assertSystemReady() {
2103         if (!mSystemReady) {
2104             throw new IllegalStateException("System not ready");
2105         }
2106     }
2107 
2108     private class DropBoxNonMonotonicObserver implements NonMonotonicObserver<String> {
2109         @Override
2110         public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
2111                 int rightIndex, String cookie) {
2112             Log.w(TAG, "Found non-monotonic values; saving to dropbox");
2113 
2114             // record error for debugging
2115             final StringBuilder builder = new StringBuilder();
2116             builder.append("found non-monotonic " + cookie + " values at left[" + leftIndex
2117                     + "] - right[" + rightIndex + "]\n");
2118             builder.append("left=").append(left).append('\n');
2119             builder.append("right=").append(right).append('\n');
2120 
2121             mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
2122                     builder.toString());
2123         }
2124 
2125         @Override
2126         public void foundNonMonotonic(
2127                 NetworkStats stats, int statsIndex, String cookie) {
2128             Log.w(TAG, "Found non-monotonic values; saving to dropbox");
2129 
2130             final StringBuilder builder = new StringBuilder();
2131             builder.append("Found non-monotonic " + cookie + " values at [" + statsIndex + "]\n");
2132             builder.append("stats=").append(stats).append('\n');
2133 
2134             mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
2135                     builder.toString());
2136         }
2137     }
2138 
2139     /**
2140      * Default external settings that read from
2141      * {@link android.provider.Settings.Global}.
2142      */
2143     private static class DefaultNetworkStatsSettings implements NetworkStatsSettings {
2144         private final ContentResolver mResolver;
2145 
2146         public DefaultNetworkStatsSettings(Context context) {
2147             mResolver = Objects.requireNonNull(context.getContentResolver());
2148             // TODO: adjust these timings for production builds
2149         }
2150 
2151         private long getGlobalLong(String name, long def) {
2152             return Settings.Global.getLong(mResolver, name, def);
2153         }
2154         private boolean getGlobalBoolean(String name, boolean def) {
2155             final int defInt = def ? 1 : 0;
2156             return Settings.Global.getInt(mResolver, name, defInt) != 0;
2157         }
2158 
2159         @Override
2160         public long getPollInterval() {
2161             return getGlobalLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS);
2162         }
2163         @Override
2164         public long getPollDelay() {
2165             return DEFAULT_PERFORM_POLL_DELAY_MS;
2166         }
2167         @Override
2168         public long getGlobalAlertBytes(long def) {
2169             return getGlobalLong(NETSTATS_GLOBAL_ALERT_BYTES, def);
2170         }
2171         @Override
2172         public boolean getSampleEnabled() {
2173             return getGlobalBoolean(NETSTATS_SAMPLE_ENABLED, true);
2174         }
2175         @Override
2176         public boolean getAugmentEnabled() {
2177             return getGlobalBoolean(NETSTATS_AUGMENT_ENABLED, true);
2178         }
2179         @Override
2180         public boolean getCombineSubtypeEnabled() {
2181             return getGlobalBoolean(NETSTATS_COMBINE_SUBTYPE_ENABLED, false);
2182         }
2183         @Override
2184         public Config getDevConfig() {
2185             return new Config(getGlobalLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
2186                     getGlobalLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
2187                     getGlobalLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS));
2188         }
2189         @Override
2190         public Config getXtConfig() {
2191             return getDevConfig();
2192         }
2193         @Override
2194         public Config getUidConfig() {
2195             return new Config(getGlobalLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
2196                     getGlobalLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS),
2197                     getGlobalLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS));
2198         }
2199         @Override
2200         public Config getUidTagConfig() {
2201             return new Config(getGlobalLong(NETSTATS_UID_TAG_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
2202                     getGlobalLong(NETSTATS_UID_TAG_ROTATE_AGE, 5 * DAY_IN_MILLIS),
2203                     getGlobalLong(NETSTATS_UID_TAG_DELETE_AGE, 15 * DAY_IN_MILLIS));
2204         }
2205         @Override
2206         public long getDevPersistBytes(long def) {
2207             return getGlobalLong(NETSTATS_DEV_PERSIST_BYTES, def);
2208         }
2209         @Override
2210         public long getXtPersistBytes(long def) {
2211             return getDevPersistBytes(def);
2212         }
2213         @Override
2214         public long getUidPersistBytes(long def) {
2215             return getGlobalLong(NETSTATS_UID_PERSIST_BYTES, def);
2216         }
2217         @Override
2218         public long getUidTagPersistBytes(long def) {
2219             return getGlobalLong(NETSTATS_UID_TAG_PERSIST_BYTES, def);
2220         }
2221     }
2222 
2223     private static int TYPE_RX_BYTES;
2224     private static int TYPE_RX_PACKETS;
2225     private static int TYPE_TX_BYTES;
2226     private static int TYPE_TX_PACKETS;
2227     private static int TYPE_TCP_RX_PACKETS;
2228     private static int TYPE_TCP_TX_PACKETS;
2229 
2230     private static native long nativeGetTotalStat(int type, boolean useBpfStats);
2231     private static native long nativeGetIfaceStat(String iface, int type, boolean useBpfStats);
2232     private static native long nativeGetUidStat(int uid, int type, boolean useBpfStats);
2233 }
2234