Home | History | Annotate | Download | only in net
      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.CONNECTIVITY_INTERNAL;
     21 import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
     22 import static android.content.Intent.ACTION_SHUTDOWN;
     23 import static android.content.Intent.ACTION_UID_REMOVED;
     24 import static android.content.Intent.ACTION_USER_REMOVED;
     25 import static android.content.Intent.EXTRA_UID;
     26 import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
     27 import static android.net.ConnectivityManager.isNetworkTypeMobile;
     28 import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
     29 import static android.net.NetworkStats.IFACE_ALL;
     30 import static android.net.NetworkStats.INTERFACES_ALL;
     31 import static android.net.NetworkStats.METERED_ALL;
     32 import static android.net.NetworkStats.ROAMING_ALL;
     33 import static android.net.NetworkStats.SET_ALL;
     34 import static android.net.NetworkStats.SET_DEFAULT;
     35 import static android.net.NetworkStats.SET_FOREGROUND;
     36 import static android.net.NetworkStats.STATS_PER_IFACE;
     37 import static android.net.NetworkStats.STATS_PER_UID;
     38 import static android.net.NetworkStats.TAG_ALL;
     39 import static android.net.NetworkStats.TAG_NONE;
     40 import static android.net.NetworkStats.UID_ALL;
     41 import static android.net.NetworkStatsHistory.FIELD_ALL;
     42 import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
     43 import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
     44 import static android.net.TrafficStats.KB_IN_BYTES;
     45 import static android.net.TrafficStats.MB_IN_BYTES;
     46 import static android.os.Trace.TRACE_TAG_NETWORK;
     47 import static android.provider.Settings.Global.NETSTATS_AUGMENT_ENABLED;
     48 import static android.provider.Settings.Global.NETSTATS_DEV_BUCKET_DURATION;
     49 import static android.provider.Settings.Global.NETSTATS_DEV_DELETE_AGE;
     50 import static android.provider.Settings.Global.NETSTATS_DEV_PERSIST_BYTES;
     51 import static android.provider.Settings.Global.NETSTATS_DEV_ROTATE_AGE;
     52 import static android.provider.Settings.Global.NETSTATS_GLOBAL_ALERT_BYTES;
     53 import static android.provider.Settings.Global.NETSTATS_POLL_INTERVAL;
     54 import static android.provider.Settings.Global.NETSTATS_SAMPLE_ENABLED;
     55 import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION;
     56 import static android.provider.Settings.Global.NETSTATS_UID_DELETE_AGE;
     57 import static android.provider.Settings.Global.NETSTATS_UID_PERSIST_BYTES;
     58 import static android.provider.Settings.Global.NETSTATS_UID_ROTATE_AGE;
     59 import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION;
     60 import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
     61 import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
     62 import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
     63 import static android.text.format.DateUtils.DAY_IN_MILLIS;
     64 import static android.text.format.DateUtils.HOUR_IN_MILLIS;
     65 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
     66 import static android.text.format.DateUtils.SECOND_IN_MILLIS;
     67 
     68 import static com.android.internal.util.Preconditions.checkNotNull;
     69 import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
     70 import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
     71 import static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet;
     72 
     73 import android.annotation.NonNull;
     74 import android.app.AlarmManager;
     75 import android.app.PendingIntent;
     76 import android.app.usage.NetworkStatsManager;
     77 import android.content.BroadcastReceiver;
     78 import android.content.ContentResolver;
     79 import android.content.Context;
     80 import android.content.Intent;
     81 import android.content.IntentFilter;
     82 import android.content.pm.ApplicationInfo;
     83 import android.content.pm.PackageManager;
     84 import android.net.DataUsageRequest;
     85 import android.net.IConnectivityManager;
     86 import android.net.INetworkManagementEventObserver;
     87 import android.net.INetworkStatsService;
     88 import android.net.INetworkStatsSession;
     89 import android.net.LinkProperties;
     90 import android.net.Network;
     91 import android.net.NetworkCapabilities;
     92 import android.net.NetworkIdentity;
     93 import android.net.NetworkInfo;
     94 import android.net.NetworkState;
     95 import android.net.NetworkStats;
     96 import android.net.NetworkStats.NonMonotonicObserver;
     97 import android.net.NetworkStatsHistory;
     98 import android.net.NetworkTemplate;
     99 import android.net.TrafficStats;
    100 import android.os.BestClock;
    101 import android.os.Binder;
    102 import android.os.DropBoxManager;
    103 import android.os.Environment;
    104 import android.os.Handler;
    105 import android.os.HandlerThread;
    106 import android.os.IBinder;
    107 import android.os.INetworkManagementService;
    108 import android.os.Message;
    109 import android.os.Messenger;
    110 import android.os.PowerManager;
    111 import android.os.RemoteException;
    112 import android.os.SystemClock;
    113 import android.os.Trace;
    114 import android.os.UserHandle;
    115 import android.provider.Settings;
    116 import android.provider.Settings.Global;
    117 import android.service.NetworkInterfaceProto;
    118 import android.service.NetworkStatsServiceDumpProto;
    119 import android.telephony.SubscriptionPlan;
    120 import android.telephony.TelephonyManager;
    121 import android.text.format.DateUtils;
    122 import android.util.ArrayMap;
    123 import android.util.ArraySet;
    124 import android.util.EventLog;
    125 import android.util.Log;
    126 import android.util.MathUtils;
    127 import android.util.Slog;
    128 import android.util.SparseIntArray;
    129 import android.util.proto.ProtoOutputStream;
    130 
    131 import com.android.internal.annotations.GuardedBy;
    132 import com.android.internal.annotations.VisibleForTesting;
    133 import com.android.internal.net.NetworkStatsFactory;
    134 import com.android.internal.net.VpnInfo;
    135 import com.android.internal.util.ArrayUtils;
    136 import com.android.internal.util.DumpUtils;
    137 import com.android.internal.util.FileRotator;
    138 import com.android.internal.util.IndentingPrintWriter;
    139 import com.android.server.EventLogTags;
    140 import com.android.server.LocalServices;
    141 import com.android.server.connectivity.Tethering;
    142 
    143 import java.io.File;
    144 import java.io.FileDescriptor;
    145 import java.io.IOException;
    146 import java.io.PrintWriter;
    147 import java.time.Clock;
    148 import java.time.ZoneOffset;
    149 import java.util.Arrays;
    150 import java.util.HashSet;
    151 import java.util.List;
    152 
    153 /**
    154  * Collect and persist detailed network statistics, and provide this data to
    155  * other system services.
    156  */
    157 public class NetworkStatsService extends INetworkStatsService.Stub {
    158     static final String TAG = "NetworkStats";
    159     static final boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
    160     static final boolean LOGV = Log.isLoggable(TAG, Log.VERBOSE);
    161 
    162     private static final int MSG_PERFORM_POLL = 1;
    163     private static final int MSG_UPDATE_IFACES = 2;
    164     private static final int MSG_REGISTER_GLOBAL_ALERT = 3;
    165 
    166     /** Flags to control detail level of poll event. */
    167     private static final int FLAG_PERSIST_NETWORK = 0x1;
    168     private static final int FLAG_PERSIST_UID = 0x2;
    169     private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID;
    170     private static final int FLAG_PERSIST_FORCE = 0x100;
    171 
    172     private static final String TAG_NETSTATS_ERROR = "netstats_error";
    173 
    174     private final Context mContext;
    175     private final INetworkManagementService mNetworkManager;
    176     private final AlarmManager mAlarmManager;
    177     private final Clock mClock;
    178     private final TelephonyManager mTeleManager;
    179     private final NetworkStatsSettings mSettings;
    180     private final NetworkStatsObservers mStatsObservers;
    181 
    182     private final File mSystemDir;
    183     private final File mBaseDir;
    184 
    185     private final PowerManager.WakeLock mWakeLock;
    186 
    187     private final boolean mUseBpfTrafficStats;
    188 
    189     private IConnectivityManager mConnManager;
    190 
    191     @VisibleForTesting
    192     public static final String ACTION_NETWORK_STATS_POLL =
    193             "com.android.server.action.NETWORK_STATS_POLL";
    194     public static final String ACTION_NETWORK_STATS_UPDATED =
    195             "com.android.server.action.NETWORK_STATS_UPDATED";
    196 
    197     private PendingIntent mPollIntent;
    198 
    199     private static final String PREFIX_DEV = "dev";
    200     private static final String PREFIX_XT = "xt";
    201     private static final String PREFIX_UID = "uid";
    202     private static final String PREFIX_UID_TAG = "uid_tag";
    203 
    204     /**
    205      * Virtual network interface for video telephony. This is for VT data usage counting purpose.
    206      */
    207     public static final String VT_INTERFACE = "vt_data0";
    208 
    209     /**
    210      * Settings that can be changed externally.
    211      */
    212     public interface NetworkStatsSettings {
    213         public long getPollInterval();
    214         public boolean getSampleEnabled();
    215         public boolean getAugmentEnabled();
    216 
    217         public static class Config {
    218             public final long bucketDuration;
    219             public final long rotateAgeMillis;
    220             public final long deleteAgeMillis;
    221 
    222             public Config(long bucketDuration, long rotateAgeMillis, long deleteAgeMillis) {
    223                 this.bucketDuration = bucketDuration;
    224                 this.rotateAgeMillis = rotateAgeMillis;
    225                 this.deleteAgeMillis = deleteAgeMillis;
    226             }
    227         }
    228 
    229         public Config getDevConfig();
    230         public Config getXtConfig();
    231         public Config getUidConfig();
    232         public Config getUidTagConfig();
    233 
    234         public long getGlobalAlertBytes(long def);
    235         public long getDevPersistBytes(long def);
    236         public long getXtPersistBytes(long def);
    237         public long getUidPersistBytes(long def);
    238         public long getUidTagPersistBytes(long def);
    239     }
    240 
    241     private final Object mStatsLock = new Object();
    242 
    243     /** Set of currently active ifaces. */
    244     @GuardedBy("mStatsLock")
    245     private final ArrayMap<String, NetworkIdentitySet> mActiveIfaces = new ArrayMap<>();
    246 
    247     /** Set of currently active ifaces for UID stats. */
    248     @GuardedBy("mStatsLock")
    249     private final ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces = new ArrayMap<>();
    250 
    251     /** Current default active iface. */
    252     private String mActiveIface;
    253 
    254     /** Set of any ifaces associated with mobile networks since boot. */
    255     @GuardedBy("mStatsLock")
    256     private String[] mMobileIfaces = new String[0];
    257 
    258     /** Set of all ifaces currently used by traffic that does not explicitly specify a Network. */
    259     @GuardedBy("mStatsLock")
    260     private Network[] mDefaultNetworks = new Network[0];
    261 
    262     private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
    263             new DropBoxNonMonotonicObserver();
    264 
    265     @GuardedBy("mStatsLock")
    266     private NetworkStatsRecorder mDevRecorder;
    267     @GuardedBy("mStatsLock")
    268     private NetworkStatsRecorder mXtRecorder;
    269     @GuardedBy("mStatsLock")
    270     private NetworkStatsRecorder mUidRecorder;
    271     @GuardedBy("mStatsLock")
    272     private NetworkStatsRecorder mUidTagRecorder;
    273 
    274     /** Cached {@link #mXtRecorder} stats. */
    275     @GuardedBy("mStatsLock")
    276     private NetworkStatsCollection mXtStatsCached;
    277 
    278     /** Current counter sets for each UID. */
    279     private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
    280 
    281     /** Data layer operation counters for splicing into other structures. */
    282     private NetworkStats mUidOperations = new NetworkStats(0L, 10);
    283 
    284     /** Must be set in factory by calling #setHandler. */
    285     private Handler mHandler;
    286     private Handler.Callback mHandlerCallback;
    287 
    288     private volatile boolean mSystemReady;
    289     private long mPersistThreshold = 2 * MB_IN_BYTES;
    290     private long mGlobalAlertBytes;
    291 
    292     private static final long POLL_RATE_LIMIT_MS = 15_000;
    293 
    294     private long mLastStatsSessionPoll;
    295 
    296     /** Map from UID to number of opened sessions */
    297     @GuardedBy("mOpenSessionCallsPerUid")
    298     private final SparseIntArray mOpenSessionCallsPerUid = new SparseIntArray();
    299 
    300     private final static int DUMP_STATS_SESSION_COUNT = 20;
    301 
    302     private static @NonNull File getDefaultSystemDir() {
    303         return new File(Environment.getDataDirectory(), "system");
    304     }
    305 
    306     private static @NonNull File getDefaultBaseDir() {
    307         File baseDir = new File(getDefaultSystemDir(), "netstats");
    308         baseDir.mkdirs();
    309         return baseDir;
    310     }
    311 
    312     private static @NonNull Clock getDefaultClock() {
    313         return new BestClock(ZoneOffset.UTC, SystemClock.currentNetworkTimeClock(),
    314                 Clock.systemUTC());
    315     }
    316 
    317     public static NetworkStatsService create(Context context,
    318                 INetworkManagementService networkManager) {
    319         AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    320         PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
    321         PowerManager.WakeLock wakeLock =
    322                 powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
    323 
    324         NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager,
    325                 wakeLock, getDefaultClock(), TelephonyManager.getDefault(),
    326                 new DefaultNetworkStatsSettings(context), new NetworkStatsObservers(),
    327                 getDefaultSystemDir(), getDefaultBaseDir());
    328 
    329         HandlerThread handlerThread = new HandlerThread(TAG);
    330         Handler.Callback callback = new HandlerCallback(service);
    331         handlerThread.start();
    332         Handler handler = new Handler(handlerThread.getLooper(), callback);
    333         service.setHandler(handler, callback);
    334         return service;
    335     }
    336 
    337     @VisibleForTesting
    338     NetworkStatsService(Context context, INetworkManagementService networkManager,
    339             AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock,
    340             TelephonyManager teleManager, NetworkStatsSettings settings,
    341             NetworkStatsObservers statsObservers, File systemDir, File baseDir) {
    342         mContext = checkNotNull(context, "missing Context");
    343         mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService");
    344         mAlarmManager = checkNotNull(alarmManager, "missing AlarmManager");
    345         mClock = checkNotNull(clock, "missing Clock");
    346         mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
    347         mTeleManager = checkNotNull(teleManager, "missing TelephonyManager");
    348         mWakeLock = checkNotNull(wakeLock, "missing WakeLock");
    349         mStatsObservers = checkNotNull(statsObservers, "missing NetworkStatsObservers");
    350         mSystemDir = checkNotNull(systemDir, "missing systemDir");
    351         mBaseDir = checkNotNull(baseDir, "missing baseDir");
    352         mUseBpfTrafficStats = new File("/sys/fs/bpf/traffic_uid_stats_map").exists();
    353 
    354         LocalServices.addService(NetworkStatsManagerInternal.class,
    355                 new NetworkStatsManagerInternalImpl());
    356     }
    357 
    358     @VisibleForTesting
    359     void setHandler(Handler handler, Handler.Callback callback) {
    360         mHandler = handler;
    361         mHandlerCallback = callback;
    362     }
    363 
    364     public void bindConnectivityManager(IConnectivityManager connManager) {
    365         mConnManager = checkNotNull(connManager, "missing IConnectivityManager");
    366     }
    367 
    368     public void systemReady() {
    369         mSystemReady = true;
    370 
    371         if (!isBandwidthControlEnabled()) {
    372             Slog.w(TAG, "bandwidth controls disabled, unable to track stats");
    373             return;
    374         }
    375 
    376         synchronized (mStatsLock) {
    377             // create data recorders along with historical rotators
    378             mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
    379             mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false);
    380             mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
    381             mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
    382 
    383             updatePersistThresholdsLocked();
    384 
    385             // upgrade any legacy stats, migrating them to rotated files
    386             maybeUpgradeLegacyStatsLocked();
    387 
    388             // read historical network stats from disk, since policy service
    389             // might need them right away.
    390             mXtStatsCached = mXtRecorder.getOrLoadCompleteLocked();
    391 
    392             // bootstrap initial stats to prevent double-counting later
    393             bootstrapStatsLocked();
    394         }
    395 
    396         // watch for tethering changes
    397         final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED);
    398         mContext.registerReceiver(mTetherReceiver, tetherFilter, null, mHandler);
    399 
    400         // listen for periodic polling events
    401         final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL);
    402         mContext.registerReceiver(mPollReceiver, pollFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
    403 
    404         // listen for uid removal to clean stats
    405         final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED);
    406         mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler);
    407 
    408         // listen for user changes to clean stats
    409         final IntentFilter userFilter = new IntentFilter(ACTION_USER_REMOVED);
    410         mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
    411 
    412         // persist stats during clean shutdown
    413         final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN);
    414         mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
    415 
    416         try {
    417             mNetworkManager.registerObserver(mAlertObserver);
    418         } catch (RemoteException e) {
    419             // ignored; service lives in system_server
    420         }
    421 
    422         registerPollAlarmLocked();
    423         registerGlobalAlert();
    424     }
    425 
    426     private NetworkStatsRecorder buildRecorder(
    427             String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
    428         final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
    429                 Context.DROPBOX_SERVICE);
    430         return new NetworkStatsRecorder(new FileRotator(
    431                 mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
    432                 mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags);
    433     }
    434 
    435     @GuardedBy("mStatsLock")
    436     private void shutdownLocked() {
    437         mContext.unregisterReceiver(mTetherReceiver);
    438         mContext.unregisterReceiver(mPollReceiver);
    439         mContext.unregisterReceiver(mRemovedReceiver);
    440         mContext.unregisterReceiver(mUserReceiver);
    441         mContext.unregisterReceiver(mShutdownReceiver);
    442 
    443         final long currentTime = mClock.millis();
    444 
    445         // persist any pending stats
    446         mDevRecorder.forcePersistLocked(currentTime);
    447         mXtRecorder.forcePersistLocked(currentTime);
    448         mUidRecorder.forcePersistLocked(currentTime);
    449         mUidTagRecorder.forcePersistLocked(currentTime);
    450 
    451         mSystemReady = false;
    452     }
    453 
    454     @GuardedBy("mStatsLock")
    455     private void maybeUpgradeLegacyStatsLocked() {
    456         File file;
    457         try {
    458             file = new File(mSystemDir, "netstats.bin");
    459             if (file.exists()) {
    460                 mDevRecorder.importLegacyNetworkLocked(file);
    461                 file.delete();
    462             }
    463 
    464             file = new File(mSystemDir, "netstats_xt.bin");
    465             if (file.exists()) {
    466                 file.delete();
    467             }
    468 
    469             file = new File(mSystemDir, "netstats_uid.bin");
    470             if (file.exists()) {
    471                 mUidRecorder.importLegacyUidLocked(file);
    472                 mUidTagRecorder.importLegacyUidLocked(file);
    473                 file.delete();
    474             }
    475         } catch (IOException e) {
    476             Log.wtf(TAG, "problem during legacy upgrade", e);
    477         } catch (OutOfMemoryError e) {
    478             Log.wtf(TAG, "problem during legacy upgrade", e);
    479         }
    480     }
    481 
    482     /**
    483      * Clear any existing {@link #ACTION_NETWORK_STATS_POLL} alarms, and
    484      * reschedule based on current {@link NetworkStatsSettings#getPollInterval()}.
    485      */
    486     private void registerPollAlarmLocked() {
    487         if (mPollIntent != null) {
    488             mAlarmManager.cancel(mPollIntent);
    489         }
    490 
    491         mPollIntent = PendingIntent.getBroadcast(
    492                 mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
    493 
    494         final long currentRealtime = SystemClock.elapsedRealtime();
    495         mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
    496                 mSettings.getPollInterval(), mPollIntent);
    497     }
    498 
    499     /**
    500      * Register for a global alert that is delivered through
    501      * {@link INetworkManagementEventObserver} once a threshold amount of data
    502      * has been transferred.
    503      */
    504     private void registerGlobalAlert() {
    505         try {
    506             mNetworkManager.setGlobalAlert(mGlobalAlertBytes);
    507         } catch (IllegalStateException e) {
    508             Slog.w(TAG, "problem registering for global alert: " + e);
    509         } catch (RemoteException e) {
    510             // ignored; service lives in system_server
    511         }
    512     }
    513 
    514     @Override
    515     public INetworkStatsSession openSession() {
    516         // NOTE: if callers want to get non-augmented data, they should go
    517         // through the public API
    518         return openSessionInternal(NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, null);
    519     }
    520 
    521     @Override
    522     public INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage) {
    523         return openSessionInternal(flags, callingPackage);
    524     }
    525 
    526     private boolean isRateLimitedForPoll(int callingUid) {
    527         if (callingUid == android.os.Process.SYSTEM_UID) {
    528             return false;
    529         }
    530 
    531         final long lastCallTime;
    532         final long now = SystemClock.elapsedRealtime();
    533         synchronized (mOpenSessionCallsPerUid) {
    534             int calls = mOpenSessionCallsPerUid.get(callingUid, 0);
    535             mOpenSessionCallsPerUid.put(callingUid, calls + 1);
    536             lastCallTime = mLastStatsSessionPoll;
    537             mLastStatsSessionPoll = now;
    538         }
    539 
    540         return now - lastCallTime < POLL_RATE_LIMIT_MS;
    541     }
    542 
    543     private INetworkStatsSession openSessionInternal(final int flags, final String callingPackage) {
    544         assertBandwidthControlEnabled();
    545 
    546         final int callingUid = Binder.getCallingUid();
    547         final int usedFlags = isRateLimitedForPoll(callingUid)
    548                 ? flags & (~NetworkStatsManager.FLAG_POLL_ON_OPEN)
    549                 : flags;
    550         if ((usedFlags & (NetworkStatsManager.FLAG_POLL_ON_OPEN
    551                 | NetworkStatsManager.FLAG_POLL_FORCE)) != 0) {
    552             final long ident = Binder.clearCallingIdentity();
    553             try {
    554                 performPoll(FLAG_PERSIST_ALL);
    555             } finally {
    556                 Binder.restoreCallingIdentity(ident);
    557             }
    558         }
    559 
    560         // return an IBinder which holds strong references to any loaded stats
    561         // for its lifetime; when caller closes only weak references remain.
    562 
    563         return new INetworkStatsSession.Stub() {
    564             private final int mCallingUid = callingUid;
    565             private final String mCallingPackage = callingPackage;
    566             private final @NetworkStatsAccess.Level int mAccessLevel = checkAccessLevel(
    567                     callingPackage);
    568 
    569             private NetworkStatsCollection mUidComplete;
    570             private NetworkStatsCollection mUidTagComplete;
    571 
    572             private NetworkStatsCollection getUidComplete() {
    573                 synchronized (mStatsLock) {
    574                     if (mUidComplete == null) {
    575                         mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
    576                     }
    577                     return mUidComplete;
    578                 }
    579             }
    580 
    581             private NetworkStatsCollection getUidTagComplete() {
    582                 synchronized (mStatsLock) {
    583                     if (mUidTagComplete == null) {
    584                         mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
    585                     }
    586                     return mUidTagComplete;
    587                 }
    588             }
    589 
    590             @Override
    591             public int[] getRelevantUids() {
    592                 return getUidComplete().getRelevantUids(mAccessLevel);
    593             }
    594 
    595             @Override
    596             public NetworkStats getDeviceSummaryForNetwork(
    597                     NetworkTemplate template, long start, long end) {
    598                 return internalGetSummaryForNetwork(template, usedFlags, start, end, mAccessLevel,
    599                         mCallingUid);
    600             }
    601 
    602             @Override
    603             public NetworkStats getSummaryForNetwork(
    604                     NetworkTemplate template, long start, long end) {
    605                 return internalGetSummaryForNetwork(template, usedFlags, start, end, mAccessLevel,
    606                         mCallingUid);
    607             }
    608 
    609             @Override
    610             public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
    611                 return internalGetHistoryForNetwork(template, usedFlags, fields, mAccessLevel,
    612                         mCallingUid);
    613             }
    614 
    615             @Override
    616             public NetworkStats getSummaryForAllUid(
    617                     NetworkTemplate template, long start, long end, boolean includeTags) {
    618                 try {
    619                     final NetworkStats stats = getUidComplete()
    620                             .getSummary(template, start, end, mAccessLevel, mCallingUid);
    621                     if (includeTags) {
    622                         final NetworkStats tagStats = getUidTagComplete()
    623                                 .getSummary(template, start, end, mAccessLevel, mCallingUid);
    624                         stats.combineAllValues(tagStats);
    625                     }
    626                     return stats;
    627                 } catch (NullPointerException e) {
    628                     // TODO: Track down and fix the cause of this crash and remove this catch block.
    629                     Slog.wtf(TAG, "NullPointerException in getSummaryForAllUid", e);
    630                     throw e;
    631                 }
    632             }
    633 
    634             @Override
    635             public NetworkStatsHistory getHistoryForUid(
    636                     NetworkTemplate template, int uid, int set, int tag, int fields) {
    637                 // NOTE: We don't augment UID-level statistics
    638                 if (tag == TAG_NONE) {
    639                     return getUidComplete().getHistory(template, null, uid, set, tag, fields,
    640                             Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
    641                 } else {
    642                     return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
    643                             Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
    644                 }
    645             }
    646 
    647             @Override
    648             public NetworkStatsHistory getHistoryIntervalForUid(
    649                     NetworkTemplate template, int uid, int set, int tag, int fields,
    650                     long start, long end) {
    651                 // NOTE: We don't augment UID-level statistics
    652                 if (tag == TAG_NONE) {
    653                     return getUidComplete().getHistory(template, null, uid, set, tag, fields,
    654                             start, end, mAccessLevel, mCallingUid);
    655                 } else if (uid == Binder.getCallingUid()) {
    656                     return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
    657                             start, end, mAccessLevel, mCallingUid);
    658                 } else {
    659                     throw new SecurityException("Calling package " + mCallingPackage
    660                             + " cannot access tag information from a different uid");
    661                 }
    662             }
    663 
    664             @Override
    665             public void close() {
    666                 mUidComplete = null;
    667                 mUidTagComplete = null;
    668             }
    669         };
    670     }
    671 
    672     private @NetworkStatsAccess.Level int checkAccessLevel(String callingPackage) {
    673         return NetworkStatsAccess.checkAccessLevel(
    674                 mContext, Binder.getCallingUid(), callingPackage);
    675     }
    676 
    677     /**
    678      * Find the most relevant {@link SubscriptionPlan} for the given
    679      * {@link NetworkTemplate} and flags. This is typically used to augment
    680      * local measurement results to match a known anchor from the carrier.
    681      */
    682     private SubscriptionPlan resolveSubscriptionPlan(NetworkTemplate template, int flags) {
    683         SubscriptionPlan plan = null;
    684         if ((flags & NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN) != 0
    685                 && mSettings.getAugmentEnabled()) {
    686             if (LOGD) Slog.d(TAG, "Resolving plan for " + template);
    687             final long token = Binder.clearCallingIdentity();
    688             try {
    689                 plan = LocalServices.getService(NetworkPolicyManagerInternal.class)
    690                         .getSubscriptionPlan(template);
    691             } finally {
    692                 Binder.restoreCallingIdentity(token);
    693             }
    694             if (LOGD) Slog.d(TAG, "Resolved to plan " + plan);
    695         }
    696         return plan;
    697     }
    698 
    699     /**
    700      * Return network summary, splicing between DEV and XT stats when
    701      * appropriate.
    702      */
    703     private NetworkStats internalGetSummaryForNetwork(NetworkTemplate template, int flags,
    704             long start, long end, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
    705         // We've been using pure XT stats long enough that we no longer need to
    706         // splice DEV and XT together.
    707         final NetworkStatsHistory history = internalGetHistoryForNetwork(template, flags, FIELD_ALL,
    708                 accessLevel, callingUid);
    709 
    710         final long now = System.currentTimeMillis();
    711         final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null);
    712 
    713         final NetworkStats stats = new NetworkStats(end - start, 1);
    714         stats.addValues(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE,
    715                 METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, entry.rxBytes, entry.rxPackets,
    716                 entry.txBytes, entry.txPackets, entry.operations));
    717         return stats;
    718     }
    719 
    720     /**
    721      * Return network history, splicing between DEV and XT stats when
    722      * appropriate.
    723      */
    724     private NetworkStatsHistory internalGetHistoryForNetwork(NetworkTemplate template,
    725             int flags, int fields, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
    726         // We've been using pure XT stats long enough that we no longer need to
    727         // splice DEV and XT together.
    728         final SubscriptionPlan augmentPlan = resolveSubscriptionPlan(template, flags);
    729         synchronized (mStatsLock) {
    730             return mXtStatsCached.getHistory(template, augmentPlan,
    731                     UID_ALL, SET_ALL, TAG_NONE, fields, Long.MIN_VALUE, Long.MAX_VALUE,
    732                     accessLevel, callingUid);
    733         }
    734     }
    735 
    736     private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
    737         assertSystemReady();
    738         assertBandwidthControlEnabled();
    739 
    740         // NOTE: if callers want to get non-augmented data, they should go
    741         // through the public API
    742         return internalGetSummaryForNetwork(template,
    743                 NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, start, end,
    744                 NetworkStatsAccess.Level.DEVICE, Binder.getCallingUid()).getTotalBytes();
    745     }
    746 
    747     private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
    748         assertSystemReady();
    749         assertBandwidthControlEnabled();
    750 
    751         final NetworkStatsCollection uidComplete;
    752         synchronized (mStatsLock) {
    753             uidComplete = mUidRecorder.getOrLoadCompleteLocked();
    754         }
    755         return uidComplete.getSummary(template, start, end, NetworkStatsAccess.Level.DEVICE,
    756                 android.os.Process.SYSTEM_UID);
    757     }
    758 
    759     @Override
    760     public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
    761         if (Binder.getCallingUid() != uid) {
    762             mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
    763         }
    764         assertBandwidthControlEnabled();
    765 
    766         // TODO: switch to data layer stats once kernel exports
    767         // for now, read network layer stats and flatten across all ifaces
    768         final long token = Binder.clearCallingIdentity();
    769         final NetworkStats networkLayer;
    770         try {
    771             networkLayer = mNetworkManager.getNetworkStatsUidDetail(uid,
    772                     NetworkStats.INTERFACES_ALL);
    773         } finally {
    774             Binder.restoreCallingIdentity(token);
    775         }
    776 
    777         // splice in operation counts
    778         networkLayer.spliceOperationsFrom(mUidOperations);
    779 
    780         final NetworkStats dataLayer = new NetworkStats(
    781                 networkLayer.getElapsedRealtime(), networkLayer.size());
    782 
    783         NetworkStats.Entry entry = null;
    784         for (int i = 0; i < networkLayer.size(); i++) {
    785             entry = networkLayer.getValues(i, entry);
    786             entry.iface = IFACE_ALL;
    787             dataLayer.combineValues(entry);
    788         }
    789 
    790         return dataLayer;
    791     }
    792 
    793     @Override
    794     public NetworkStats getDetailedUidStats(String[] requiredIfaces) {
    795         try {
    796             final String[] ifacesToQuery =
    797                     NetworkStatsFactory.augmentWithStackedInterfaces(requiredIfaces);
    798             return getNetworkStatsUidDetail(ifacesToQuery);
    799         } catch (RemoteException e) {
    800             Log.wtf(TAG, "Error compiling UID stats", e);
    801             return new NetworkStats(0L, 0);
    802         }
    803     }
    804 
    805     @Override
    806     public String[] getMobileIfaces() {
    807         return mMobileIfaces;
    808     }
    809 
    810     @Override
    811     public void incrementOperationCount(int uid, int tag, int operationCount) {
    812         if (Binder.getCallingUid() != uid) {
    813             mContext.enforceCallingOrSelfPermission(
    814                     android.Manifest.permission.UPDATE_DEVICE_STATS, TAG);
    815         }
    816 
    817         if (operationCount < 0) {
    818             throw new IllegalArgumentException("operation count can only be incremented");
    819         }
    820         if (tag == TAG_NONE) {
    821             throw new IllegalArgumentException("operation count must have specific tag");
    822         }
    823 
    824         synchronized (mStatsLock) {
    825             final int set = mActiveUidCounterSet.get(uid, SET_DEFAULT);
    826             mUidOperations.combineValues(
    827                     mActiveIface, uid, set, tag, 0L, 0L, 0L, 0L, operationCount);
    828             mUidOperations.combineValues(
    829                     mActiveIface, uid, set, TAG_NONE, 0L, 0L, 0L, 0L, operationCount);
    830         }
    831     }
    832 
    833     @VisibleForTesting
    834     void setUidForeground(int uid, boolean uidForeground) {
    835         synchronized (mStatsLock) {
    836             final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT;
    837             final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT);
    838             if (oldSet != set) {
    839                 mActiveUidCounterSet.put(uid, set);
    840                 setKernelCounterSet(uid, set);
    841             }
    842         }
    843     }
    844 
    845     @Override
    846     public void forceUpdateIfaces(Network[] defaultNetworks) {
    847         mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
    848         assertBandwidthControlEnabled();
    849 
    850         final long token = Binder.clearCallingIdentity();
    851         try {
    852             updateIfaces(defaultNetworks);
    853         } finally {
    854             Binder.restoreCallingIdentity(token);
    855         }
    856     }
    857 
    858     @Override
    859     public void forceUpdate() {
    860         mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
    861         assertBandwidthControlEnabled();
    862 
    863         final long token = Binder.clearCallingIdentity();
    864         try {
    865             performPoll(FLAG_PERSIST_ALL);
    866         } finally {
    867             Binder.restoreCallingIdentity(token);
    868         }
    869     }
    870 
    871     private void advisePersistThreshold(long thresholdBytes) {
    872         assertBandwidthControlEnabled();
    873 
    874         // clamp threshold into safe range
    875         mPersistThreshold = MathUtils.constrain(thresholdBytes, 128 * KB_IN_BYTES, 2 * MB_IN_BYTES);
    876         if (LOGV) {
    877             Slog.v(TAG, "advisePersistThreshold() given " + thresholdBytes + ", clamped to "
    878                     + mPersistThreshold);
    879         }
    880 
    881         // update and persist if beyond new thresholds
    882         final long currentTime = mClock.millis();
    883         synchronized (mStatsLock) {
    884             if (!mSystemReady) return;
    885 
    886             updatePersistThresholdsLocked();
    887 
    888             mDevRecorder.maybePersistLocked(currentTime);
    889             mXtRecorder.maybePersistLocked(currentTime);
    890             mUidRecorder.maybePersistLocked(currentTime);
    891             mUidTagRecorder.maybePersistLocked(currentTime);
    892         }
    893 
    894         // re-arm global alert
    895         registerGlobalAlert();
    896     }
    897 
    898     @Override
    899     public DataUsageRequest registerUsageCallback(String callingPackage,
    900                 DataUsageRequest request, Messenger messenger, IBinder binder) {
    901         checkNotNull(callingPackage, "calling package is null");
    902         checkNotNull(request, "DataUsageRequest is null");
    903         checkNotNull(request.template, "NetworkTemplate is null");
    904         checkNotNull(messenger, "messenger is null");
    905         checkNotNull(binder, "binder is null");
    906 
    907         int callingUid = Binder.getCallingUid();
    908         @NetworkStatsAccess.Level int accessLevel = checkAccessLevel(callingPackage);
    909         DataUsageRequest normalizedRequest;
    910         final long token = Binder.clearCallingIdentity();
    911         try {
    912             normalizedRequest = mStatsObservers.register(request, messenger, binder,
    913                     callingUid, accessLevel);
    914         } finally {
    915             Binder.restoreCallingIdentity(token);
    916         }
    917 
    918         // Create baseline stats
    919         mHandler.sendMessage(mHandler.obtainMessage(MSG_PERFORM_POLL, FLAG_PERSIST_ALL));
    920 
    921         return normalizedRequest;
    922    }
    923 
    924     @Override
    925     public void unregisterUsageRequest(DataUsageRequest request) {
    926         checkNotNull(request, "DataUsageRequest is null");
    927 
    928         int callingUid = Binder.getCallingUid();
    929         final long token = Binder.clearCallingIdentity();
    930         try {
    931             mStatsObservers.unregister(request, callingUid);
    932         } finally {
    933             Binder.restoreCallingIdentity(token);
    934         }
    935     }
    936 
    937     @Override
    938     public long getUidStats(int uid, int type) {
    939         return nativeGetUidStat(uid, type, checkBpfStatsEnable());
    940     }
    941 
    942     @Override
    943     public long getIfaceStats(String iface, int type) {
    944         return nativeGetIfaceStat(iface, type, checkBpfStatsEnable());
    945     }
    946 
    947     @Override
    948     public long getTotalStats(int type) {
    949         return nativeGetTotalStat(type, checkBpfStatsEnable());
    950     }
    951 
    952     private boolean checkBpfStatsEnable() {
    953         return mUseBpfTrafficStats;
    954     }
    955 
    956     /**
    957      * Update {@link NetworkStatsRecorder} and {@link #mGlobalAlertBytes} to
    958      * reflect current {@link #mPersistThreshold} value. Always defers to
    959      * {@link Global} values when defined.
    960      */
    961     @GuardedBy("mStatsLock")
    962     private void updatePersistThresholdsLocked() {
    963         mDevRecorder.setPersistThreshold(mSettings.getDevPersistBytes(mPersistThreshold));
    964         mXtRecorder.setPersistThreshold(mSettings.getXtPersistBytes(mPersistThreshold));
    965         mUidRecorder.setPersistThreshold(mSettings.getUidPersistBytes(mPersistThreshold));
    966         mUidTagRecorder.setPersistThreshold(mSettings.getUidTagPersistBytes(mPersistThreshold));
    967         mGlobalAlertBytes = mSettings.getGlobalAlertBytes(mPersistThreshold);
    968     }
    969 
    970     /**
    971      * Receiver that watches for {@link Tethering} to claim interface pairs.
    972      */
    973     private BroadcastReceiver mTetherReceiver = new BroadcastReceiver() {
    974         @Override
    975         public void onReceive(Context context, Intent intent) {
    976             // on background handler thread, and verified CONNECTIVITY_INTERNAL
    977             // permission above.
    978             performPoll(FLAG_PERSIST_NETWORK);
    979         }
    980     };
    981 
    982     private BroadcastReceiver mPollReceiver = new BroadcastReceiver() {
    983         @Override
    984         public void onReceive(Context context, Intent intent) {
    985             // on background handler thread, and verified UPDATE_DEVICE_STATS
    986             // permission above.
    987             performPoll(FLAG_PERSIST_ALL);
    988 
    989             // verify that we're watching global alert
    990             registerGlobalAlert();
    991         }
    992     };
    993 
    994     private BroadcastReceiver mRemovedReceiver = new BroadcastReceiver() {
    995         @Override
    996         public void onReceive(Context context, Intent intent) {
    997             // on background handler thread, and UID_REMOVED is protected
    998             // broadcast.
    999 
   1000             final int uid = intent.getIntExtra(EXTRA_UID, -1);
   1001             if (uid == -1) return;
   1002 
   1003             synchronized (mStatsLock) {
   1004                 mWakeLock.acquire();
   1005                 try {
   1006                     removeUidsLocked(uid);
   1007                 } finally {
   1008                     mWakeLock.release();
   1009                 }
   1010             }
   1011         }
   1012     };
   1013 
   1014     private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
   1015         @Override
   1016         public void onReceive(Context context, Intent intent) {
   1017             // On background handler thread, and USER_REMOVED is protected
   1018             // broadcast.
   1019 
   1020             final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
   1021             if (userId == -1) return;
   1022 
   1023             synchronized (mStatsLock) {
   1024                 mWakeLock.acquire();
   1025                 try {
   1026                     removeUserLocked(userId);
   1027                 } finally {
   1028                     mWakeLock.release();
   1029                 }
   1030             }
   1031         }
   1032     };
   1033 
   1034     private BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() {
   1035         @Override
   1036         public void onReceive(Context context, Intent intent) {
   1037             // SHUTDOWN is protected broadcast.
   1038             synchronized (mStatsLock) {
   1039                 shutdownLocked();
   1040             }
   1041         }
   1042     };
   1043 
   1044     /**
   1045      * Observer that watches for {@link INetworkManagementService} alerts.
   1046      */
   1047     private INetworkManagementEventObserver mAlertObserver = new BaseNetworkObserver() {
   1048         @Override
   1049         public void limitReached(String limitName, String iface) {
   1050             // only someone like NMS should be calling us
   1051             mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
   1052 
   1053             if (LIMIT_GLOBAL_ALERT.equals(limitName)) {
   1054                 // kick off background poll to collect network stats; UID stats
   1055                 // are handled during normal polling interval.
   1056                 final int flags = FLAG_PERSIST_NETWORK;
   1057                 mHandler.obtainMessage(MSG_PERFORM_POLL, flags, 0).sendToTarget();
   1058 
   1059                 // re-arm global alert for next update
   1060                 mHandler.obtainMessage(MSG_REGISTER_GLOBAL_ALERT).sendToTarget();
   1061             }
   1062         }
   1063     };
   1064 
   1065     private void updateIfaces(Network[] defaultNetworks) {
   1066         synchronized (mStatsLock) {
   1067             mWakeLock.acquire();
   1068             try {
   1069                 updateIfacesLocked(defaultNetworks);
   1070             } finally {
   1071                 mWakeLock.release();
   1072             }
   1073         }
   1074     }
   1075 
   1076     /**
   1077      * Inspect all current {@link NetworkState} to derive mapping from {@code
   1078      * iface} to {@link NetworkStatsHistory}. When multiple {@link NetworkInfo}
   1079      * are active on a single {@code iface}, they are combined under a single
   1080      * {@link NetworkIdentitySet}.
   1081      */
   1082     @GuardedBy("mStatsLock")
   1083     private void updateIfacesLocked(Network[] defaultNetworks) {
   1084         if (!mSystemReady) return;
   1085         if (LOGV) Slog.v(TAG, "updateIfacesLocked()");
   1086 
   1087         // take one last stats snapshot before updating iface mapping. this
   1088         // isn't perfect, since the kernel may already be counting traffic from
   1089         // the updated network.
   1090 
   1091         // poll, but only persist network stats to keep codepath fast. UID stats
   1092         // will be persisted during next alarm poll event.
   1093         performPollLocked(FLAG_PERSIST_NETWORK);
   1094 
   1095         final NetworkState[] states;
   1096         final LinkProperties activeLink;
   1097         try {
   1098             states = mConnManager.getAllNetworkState();
   1099             activeLink = mConnManager.getActiveLinkProperties();
   1100         } catch (RemoteException e) {
   1101             // ignored; service lives in system_server
   1102             return;
   1103         }
   1104 
   1105         mActiveIface = activeLink != null ? activeLink.getInterfaceName() : null;
   1106 
   1107         // Rebuild active interfaces based on connected networks
   1108         mActiveIfaces.clear();
   1109         mActiveUidIfaces.clear();
   1110         if (defaultNetworks != null) {
   1111             // Caller is ConnectivityService. Update the list of default networks.
   1112             mDefaultNetworks = defaultNetworks;
   1113         }
   1114 
   1115         final ArraySet<String> mobileIfaces = new ArraySet<>();
   1116         for (NetworkState state : states) {
   1117             if (state.networkInfo.isConnected()) {
   1118                 final boolean isMobile = isNetworkTypeMobile(state.networkInfo.getType());
   1119                 final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, state.network);
   1120                 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state,
   1121                         isDefault);
   1122 
   1123                 // Traffic occurring on the base interface is always counted for
   1124                 // both total usage and UID details.
   1125                 final String baseIface = state.linkProperties.getInterfaceName();
   1126                 if (baseIface != null) {
   1127                     findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident);
   1128                     findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident);
   1129 
   1130                     // Build a separate virtual interface for VT (Video Telephony) data usage.
   1131                     // Only do this when IMS is not metered, but VT is metered.
   1132                     // If IMS is metered, then the IMS network usage has already included VT usage.
   1133                     // VT is considered always metered in framework's layer. If VT is not metered
   1134                     // per carrier's policy, modem will report 0 usage for VT calls.
   1135                     if (state.networkCapabilities.hasCapability(
   1136                             NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.getMetered()) {
   1137 
   1138                         // Copy the identify from IMS one but mark it as metered.
   1139                         NetworkIdentity vtIdent = new NetworkIdentity(ident.getType(),
   1140                                 ident.getSubType(), ident.getSubscriberId(), ident.getNetworkId(),
   1141                                 ident.getRoaming(), true /* metered */,
   1142                                 true /* onDefaultNetwork */);
   1143                         findOrCreateNetworkIdentitySet(mActiveIfaces, VT_INTERFACE).add(vtIdent);
   1144                         findOrCreateNetworkIdentitySet(mActiveUidIfaces, VT_INTERFACE).add(vtIdent);
   1145                     }
   1146 
   1147                     if (isMobile) {
   1148                         mobileIfaces.add(baseIface);
   1149                     }
   1150                 }
   1151 
   1152                 // Traffic occurring on stacked interfaces is usually clatd,
   1153                 // which is already accounted against its final egress interface
   1154                 // by the kernel. Thus, we only need to collect stacked
   1155                 // interface stats at the UID level.
   1156                 final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks();
   1157                 for (LinkProperties stackedLink : stackedLinks) {
   1158                     final String stackedIface = stackedLink.getInterfaceName();
   1159                     if (stackedIface != null) {
   1160                         findOrCreateNetworkIdentitySet(mActiveUidIfaces, stackedIface).add(ident);
   1161                         if (isMobile) {
   1162                             mobileIfaces.add(stackedIface);
   1163                         }
   1164 
   1165                         NetworkStatsFactory.noteStackedIface(stackedIface, baseIface);
   1166                     }
   1167                 }
   1168             }
   1169         }
   1170 
   1171         mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]);
   1172     }
   1173 
   1174     private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet(
   1175             ArrayMap<K, NetworkIdentitySet> map, K key) {
   1176         NetworkIdentitySet ident = map.get(key);
   1177         if (ident == null) {
   1178             ident = new NetworkIdentitySet();
   1179             map.put(key, ident);
   1180         }
   1181         return ident;
   1182     }
   1183 
   1184     @GuardedBy("mStatsLock")
   1185     private void recordSnapshotLocked(long currentTime) throws RemoteException {
   1186         // snapshot and record current counters; read UID stats first to
   1187         // avoid over counting dev stats.
   1188         Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotUid");
   1189         final NetworkStats uidSnapshot = getNetworkStatsUidDetail(INTERFACES_ALL);
   1190         Trace.traceEnd(TRACE_TAG_NETWORK);
   1191         Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotXt");
   1192         final NetworkStats xtSnapshot = getNetworkStatsXt();
   1193         Trace.traceEnd(TRACE_TAG_NETWORK);
   1194         Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotDev");
   1195         final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev();
   1196         Trace.traceEnd(TRACE_TAG_NETWORK);
   1197 
   1198         // Tethering snapshot for dev and xt stats. Counts per-interface data from tethering stats
   1199         // providers that isn't already counted by dev and XT stats.
   1200         Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotTether");
   1201         final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
   1202         Trace.traceEnd(TRACE_TAG_NETWORK);
   1203         xtSnapshot.combineAllValues(tetherSnapshot);
   1204         devSnapshot.combineAllValues(tetherSnapshot);
   1205 
   1206         // For xt/dev, we pass a null VPN array because usage is aggregated by UID, so VPN traffic
   1207         // can't be reattributed to responsible apps.
   1208         Trace.traceBegin(TRACE_TAG_NETWORK, "recordDev");
   1209         mDevRecorder.recordSnapshotLocked(
   1210                 devSnapshot, mActiveIfaces, null /* vpnArray */, currentTime);
   1211         Trace.traceEnd(TRACE_TAG_NETWORK);
   1212         Trace.traceBegin(TRACE_TAG_NETWORK, "recordXt");
   1213         mXtRecorder.recordSnapshotLocked(
   1214                 xtSnapshot, mActiveIfaces, null /* vpnArray */, currentTime);
   1215         Trace.traceEnd(TRACE_TAG_NETWORK);
   1216 
   1217         // For per-UID stats, pass the VPN info so VPN traffic is reattributed to responsible apps.
   1218         VpnInfo[] vpnArray = mConnManager.getAllVpnInfo();
   1219         Trace.traceBegin(TRACE_TAG_NETWORK, "recordUid");
   1220         mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, vpnArray, currentTime);
   1221         Trace.traceEnd(TRACE_TAG_NETWORK);
   1222         Trace.traceBegin(TRACE_TAG_NETWORK, "recordUidTag");
   1223         mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, vpnArray, currentTime);
   1224         Trace.traceEnd(TRACE_TAG_NETWORK);
   1225 
   1226         // We need to make copies of member fields that are sent to the observer to avoid
   1227         // a race condition between the service handler thread and the observer's
   1228         mStatsObservers.updateStats(xtSnapshot, uidSnapshot, new ArrayMap<>(mActiveIfaces),
   1229                 new ArrayMap<>(mActiveUidIfaces), vpnArray, currentTime);
   1230     }
   1231 
   1232     /**
   1233      * Bootstrap initial stats snapshot, usually during {@link #systemReady()}
   1234      * so we have baseline values without double-counting.
   1235      */
   1236     @GuardedBy("mStatsLock")
   1237     private void bootstrapStatsLocked() {
   1238         final long currentTime = mClock.millis();
   1239 
   1240         try {
   1241             recordSnapshotLocked(currentTime);
   1242         } catch (IllegalStateException e) {
   1243             Slog.w(TAG, "problem reading network stats: " + e);
   1244         } catch (RemoteException e) {
   1245             // ignored; service lives in system_server
   1246         }
   1247     }
   1248 
   1249     private void performPoll(int flags) {
   1250         synchronized (mStatsLock) {
   1251             mWakeLock.acquire();
   1252 
   1253             try {
   1254                 performPollLocked(flags);
   1255             } finally {
   1256                 mWakeLock.release();
   1257             }
   1258         }
   1259     }
   1260 
   1261     /**
   1262      * Periodic poll operation, reading current statistics and recording into
   1263      * {@link NetworkStatsHistory}.
   1264      */
   1265     @GuardedBy("mStatsLock")
   1266     private void performPollLocked(int flags) {
   1267         if (!mSystemReady) return;
   1268         if (LOGV) Slog.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")");
   1269         Trace.traceBegin(TRACE_TAG_NETWORK, "performPollLocked");
   1270 
   1271         final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0;
   1272         final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
   1273         final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
   1274 
   1275         // TODO: consider marking "untrusted" times in historical stats
   1276         final long currentTime = mClock.millis();
   1277 
   1278         try {
   1279             recordSnapshotLocked(currentTime);
   1280         } catch (IllegalStateException e) {
   1281             Log.wtf(TAG, "problem reading network stats", e);
   1282             return;
   1283         } catch (RemoteException e) {
   1284             // ignored; service lives in system_server
   1285             return;
   1286         }
   1287 
   1288         // persist any pending data depending on requested flags
   1289         Trace.traceBegin(TRACE_TAG_NETWORK, "[persisting]");
   1290         if (persistForce) {
   1291             mDevRecorder.forcePersistLocked(currentTime);
   1292             mXtRecorder.forcePersistLocked(currentTime);
   1293             mUidRecorder.forcePersistLocked(currentTime);
   1294             mUidTagRecorder.forcePersistLocked(currentTime);
   1295         } else {
   1296             if (persistNetwork) {
   1297                 mDevRecorder.maybePersistLocked(currentTime);
   1298                 mXtRecorder.maybePersistLocked(currentTime);
   1299             }
   1300             if (persistUid) {
   1301                 mUidRecorder.maybePersistLocked(currentTime);
   1302                 mUidTagRecorder.maybePersistLocked(currentTime);
   1303             }
   1304         }
   1305         Trace.traceEnd(TRACE_TAG_NETWORK);
   1306 
   1307         if (mSettings.getSampleEnabled()) {
   1308             // sample stats after each full poll
   1309             performSampleLocked();
   1310         }
   1311 
   1312         // finally, dispatch updated event to any listeners
   1313         final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
   1314         updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   1315         mContext.sendBroadcastAsUser(updatedIntent, UserHandle.ALL,
   1316                 READ_NETWORK_USAGE_HISTORY);
   1317 
   1318         Trace.traceEnd(TRACE_TAG_NETWORK);
   1319     }
   1320 
   1321     /**
   1322      * Sample recent statistics summary into {@link EventLog}.
   1323      */
   1324     @GuardedBy("mStatsLock")
   1325     private void performSampleLocked() {
   1326         // TODO: migrate trustedtime fixes to separate binary log events
   1327         final long currentTime = mClock.millis();
   1328 
   1329         NetworkTemplate template;
   1330         NetworkStats.Entry devTotal;
   1331         NetworkStats.Entry xtTotal;
   1332         NetworkStats.Entry uidTotal;
   1333 
   1334         // collect mobile sample
   1335         template = buildTemplateMobileWildcard();
   1336         devTotal = mDevRecorder.getTotalSinceBootLocked(template);
   1337         xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
   1338         uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
   1339 
   1340         EventLogTags.writeNetstatsMobileSample(
   1341                 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
   1342                 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
   1343                 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
   1344                 currentTime);
   1345 
   1346         // collect wifi sample
   1347         template = buildTemplateWifiWildcard();
   1348         devTotal = mDevRecorder.getTotalSinceBootLocked(template);
   1349         xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
   1350         uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
   1351 
   1352         EventLogTags.writeNetstatsWifiSample(
   1353                 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
   1354                 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
   1355                 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
   1356                 currentTime);
   1357     }
   1358 
   1359     /**
   1360      * Clean up {@link #mUidRecorder} after UID is removed.
   1361      */
   1362     @GuardedBy("mStatsLock")
   1363     private void removeUidsLocked(int... uids) {
   1364         if (LOGV) Slog.v(TAG, "removeUidsLocked() for UIDs " + Arrays.toString(uids));
   1365 
   1366         // Perform one last poll before removing
   1367         performPollLocked(FLAG_PERSIST_ALL);
   1368 
   1369         mUidRecorder.removeUidsLocked(uids);
   1370         mUidTagRecorder.removeUidsLocked(uids);
   1371 
   1372         // Clear kernel stats associated with UID
   1373         for (int uid : uids) {
   1374             resetKernelUidStats(uid);
   1375         }
   1376     }
   1377 
   1378     /**
   1379      * Clean up {@link #mUidRecorder} after user is removed.
   1380      */
   1381     @GuardedBy("mStatsLock")
   1382     private void removeUserLocked(int userId) {
   1383         if (LOGV) Slog.v(TAG, "removeUserLocked() for userId=" + userId);
   1384 
   1385         // Build list of UIDs that we should clean up
   1386         int[] uids = new int[0];
   1387         final List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
   1388                 PackageManager.MATCH_ANY_USER
   1389                 | PackageManager.MATCH_DISABLED_COMPONENTS);
   1390         for (ApplicationInfo app : apps) {
   1391             final int uid = UserHandle.getUid(userId, app.uid);
   1392             uids = ArrayUtils.appendInt(uids, uid);
   1393         }
   1394 
   1395         removeUidsLocked(uids);
   1396     }
   1397 
   1398     private class NetworkStatsManagerInternalImpl extends NetworkStatsManagerInternal {
   1399         @Override
   1400         public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
   1401             Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkTotalBytes");
   1402             try {
   1403                 return NetworkStatsService.this.getNetworkTotalBytes(template, start, end);
   1404             } finally {
   1405                 Trace.traceEnd(TRACE_TAG_NETWORK);
   1406             }
   1407         }
   1408 
   1409         @Override
   1410         public NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
   1411             Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkUidBytes");
   1412             try {
   1413                 return NetworkStatsService.this.getNetworkUidBytes(template, start, end);
   1414             } finally {
   1415                 Trace.traceEnd(TRACE_TAG_NETWORK);
   1416             }
   1417         }
   1418 
   1419         @Override
   1420         public void setUidForeground(int uid, boolean uidForeground) {
   1421             NetworkStatsService.this.setUidForeground(uid, uidForeground);
   1422         }
   1423 
   1424         @Override
   1425         public void advisePersistThreshold(long thresholdBytes) {
   1426             NetworkStatsService.this.advisePersistThreshold(thresholdBytes);
   1427         }
   1428 
   1429         @Override
   1430         public void forceUpdate() {
   1431             NetworkStatsService.this.forceUpdate();
   1432         }
   1433     }
   1434 
   1435     @Override
   1436     protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) {
   1437         if (!DumpUtils.checkDumpPermission(mContext, TAG, rawWriter)) return;
   1438 
   1439         long duration = DateUtils.DAY_IN_MILLIS;
   1440         final HashSet<String> argSet = new HashSet<String>();
   1441         for (String arg : args) {
   1442             argSet.add(arg);
   1443 
   1444             if (arg.startsWith("--duration=")) {
   1445                 try {
   1446                     duration = Long.parseLong(arg.substring(11));
   1447                 } catch (NumberFormatException ignored) {
   1448                 }
   1449             }
   1450         }
   1451 
   1452         // usage: dumpsys netstats --full --uid --tag --poll --checkin
   1453         final boolean poll = argSet.contains("--poll") || argSet.contains("poll");
   1454         final boolean checkin = argSet.contains("--checkin");
   1455         final boolean fullHistory = argSet.contains("--full") || argSet.contains("full");
   1456         final boolean includeUid = argSet.contains("--uid") || argSet.contains("detail");
   1457         final boolean includeTag = argSet.contains("--tag") || argSet.contains("detail");
   1458 
   1459         final IndentingPrintWriter pw = new IndentingPrintWriter(rawWriter, "  ");
   1460 
   1461         synchronized (mStatsLock) {
   1462             if (args.length > 0 && "--proto".equals(args[0])) {
   1463                 // In this case ignore all other arguments.
   1464                 dumpProtoLocked(fd);
   1465                 return;
   1466             }
   1467 
   1468             if (poll) {
   1469                 performPollLocked(FLAG_PERSIST_ALL | FLAG_PERSIST_FORCE);
   1470                 pw.println("Forced poll");
   1471                 return;
   1472             }
   1473 
   1474             if (checkin) {
   1475                 final long end = System.currentTimeMillis();
   1476                 final long start = end - duration;
   1477 
   1478                 pw.print("v1,");
   1479                 pw.print(start / SECOND_IN_MILLIS); pw.print(',');
   1480                 pw.print(end / SECOND_IN_MILLIS); pw.println();
   1481 
   1482                 pw.println("xt");
   1483                 mXtRecorder.dumpCheckin(rawWriter, start, end);
   1484 
   1485                 if (includeUid) {
   1486                     pw.println("uid");
   1487                     mUidRecorder.dumpCheckin(rawWriter, start, end);
   1488                 }
   1489                 if (includeTag) {
   1490                     pw.println("tag");
   1491                     mUidTagRecorder.dumpCheckin(rawWriter, start, end);
   1492                 }
   1493                 return;
   1494             }
   1495 
   1496             pw.println("Active interfaces:");
   1497             pw.increaseIndent();
   1498             for (int i = 0; i < mActiveIfaces.size(); i++) {
   1499                 pw.printPair("iface", mActiveIfaces.keyAt(i));
   1500                 pw.printPair("ident", mActiveIfaces.valueAt(i));
   1501                 pw.println();
   1502             }
   1503             pw.decreaseIndent();
   1504 
   1505             pw.println("Active UID interfaces:");
   1506             pw.increaseIndent();
   1507             for (int i = 0; i < mActiveUidIfaces.size(); i++) {
   1508                 pw.printPair("iface", mActiveUidIfaces.keyAt(i));
   1509                 pw.printPair("ident", mActiveUidIfaces.valueAt(i));
   1510                 pw.println();
   1511             }
   1512             pw.decreaseIndent();
   1513 
   1514             // Get the top openSession callers
   1515             final SparseIntArray calls;
   1516             synchronized (mOpenSessionCallsPerUid) {
   1517                 calls = mOpenSessionCallsPerUid.clone();
   1518             }
   1519 
   1520             final int N = calls.size();
   1521             final long[] values = new long[N];
   1522             for (int j = 0; j < N; j++) {
   1523                 values[j] = ((long) calls.valueAt(j) << 32) | calls.keyAt(j);
   1524             }
   1525             Arrays.sort(values);
   1526 
   1527             pw.println("Top openSession callers (uid=count):");
   1528             pw.increaseIndent();
   1529             final int end = Math.max(0, N - DUMP_STATS_SESSION_COUNT);
   1530             for (int j = N - 1; j >= end; j--) {
   1531                 final int uid = (int) (values[j] & 0xffffffff);
   1532                 final int count = (int) (values[j] >> 32);
   1533                 pw.print(uid); pw.print("="); pw.println(count);
   1534             }
   1535             pw.decreaseIndent();
   1536             pw.println();
   1537 
   1538             pw.println("Dev stats:");
   1539             pw.increaseIndent();
   1540             mDevRecorder.dumpLocked(pw, fullHistory);
   1541             pw.decreaseIndent();
   1542 
   1543             pw.println("Xt stats:");
   1544             pw.increaseIndent();
   1545             mXtRecorder.dumpLocked(pw, fullHistory);
   1546             pw.decreaseIndent();
   1547 
   1548             if (includeUid) {
   1549                 pw.println("UID stats:");
   1550                 pw.increaseIndent();
   1551                 mUidRecorder.dumpLocked(pw, fullHistory);
   1552                 pw.decreaseIndent();
   1553             }
   1554 
   1555             if (includeTag) {
   1556                 pw.println("UID tag stats:");
   1557                 pw.increaseIndent();
   1558                 mUidTagRecorder.dumpLocked(pw, fullHistory);
   1559                 pw.decreaseIndent();
   1560             }
   1561         }
   1562     }
   1563 
   1564     @GuardedBy("mStatsLock")
   1565     private void dumpProtoLocked(FileDescriptor fd) {
   1566         final ProtoOutputStream proto = new ProtoOutputStream(fd);
   1567 
   1568         // TODO Right now it writes all history.  Should it limit to the "since-boot" log?
   1569 
   1570         dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES, mActiveIfaces);
   1571         dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES, mActiveUidIfaces);
   1572         mDevRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS);
   1573         mXtRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.XT_STATS);
   1574         mUidRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.UID_STATS);
   1575         mUidTagRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.UID_TAG_STATS);
   1576 
   1577         proto.flush();
   1578     }
   1579 
   1580     private static void dumpInterfaces(ProtoOutputStream proto, long tag,
   1581             ArrayMap<String, NetworkIdentitySet> ifaces) {
   1582         for (int i = 0; i < ifaces.size(); i++) {
   1583             final long start = proto.start(tag);
   1584 
   1585             proto.write(NetworkInterfaceProto.INTERFACE, ifaces.keyAt(i));
   1586             ifaces.valueAt(i).writeToProto(proto, NetworkInterfaceProto.IDENTITIES);
   1587 
   1588             proto.end(start);
   1589         }
   1590     }
   1591 
   1592     /**
   1593      * Return snapshot of current UID statistics, including any
   1594      * {@link TrafficStats#UID_TETHERING}, video calling data usage, and {@link #mUidOperations}
   1595      * values.
   1596      *
   1597      * @param ifaces A list of interfaces the stats should be restricted to, or
   1598      *               {@link NetworkStats#INTERFACES_ALL}.
   1599      */
   1600     private NetworkStats getNetworkStatsUidDetail(String[] ifaces)
   1601             throws RemoteException {
   1602 
   1603         // TODO: remove 464xlat adjustments from NetworkStatsFactory and apply all at once here.
   1604         final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL,
   1605                 ifaces);
   1606 
   1607         // fold tethering stats and operations into uid snapshot
   1608         final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_UID);
   1609         tetherSnapshot.filter(UID_ALL, ifaces, TAG_ALL);
   1610         NetworkStatsFactory.apply464xlatAdjustments(uidSnapshot, tetherSnapshot);
   1611         uidSnapshot.combineAllValues(tetherSnapshot);
   1612 
   1613         final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
   1614                 Context.TELEPHONY_SERVICE);
   1615 
   1616         // fold video calling data usage stats into uid snapshot
   1617         final NetworkStats vtStats = telephonyManager.getVtDataUsage(STATS_PER_UID);
   1618         if (vtStats != null) {
   1619             vtStats.filter(UID_ALL, ifaces, TAG_ALL);
   1620             NetworkStatsFactory.apply464xlatAdjustments(uidSnapshot, vtStats);
   1621             uidSnapshot.combineAllValues(vtStats);
   1622         }
   1623 
   1624         uidSnapshot.combineAllValues(mUidOperations);
   1625 
   1626         return uidSnapshot;
   1627     }
   1628 
   1629     /**
   1630      * Return snapshot of current XT statistics with video calling data usage statistics.
   1631      */
   1632     private NetworkStats getNetworkStatsXt() throws RemoteException {
   1633         final NetworkStats xtSnapshot = mNetworkManager.getNetworkStatsSummaryXt();
   1634 
   1635         final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
   1636                 Context.TELEPHONY_SERVICE);
   1637 
   1638         // Merge video calling data usage into XT
   1639         final NetworkStats vtSnapshot = telephonyManager.getVtDataUsage(STATS_PER_IFACE);
   1640         if (vtSnapshot != null) {
   1641             xtSnapshot.combineAllValues(vtSnapshot);
   1642         }
   1643 
   1644         return xtSnapshot;
   1645     }
   1646 
   1647     /**
   1648      * Return snapshot of current tethering statistics. Will return empty
   1649      * {@link NetworkStats} if any problems are encountered.
   1650      */
   1651     private NetworkStats getNetworkStatsTethering(int how) throws RemoteException {
   1652         try {
   1653             return mNetworkManager.getNetworkStatsTethering(how);
   1654         } catch (IllegalStateException e) {
   1655             Log.wtf(TAG, "problem reading network stats", e);
   1656             return new NetworkStats(0L, 10);
   1657         }
   1658     }
   1659 
   1660     @VisibleForTesting
   1661     static class HandlerCallback implements Handler.Callback {
   1662         private final NetworkStatsService mService;
   1663 
   1664         HandlerCallback(NetworkStatsService service) {
   1665             this.mService = service;
   1666         }
   1667 
   1668         @Override
   1669         public boolean handleMessage(Message msg) {
   1670             switch (msg.what) {
   1671                 case MSG_PERFORM_POLL: {
   1672                     final int flags = msg.arg1;
   1673                     mService.performPoll(flags);
   1674                     return true;
   1675                 }
   1676                 case MSG_UPDATE_IFACES: {
   1677                     mService.updateIfaces(null);
   1678                     return true;
   1679                 }
   1680                 case MSG_REGISTER_GLOBAL_ALERT: {
   1681                     mService.registerGlobalAlert();
   1682                     return true;
   1683                 }
   1684                 default: {
   1685                     return false;
   1686                 }
   1687             }
   1688         }
   1689     }
   1690 
   1691     private void assertSystemReady() {
   1692         if (!mSystemReady) {
   1693             throw new IllegalStateException("System not ready");
   1694         }
   1695     }
   1696 
   1697     private void assertBandwidthControlEnabled() {
   1698         if (!isBandwidthControlEnabled()) {
   1699             throw new IllegalStateException("Bandwidth module disabled");
   1700         }
   1701     }
   1702 
   1703     private boolean isBandwidthControlEnabled() {
   1704         final long token = Binder.clearCallingIdentity();
   1705         try {
   1706             return mNetworkManager.isBandwidthControlEnabled();
   1707         } catch (RemoteException e) {
   1708             // ignored; service lives in system_server
   1709             return false;
   1710         } finally {
   1711             Binder.restoreCallingIdentity(token);
   1712         }
   1713     }
   1714 
   1715     private class DropBoxNonMonotonicObserver implements NonMonotonicObserver<String> {
   1716         @Override
   1717         public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
   1718                 int rightIndex, String cookie) {
   1719             Log.w(TAG, "Found non-monotonic values; saving to dropbox");
   1720 
   1721             // record error for debugging
   1722             final StringBuilder builder = new StringBuilder();
   1723             builder.append("found non-monotonic " + cookie + " values at left[" + leftIndex
   1724                     + "] - right[" + rightIndex + "]\n");
   1725             builder.append("left=").append(left).append('\n');
   1726             builder.append("right=").append(right).append('\n');
   1727 
   1728             mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
   1729                     builder.toString());
   1730         }
   1731 
   1732         @Override
   1733         public void foundNonMonotonic(
   1734                 NetworkStats stats, int statsIndex, String cookie) {
   1735             Log.w(TAG, "Found non-monotonic values; saving to dropbox");
   1736 
   1737             final StringBuilder builder = new StringBuilder();
   1738             builder.append("Found non-monotonic " + cookie + " values at [" + statsIndex + "]\n");
   1739             builder.append("stats=").append(stats).append('\n');
   1740 
   1741             mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
   1742                     builder.toString());
   1743         }
   1744     }
   1745 
   1746     /**
   1747      * Default external settings that read from
   1748      * {@link android.provider.Settings.Global}.
   1749      */
   1750     private static class DefaultNetworkStatsSettings implements NetworkStatsSettings {
   1751         private final ContentResolver mResolver;
   1752 
   1753         public DefaultNetworkStatsSettings(Context context) {
   1754             mResolver = checkNotNull(context.getContentResolver());
   1755             // TODO: adjust these timings for production builds
   1756         }
   1757 
   1758         private long getGlobalLong(String name, long def) {
   1759             return Settings.Global.getLong(mResolver, name, def);
   1760         }
   1761         private boolean getGlobalBoolean(String name, boolean def) {
   1762             final int defInt = def ? 1 : 0;
   1763             return Settings.Global.getInt(mResolver, name, defInt) != 0;
   1764         }
   1765 
   1766         @Override
   1767         public long getPollInterval() {
   1768             return getGlobalLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS);
   1769         }
   1770         @Override
   1771         public long getGlobalAlertBytes(long def) {
   1772             return getGlobalLong(NETSTATS_GLOBAL_ALERT_BYTES, def);
   1773         }
   1774         @Override
   1775         public boolean getSampleEnabled() {
   1776             return getGlobalBoolean(NETSTATS_SAMPLE_ENABLED, true);
   1777         }
   1778         @Override
   1779         public boolean getAugmentEnabled() {
   1780             return getGlobalBoolean(NETSTATS_AUGMENT_ENABLED, true);
   1781         }
   1782         @Override
   1783         public Config getDevConfig() {
   1784             return new Config(getGlobalLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
   1785                     getGlobalLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
   1786                     getGlobalLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS));
   1787         }
   1788         @Override
   1789         public Config getXtConfig() {
   1790             return getDevConfig();
   1791         }
   1792         @Override
   1793         public Config getUidConfig() {
   1794             return new Config(getGlobalLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
   1795                     getGlobalLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS),
   1796                     getGlobalLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS));
   1797         }
   1798         @Override
   1799         public Config getUidTagConfig() {
   1800             return new Config(getGlobalLong(NETSTATS_UID_TAG_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
   1801                     getGlobalLong(NETSTATS_UID_TAG_ROTATE_AGE, 5 * DAY_IN_MILLIS),
   1802                     getGlobalLong(NETSTATS_UID_TAG_DELETE_AGE, 15 * DAY_IN_MILLIS));
   1803         }
   1804         @Override
   1805         public long getDevPersistBytes(long def) {
   1806             return getGlobalLong(NETSTATS_DEV_PERSIST_BYTES, def);
   1807         }
   1808         @Override
   1809         public long getXtPersistBytes(long def) {
   1810             return getDevPersistBytes(def);
   1811         }
   1812         @Override
   1813         public long getUidPersistBytes(long def) {
   1814             return getGlobalLong(NETSTATS_UID_PERSIST_BYTES, def);
   1815         }
   1816         @Override
   1817         public long getUidTagPersistBytes(long def) {
   1818             return getGlobalLong(NETSTATS_UID_TAG_PERSIST_BYTES, def);
   1819         }
   1820     }
   1821 
   1822     private static int TYPE_RX_BYTES;
   1823     private static int TYPE_RX_PACKETS;
   1824     private static int TYPE_TX_BYTES;
   1825     private static int TYPE_TX_PACKETS;
   1826     private static int TYPE_TCP_RX_PACKETS;
   1827     private static int TYPE_TCP_TX_PACKETS;
   1828 
   1829     private static native long nativeGetTotalStat(int type, boolean useBpfStats);
   1830     private static native long nativeGetIfaceStat(String iface, int type, boolean useBpfStats);
   1831     private static native long nativeGetUidStat(int uid, int type, boolean useBpfStats);
   1832 }
   1833