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.DUMP;
     22 import static android.Manifest.permission.MODIFY_NETWORK_ACCOUNTING;
     23 import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
     24 import static android.content.Intent.ACTION_SHUTDOWN;
     25 import static android.content.Intent.ACTION_UID_REMOVED;
     26 import static android.content.Intent.ACTION_USER_REMOVED;
     27 import static android.content.Intent.EXTRA_UID;
     28 import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
     29 import static android.net.ConnectivityManager.isNetworkTypeMobile;
     30 import static android.net.NetworkStats.IFACE_ALL;
     31 import static android.net.NetworkStats.SET_ALL;
     32 import static android.net.NetworkStats.SET_DEFAULT;
     33 import static android.net.NetworkStats.SET_FOREGROUND;
     34 import static android.net.NetworkStats.TAG_NONE;
     35 import static android.net.NetworkStats.UID_ALL;
     36 import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
     37 import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
     38 import static android.net.TrafficStats.KB_IN_BYTES;
     39 import static android.net.TrafficStats.MB_IN_BYTES;
     40 import static android.provider.Settings.Global.NETSTATS_DEV_BUCKET_DURATION;
     41 import static android.provider.Settings.Global.NETSTATS_DEV_DELETE_AGE;
     42 import static android.provider.Settings.Global.NETSTATS_DEV_PERSIST_BYTES;
     43 import static android.provider.Settings.Global.NETSTATS_DEV_ROTATE_AGE;
     44 import static android.provider.Settings.Global.NETSTATS_GLOBAL_ALERT_BYTES;
     45 import static android.provider.Settings.Global.NETSTATS_POLL_INTERVAL;
     46 import static android.provider.Settings.Global.NETSTATS_SAMPLE_ENABLED;
     47 import static android.provider.Settings.Global.NETSTATS_TIME_CACHE_MAX_AGE;
     48 import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION;
     49 import static android.provider.Settings.Global.NETSTATS_UID_DELETE_AGE;
     50 import static android.provider.Settings.Global.NETSTATS_UID_PERSIST_BYTES;
     51 import static android.provider.Settings.Global.NETSTATS_UID_ROTATE_AGE;
     52 import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION;
     53 import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
     54 import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
     55 import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
     56 import static android.text.format.DateUtils.DAY_IN_MILLIS;
     57 import static android.text.format.DateUtils.HOUR_IN_MILLIS;
     58 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
     59 import static android.text.format.DateUtils.SECOND_IN_MILLIS;
     60 import static com.android.internal.util.Preconditions.checkNotNull;
     61 import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
     62 import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
     63 import static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet;
     64 
     65 import android.Manifest;
     66 import android.app.AlarmManager;
     67 import android.app.AppOpsManager;
     68 import android.app.IAlarmManager;
     69 import android.app.PendingIntent;
     70 import android.app.admin.DeviceAdminInfo;
     71 import android.app.admin.DevicePolicyManagerInternal;
     72 import android.content.BroadcastReceiver;
     73 import android.content.ContentResolver;
     74 import android.content.Context;
     75 import android.content.Intent;
     76 import android.content.IntentFilter;
     77 import android.content.pm.ApplicationInfo;
     78 import android.content.pm.PackageManager;
     79 import android.net.IConnectivityManager;
     80 import android.net.INetworkManagementEventObserver;
     81 import android.net.INetworkStatsService;
     82 import android.net.INetworkStatsSession;
     83 import android.net.LinkProperties;
     84 import android.net.NetworkIdentity;
     85 import android.net.NetworkInfo;
     86 import android.net.NetworkState;
     87 import android.net.NetworkStats;
     88 import android.net.NetworkStats.NonMonotonicObserver;
     89 import android.net.NetworkStatsHistory;
     90 import android.net.NetworkTemplate;
     91 import android.net.TrafficStats;
     92 import android.os.Binder;
     93 import android.os.DropBoxManager;
     94 import android.os.Environment;
     95 import android.os.Handler;
     96 import android.os.HandlerThread;
     97 import android.os.INetworkManagementService;
     98 import android.os.Message;
     99 import android.os.PowerManager;
    100 import android.os.Process;
    101 import android.os.RemoteException;
    102 import android.os.ServiceManager;
    103 import android.os.SystemClock;
    104 import android.os.UserHandle;
    105 import android.provider.Settings;
    106 import android.provider.Settings.Global;
    107 import android.telephony.TelephonyManager;
    108 import android.text.format.DateUtils;
    109 import android.util.ArrayMap;
    110 import android.util.ArraySet;
    111 import android.util.EventLog;
    112 import android.util.Log;
    113 import android.util.MathUtils;
    114 import android.util.NtpTrustedTime;
    115 import android.util.Slog;
    116 import android.util.SparseIntArray;
    117 import android.util.TrustedTime;
    118 
    119 import com.android.internal.annotations.VisibleForTesting;
    120 import com.android.internal.net.VpnInfo;
    121 import com.android.internal.util.ArrayUtils;
    122 import com.android.internal.util.FileRotator;
    123 import com.android.internal.util.IndentingPrintWriter;
    124 import com.android.server.EventLogTags;
    125 import com.android.server.LocalServices;
    126 import com.android.server.connectivity.Tethering;
    127 
    128 import java.io.File;
    129 import java.io.FileDescriptor;
    130 import java.io.IOException;
    131 import java.io.PrintWriter;
    132 import java.util.Arrays;
    133 import java.util.HashSet;
    134 import java.util.List;
    135 
    136 /**
    137  * Collect and persist detailed network statistics, and provide this data to
    138  * other system services.
    139  */
    140 public class NetworkStatsService extends INetworkStatsService.Stub {
    141     private static final String TAG = "NetworkStats";
    142     private static final boolean LOGV = false;
    143 
    144     private static final int MSG_PERFORM_POLL = 1;
    145     private static final int MSG_UPDATE_IFACES = 2;
    146     private static final int MSG_REGISTER_GLOBAL_ALERT = 3;
    147 
    148     /** Flags to control detail level of poll event. */
    149     private static final int FLAG_PERSIST_NETWORK = 0x1;
    150     private static final int FLAG_PERSIST_UID = 0x2;
    151     private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID;
    152     private static final int FLAG_PERSIST_FORCE = 0x100;
    153 
    154     private static final String TAG_NETSTATS_ERROR = "netstats_error";
    155 
    156     private final Context mContext;
    157     private final INetworkManagementService mNetworkManager;
    158     private final AlarmManager mAlarmManager;
    159     private final TrustedTime mTime;
    160     private final TelephonyManager mTeleManager;
    161     private final NetworkStatsSettings mSettings;
    162 
    163     private final File mSystemDir;
    164     private final File mBaseDir;
    165 
    166     private final PowerManager.WakeLock mWakeLock;
    167 
    168     private IConnectivityManager mConnManager;
    169 
    170     @VisibleForTesting
    171     public static final String ACTION_NETWORK_STATS_POLL =
    172             "com.android.server.action.NETWORK_STATS_POLL";
    173     public static final String ACTION_NETWORK_STATS_UPDATED =
    174             "com.android.server.action.NETWORK_STATS_UPDATED";
    175 
    176     private PendingIntent mPollIntent;
    177 
    178     private static final String PREFIX_DEV = "dev";
    179     private static final String PREFIX_XT = "xt";
    180     private static final String PREFIX_UID = "uid";
    181     private static final String PREFIX_UID_TAG = "uid_tag";
    182 
    183     /**
    184      * Settings that can be changed externally.
    185      */
    186     public interface NetworkStatsSettings {
    187         public long getPollInterval();
    188         public long getTimeCacheMaxAge();
    189         public boolean getSampleEnabled();
    190 
    191         public static class Config {
    192             public final long bucketDuration;
    193             public final long rotateAgeMillis;
    194             public final long deleteAgeMillis;
    195 
    196             public Config(long bucketDuration, long rotateAgeMillis, long deleteAgeMillis) {
    197                 this.bucketDuration = bucketDuration;
    198                 this.rotateAgeMillis = rotateAgeMillis;
    199                 this.deleteAgeMillis = deleteAgeMillis;
    200             }
    201         }
    202 
    203         public Config getDevConfig();
    204         public Config getXtConfig();
    205         public Config getUidConfig();
    206         public Config getUidTagConfig();
    207 
    208         public long getGlobalAlertBytes(long def);
    209         public long getDevPersistBytes(long def);
    210         public long getXtPersistBytes(long def);
    211         public long getUidPersistBytes(long def);
    212         public long getUidTagPersistBytes(long def);
    213     }
    214 
    215     private final Object mStatsLock = new Object();
    216 
    217     /** Set of currently active ifaces. */
    218     private final ArrayMap<String, NetworkIdentitySet> mActiveIfaces = new ArrayMap<>();
    219     /** Set of currently active ifaces for UID stats. */
    220     private final ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces = new ArrayMap<>();
    221     /** Current default active iface. */
    222     private String mActiveIface;
    223     /** Set of any ifaces associated with mobile networks since boot. */
    224     private String[] mMobileIfaces = new String[0];
    225 
    226     private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
    227             new DropBoxNonMonotonicObserver();
    228 
    229     private NetworkStatsRecorder mDevRecorder;
    230     private NetworkStatsRecorder mXtRecorder;
    231     private NetworkStatsRecorder mUidRecorder;
    232     private NetworkStatsRecorder mUidTagRecorder;
    233 
    234     /** Cached {@link #mXtRecorder} stats. */
    235     private NetworkStatsCollection mXtStatsCached;
    236 
    237     /** Current counter sets for each UID. */
    238     private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
    239 
    240     /** Data layer operation counters for splicing into other structures. */
    241     private NetworkStats mUidOperations = new NetworkStats(0L, 10);
    242 
    243     private final Handler mHandler;
    244 
    245     private boolean mSystemReady;
    246     private long mPersistThreshold = 2 * MB_IN_BYTES;
    247     private long mGlobalAlertBytes;
    248 
    249     public NetworkStatsService(
    250             Context context, INetworkManagementService networkManager, IAlarmManager alarmManager) {
    251         this(context, networkManager, alarmManager, NtpTrustedTime.getInstance(context),
    252                 getDefaultSystemDir(), new DefaultNetworkStatsSettings(context));
    253     }
    254 
    255     private static File getDefaultSystemDir() {
    256         return new File(Environment.getDataDirectory(), "system");
    257     }
    258 
    259     public NetworkStatsService(Context context, INetworkManagementService networkManager,
    260             IAlarmManager alarmManager, TrustedTime time, File systemDir,
    261             NetworkStatsSettings settings) {
    262         mContext = checkNotNull(context, "missing Context");
    263         mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService");
    264         mTime = checkNotNull(time, "missing TrustedTime");
    265         mTeleManager = checkNotNull(TelephonyManager.getDefault(), "missing TelephonyManager");
    266         mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
    267         mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    268 
    269         final PowerManager powerManager = (PowerManager) context.getSystemService(
    270                 Context.POWER_SERVICE);
    271         mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
    272 
    273         HandlerThread thread = new HandlerThread(TAG);
    274         thread.start();
    275         mHandler = new Handler(thread.getLooper(), mHandlerCallback);
    276 
    277         mSystemDir = checkNotNull(systemDir);
    278         mBaseDir = new File(systemDir, "netstats");
    279         mBaseDir.mkdirs();
    280     }
    281 
    282     public void bindConnectivityManager(IConnectivityManager connManager) {
    283         mConnManager = checkNotNull(connManager, "missing IConnectivityManager");
    284     }
    285 
    286     public void systemReady() {
    287         mSystemReady = true;
    288 
    289         if (!isBandwidthControlEnabled()) {
    290             Slog.w(TAG, "bandwidth controls disabled, unable to track stats");
    291             return;
    292         }
    293 
    294         // create data recorders along with historical rotators
    295         mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
    296         mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false);
    297         mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
    298         mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
    299 
    300         updatePersistThresholds();
    301 
    302         synchronized (mStatsLock) {
    303             // upgrade any legacy stats, migrating them to rotated files
    304             maybeUpgradeLegacyStatsLocked();
    305 
    306             // read historical network stats from disk, since policy service
    307             // might need them right away.
    308             mXtStatsCached = mXtRecorder.getOrLoadCompleteLocked();
    309 
    310             // bootstrap initial stats to prevent double-counting later
    311             bootstrapStatsLocked();
    312         }
    313 
    314         // watch for tethering changes
    315         final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED);
    316         mContext.registerReceiver(mTetherReceiver, tetherFilter, null, mHandler);
    317 
    318         // listen for periodic polling events
    319         final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL);
    320         mContext.registerReceiver(mPollReceiver, pollFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
    321 
    322         // listen for uid removal to clean stats
    323         final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED);
    324         mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler);
    325 
    326         // listen for user changes to clean stats
    327         final IntentFilter userFilter = new IntentFilter(ACTION_USER_REMOVED);
    328         mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
    329 
    330         // persist stats during clean shutdown
    331         final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN);
    332         mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
    333 
    334         try {
    335             mNetworkManager.registerObserver(mAlertObserver);
    336         } catch (RemoteException e) {
    337             // ignored; service lives in system_server
    338         }
    339 
    340         registerPollAlarmLocked();
    341         registerGlobalAlert();
    342     }
    343 
    344     private NetworkStatsRecorder buildRecorder(
    345             String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
    346         final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
    347                 Context.DROPBOX_SERVICE);
    348         return new NetworkStatsRecorder(new FileRotator(
    349                 mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
    350                 mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags);
    351     }
    352 
    353     private void shutdownLocked() {
    354         mContext.unregisterReceiver(mTetherReceiver);
    355         mContext.unregisterReceiver(mPollReceiver);
    356         mContext.unregisterReceiver(mRemovedReceiver);
    357         mContext.unregisterReceiver(mShutdownReceiver);
    358 
    359         final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
    360                 : System.currentTimeMillis();
    361 
    362         // persist any pending stats
    363         mDevRecorder.forcePersistLocked(currentTime);
    364         mXtRecorder.forcePersistLocked(currentTime);
    365         mUidRecorder.forcePersistLocked(currentTime);
    366         mUidTagRecorder.forcePersistLocked(currentTime);
    367 
    368         mDevRecorder = null;
    369         mXtRecorder = null;
    370         mUidRecorder = null;
    371         mUidTagRecorder = null;
    372 
    373         mXtStatsCached = null;
    374 
    375         mSystemReady = false;
    376     }
    377 
    378     private void maybeUpgradeLegacyStatsLocked() {
    379         File file;
    380         try {
    381             file = new File(mSystemDir, "netstats.bin");
    382             if (file.exists()) {
    383                 mDevRecorder.importLegacyNetworkLocked(file);
    384                 file.delete();
    385             }
    386 
    387             file = new File(mSystemDir, "netstats_xt.bin");
    388             if (file.exists()) {
    389                 file.delete();
    390             }
    391 
    392             file = new File(mSystemDir, "netstats_uid.bin");
    393             if (file.exists()) {
    394                 mUidRecorder.importLegacyUidLocked(file);
    395                 mUidTagRecorder.importLegacyUidLocked(file);
    396                 file.delete();
    397             }
    398         } catch (IOException e) {
    399             Log.wtf(TAG, "problem during legacy upgrade", e);
    400         } catch (OutOfMemoryError e) {
    401             Log.wtf(TAG, "problem during legacy upgrade", e);
    402         }
    403     }
    404 
    405     /**
    406      * Clear any existing {@link #ACTION_NETWORK_STATS_POLL} alarms, and
    407      * reschedule based on current {@link NetworkStatsSettings#getPollInterval()}.
    408      */
    409     private void registerPollAlarmLocked() {
    410         if (mPollIntent != null) {
    411             mAlarmManager.cancel(mPollIntent);
    412         }
    413 
    414         mPollIntent = PendingIntent.getBroadcast(
    415                 mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
    416 
    417         final long currentRealtime = SystemClock.elapsedRealtime();
    418         mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
    419                 mSettings.getPollInterval(), mPollIntent);
    420     }
    421 
    422     /**
    423      * Register for a global alert that is delivered through
    424      * {@link INetworkManagementEventObserver} once a threshold amount of data
    425      * has been transferred.
    426      */
    427     private void registerGlobalAlert() {
    428         try {
    429             mNetworkManager.setGlobalAlert(mGlobalAlertBytes);
    430         } catch (IllegalStateException e) {
    431             Slog.w(TAG, "problem registering for global alert: " + e);
    432         } catch (RemoteException e) {
    433             // ignored; service lives in system_server
    434         }
    435     }
    436 
    437     @Override
    438     public INetworkStatsSession openSession() {
    439         return createSession(null, /* poll on create */ false);
    440     }
    441 
    442     @Override
    443     public INetworkStatsSession openSessionForUsageStats(final String callingPackage) {
    444         return createSession(callingPackage, /* poll on create */ true);
    445     }
    446 
    447     private INetworkStatsSession createSession(final String callingPackage, boolean pollOnCreate) {
    448         assertBandwidthControlEnabled();
    449 
    450         if (pollOnCreate) {
    451             final long ident = Binder.clearCallingIdentity();
    452             try {
    453                 performPoll(FLAG_PERSIST_ALL);
    454             } finally {
    455                 Binder.restoreCallingIdentity(ident);
    456             }
    457         }
    458 
    459         // return an IBinder which holds strong references to any loaded stats
    460         // for its lifetime; when caller closes only weak references remain.
    461 
    462         return new INetworkStatsSession.Stub() {
    463             private NetworkStatsCollection mUidComplete;
    464             private NetworkStatsCollection mUidTagComplete;
    465             private String mCallingPackage = callingPackage;
    466 
    467             private NetworkStatsCollection getUidComplete() {
    468                 synchronized (mStatsLock) {
    469                     if (mUidComplete == null) {
    470                         mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
    471                     }
    472                     return mUidComplete;
    473                 }
    474             }
    475 
    476             private NetworkStatsCollection getUidTagComplete() {
    477                 synchronized (mStatsLock) {
    478                     if (mUidTagComplete == null) {
    479                         mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
    480                     }
    481                     return mUidTagComplete;
    482                 }
    483             }
    484 
    485             @Override
    486             public int[] getRelevantUids() {
    487                 enforcePermissionForManagedAdmin(mCallingPackage);
    488                 return getUidComplete().getRelevantUids();
    489             }
    490 
    491             @Override
    492             public NetworkStats getDeviceSummaryForNetwork(NetworkTemplate template, long start,
    493                     long end) {
    494                 enforcePermission(mCallingPackage);
    495                 NetworkStats result = new NetworkStats(end - start, 1);
    496                 final long ident = Binder.clearCallingIdentity();
    497                 try {
    498                     result.combineAllValues(internalGetSummaryForNetwork(template, start, end));
    499                 } finally {
    500                     Binder.restoreCallingIdentity(ident);
    501                 }
    502                 return result;
    503             }
    504 
    505             @Override
    506             public NetworkStats getSummaryForNetwork(
    507                     NetworkTemplate template, long start, long end) {
    508                 enforcePermission(mCallingPackage);
    509                 return internalGetSummaryForNetwork(template, start, end);
    510             }
    511 
    512             @Override
    513             public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
    514                 return internalGetHistoryForNetwork(template, fields);
    515             }
    516 
    517             @Override
    518             public NetworkStats getSummaryForAllUid(
    519                     NetworkTemplate template, long start, long end, boolean includeTags) {
    520                 enforcePermissionForManagedAdmin(mCallingPackage);
    521                 final NetworkStats stats = getUidComplete().getSummary(template, start, end);
    522                 if (includeTags) {
    523                     final NetworkStats tagStats = getUidTagComplete()
    524                             .getSummary(template, start, end);
    525                     stats.combineAllValues(tagStats);
    526                 }
    527                 return stats;
    528             }
    529 
    530             @Override
    531             public NetworkStatsHistory getHistoryForUid(
    532                     NetworkTemplate template, int uid, int set, int tag, int fields) {
    533                 enforcePermissionForManagedAdmin(mCallingPackage);
    534                 if (tag == TAG_NONE) {
    535                     return getUidComplete().getHistory(template, uid, set, tag, fields);
    536                 } else {
    537                     return getUidTagComplete().getHistory(template, uid, set, tag, fields);
    538                 }
    539             }
    540 
    541             @Override
    542             public NetworkStatsHistory getHistoryIntervalForUid(
    543                     NetworkTemplate template, int uid, int set, int tag, int fields,
    544                     long start, long end) {
    545                 enforcePermissionForManagedAdmin(mCallingPackage);
    546                 if (tag == TAG_NONE) {
    547                     return getUidComplete().getHistory(template, uid, set, tag, fields, start, end);
    548                 } else {
    549                     return getUidTagComplete().getHistory(template, uid, set, tag, fields,
    550                             start, end);
    551                 }
    552             }
    553 
    554             @Override
    555             public void close() {
    556                 mUidComplete = null;
    557                 mUidTagComplete = null;
    558             }
    559         };
    560     }
    561 
    562     private boolean hasAppOpsPermission(String callingPackage) {
    563         final int callingUid = Binder.getCallingUid();
    564         boolean appOpsAllow = false;
    565         if (callingPackage != null) {
    566             AppOpsManager appOps = (AppOpsManager) mContext.getSystemService(
    567                     Context.APP_OPS_SERVICE);
    568 
    569             final int mode = appOps.checkOp(AppOpsManager.OP_GET_USAGE_STATS,
    570                     callingUid, callingPackage);
    571             if (mode == AppOpsManager.MODE_DEFAULT) {
    572                 // The default behavior here is to check if PackageManager has given the app
    573                 // permission.
    574                 final int permissionCheck = mContext.checkCallingPermission(
    575                         Manifest.permission.PACKAGE_USAGE_STATS);
    576                 appOpsAllow = permissionCheck == PackageManager.PERMISSION_GRANTED;
    577             }
    578             appOpsAllow = (mode == AppOpsManager.MODE_ALLOWED);
    579         }
    580         return appOpsAllow;
    581     }
    582 
    583     private void enforcePermissionForManagedAdmin(String callingPackage) {
    584         boolean hasPermission = hasAppOpsPermission(callingPackage);
    585         if (!hasPermission) {
    586             // Profile and device owners are exempt from permission checking.
    587             final int callingUid = Binder.getCallingUid();
    588             final DevicePolicyManagerInternal dpmi = LocalServices.getService(
    589                     DevicePolicyManagerInternal.class);
    590 
    591             // Device owners are also profile owners so it is enough to check for that.
    592             if (dpmi != null && dpmi.isActiveAdminWithPolicy(callingUid,
    593                     DeviceAdminInfo.USES_POLICY_PROFILE_OWNER)) {
    594                 return;
    595             }
    596         }
    597         if (!hasPermission) {
    598             mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
    599         }
    600     }
    601 
    602     private void enforcePermission(String callingPackage) {
    603         boolean appOpsAllow = hasAppOpsPermission(callingPackage);
    604         if (!appOpsAllow) {
    605             mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
    606         }
    607     }
    608 
    609 
    610     /**
    611      * Return network summary, splicing between DEV and XT stats when
    612      * appropriate.
    613      */
    614     private NetworkStats internalGetSummaryForNetwork(
    615             NetworkTemplate template, long start, long end) {
    616         // We've been using pure XT stats long enough that we no longer need to
    617         // splice DEV and XT together.
    618         return mXtStatsCached.getSummary(template, start, end);
    619     }
    620 
    621     /**
    622      * Return network history, splicing between DEV and XT stats when
    623      * appropriate.
    624      */
    625     private NetworkStatsHistory internalGetHistoryForNetwork(NetworkTemplate template, int fields) {
    626         // We've been using pure XT stats long enough that we no longer need to
    627         // splice DEV and XT together.
    628         return mXtStatsCached.getHistory(template, UID_ALL, SET_ALL, TAG_NONE, fields);
    629     }
    630 
    631     @Override
    632     public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
    633         mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
    634         assertBandwidthControlEnabled();
    635         return internalGetSummaryForNetwork(template, start, end).getTotalBytes();
    636     }
    637 
    638     @Override
    639     public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
    640         if (Binder.getCallingUid() != uid) {
    641             mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
    642         }
    643         assertBandwidthControlEnabled();
    644 
    645         // TODO: switch to data layer stats once kernel exports
    646         // for now, read network layer stats and flatten across all ifaces
    647         final long token = Binder.clearCallingIdentity();
    648         final NetworkStats networkLayer;
    649         try {
    650             networkLayer = mNetworkManager.getNetworkStatsUidDetail(uid);
    651         } finally {
    652             Binder.restoreCallingIdentity(token);
    653         }
    654 
    655         // splice in operation counts
    656         networkLayer.spliceOperationsFrom(mUidOperations);
    657 
    658         final NetworkStats dataLayer = new NetworkStats(
    659                 networkLayer.getElapsedRealtime(), networkLayer.size());
    660 
    661         NetworkStats.Entry entry = null;
    662         for (int i = 0; i < networkLayer.size(); i++) {
    663             entry = networkLayer.getValues(i, entry);
    664             entry.iface = IFACE_ALL;
    665             dataLayer.combineValues(entry);
    666         }
    667 
    668         return dataLayer;
    669     }
    670 
    671     @Override
    672     public String[] getMobileIfaces() {
    673         return mMobileIfaces;
    674     }
    675 
    676     @Override
    677     public void incrementOperationCount(int uid, int tag, int operationCount) {
    678         if (Binder.getCallingUid() != uid) {
    679             mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG);
    680         }
    681 
    682         if (operationCount < 0) {
    683             throw new IllegalArgumentException("operation count can only be incremented");
    684         }
    685         if (tag == TAG_NONE) {
    686             throw new IllegalArgumentException("operation count must have specific tag");
    687         }
    688 
    689         synchronized (mStatsLock) {
    690             final int set = mActiveUidCounterSet.get(uid, SET_DEFAULT);
    691             mUidOperations.combineValues(
    692                     mActiveIface, uid, set, tag, 0L, 0L, 0L, 0L, operationCount);
    693             mUidOperations.combineValues(
    694                     mActiveIface, uid, set, TAG_NONE, 0L, 0L, 0L, 0L, operationCount);
    695         }
    696     }
    697 
    698     @Override
    699     public void setUidForeground(int uid, boolean uidForeground) {
    700         mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG);
    701 
    702         synchronized (mStatsLock) {
    703             final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT;
    704             final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT);
    705             if (oldSet != set) {
    706                 mActiveUidCounterSet.put(uid, set);
    707                 setKernelCounterSet(uid, set);
    708             }
    709         }
    710     }
    711 
    712     @Override
    713     public void forceUpdateIfaces() {
    714         mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
    715         assertBandwidthControlEnabled();
    716 
    717         final long token = Binder.clearCallingIdentity();
    718         try {
    719             updateIfaces();
    720         } finally {
    721             Binder.restoreCallingIdentity(token);
    722         }
    723     }
    724 
    725     @Override
    726     public void forceUpdate() {
    727         mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
    728         assertBandwidthControlEnabled();
    729 
    730         final long token = Binder.clearCallingIdentity();
    731         try {
    732             performPoll(FLAG_PERSIST_ALL);
    733         } finally {
    734             Binder.restoreCallingIdentity(token);
    735         }
    736     }
    737 
    738     @Override
    739     public void advisePersistThreshold(long thresholdBytes) {
    740         mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG);
    741         assertBandwidthControlEnabled();
    742 
    743         // clamp threshold into safe range
    744         mPersistThreshold = MathUtils.constrain(thresholdBytes, 128 * KB_IN_BYTES, 2 * MB_IN_BYTES);
    745         if (LOGV) {
    746             Slog.v(TAG, "advisePersistThreshold() given " + thresholdBytes + ", clamped to "
    747                     + mPersistThreshold);
    748         }
    749 
    750         // update and persist if beyond new thresholds
    751         final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
    752                 : System.currentTimeMillis();
    753         synchronized (mStatsLock) {
    754             if (!mSystemReady) return;
    755 
    756             updatePersistThresholds();
    757 
    758             mDevRecorder.maybePersistLocked(currentTime);
    759             mXtRecorder.maybePersistLocked(currentTime);
    760             mUidRecorder.maybePersistLocked(currentTime);
    761             mUidTagRecorder.maybePersistLocked(currentTime);
    762         }
    763 
    764         // re-arm global alert
    765         registerGlobalAlert();
    766     }
    767 
    768     /**
    769      * Update {@link NetworkStatsRecorder} and {@link #mGlobalAlertBytes} to
    770      * reflect current {@link #mPersistThreshold} value. Always defers to
    771      * {@link Global} values when defined.
    772      */
    773     private void updatePersistThresholds() {
    774         mDevRecorder.setPersistThreshold(mSettings.getDevPersistBytes(mPersistThreshold));
    775         mXtRecorder.setPersistThreshold(mSettings.getXtPersistBytes(mPersistThreshold));
    776         mUidRecorder.setPersistThreshold(mSettings.getUidPersistBytes(mPersistThreshold));
    777         mUidTagRecorder.setPersistThreshold(mSettings.getUidTagPersistBytes(mPersistThreshold));
    778         mGlobalAlertBytes = mSettings.getGlobalAlertBytes(mPersistThreshold);
    779     }
    780 
    781     /**
    782      * Receiver that watches for {@link Tethering} to claim interface pairs.
    783      */
    784     private BroadcastReceiver mTetherReceiver = new BroadcastReceiver() {
    785         @Override
    786         public void onReceive(Context context, Intent intent) {
    787             // on background handler thread, and verified CONNECTIVITY_INTERNAL
    788             // permission above.
    789             performPoll(FLAG_PERSIST_NETWORK);
    790         }
    791     };
    792 
    793     private BroadcastReceiver mPollReceiver = new BroadcastReceiver() {
    794         @Override
    795         public void onReceive(Context context, Intent intent) {
    796             // on background handler thread, and verified UPDATE_DEVICE_STATS
    797             // permission above.
    798             performPoll(FLAG_PERSIST_ALL);
    799 
    800             // verify that we're watching global alert
    801             registerGlobalAlert();
    802         }
    803     };
    804 
    805     private BroadcastReceiver mRemovedReceiver = new BroadcastReceiver() {
    806         @Override
    807         public void onReceive(Context context, Intent intent) {
    808             // on background handler thread, and UID_REMOVED is protected
    809             // broadcast.
    810 
    811             final int uid = intent.getIntExtra(EXTRA_UID, -1);
    812             if (uid == -1) return;
    813 
    814             synchronized (mStatsLock) {
    815                 mWakeLock.acquire();
    816                 try {
    817                     removeUidsLocked(uid);
    818                 } finally {
    819                     mWakeLock.release();
    820                 }
    821             }
    822         }
    823     };
    824 
    825     private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
    826         @Override
    827         public void onReceive(Context context, Intent intent) {
    828             // On background handler thread, and USER_REMOVED is protected
    829             // broadcast.
    830 
    831             final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
    832             if (userId == -1) return;
    833 
    834             synchronized (mStatsLock) {
    835                 mWakeLock.acquire();
    836                 try {
    837                     removeUserLocked(userId);
    838                 } finally {
    839                     mWakeLock.release();
    840                 }
    841             }
    842         }
    843     };
    844 
    845     private BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() {
    846         @Override
    847         public void onReceive(Context context, Intent intent) {
    848             // SHUTDOWN is protected broadcast.
    849             synchronized (mStatsLock) {
    850                 shutdownLocked();
    851             }
    852         }
    853     };
    854 
    855     /**
    856      * Observer that watches for {@link INetworkManagementService} alerts.
    857      */
    858     private INetworkManagementEventObserver mAlertObserver = new BaseNetworkObserver() {
    859         @Override
    860         public void limitReached(String limitName, String iface) {
    861             // only someone like NMS should be calling us
    862             mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
    863 
    864             if (LIMIT_GLOBAL_ALERT.equals(limitName)) {
    865                 // kick off background poll to collect network stats; UID stats
    866                 // are handled during normal polling interval.
    867                 final int flags = FLAG_PERSIST_NETWORK;
    868                 mHandler.obtainMessage(MSG_PERFORM_POLL, flags, 0).sendToTarget();
    869 
    870                 // re-arm global alert for next update
    871                 mHandler.obtainMessage(MSG_REGISTER_GLOBAL_ALERT).sendToTarget();
    872             }
    873         }
    874     };
    875 
    876     private void updateIfaces() {
    877         synchronized (mStatsLock) {
    878             mWakeLock.acquire();
    879             try {
    880                 updateIfacesLocked();
    881             } finally {
    882                 mWakeLock.release();
    883             }
    884         }
    885     }
    886 
    887     /**
    888      * Inspect all current {@link NetworkState} to derive mapping from {@code
    889      * iface} to {@link NetworkStatsHistory}. When multiple {@link NetworkInfo}
    890      * are active on a single {@code iface}, they are combined under a single
    891      * {@link NetworkIdentitySet}.
    892      */
    893     private void updateIfacesLocked() {
    894         if (!mSystemReady) return;
    895         if (LOGV) Slog.v(TAG, "updateIfacesLocked()");
    896 
    897         // take one last stats snapshot before updating iface mapping. this
    898         // isn't perfect, since the kernel may already be counting traffic from
    899         // the updated network.
    900 
    901         // poll, but only persist network stats to keep codepath fast. UID stats
    902         // will be persisted during next alarm poll event.
    903         performPollLocked(FLAG_PERSIST_NETWORK);
    904 
    905         final NetworkState[] states;
    906         final LinkProperties activeLink;
    907         try {
    908             states = mConnManager.getAllNetworkState();
    909             activeLink = mConnManager.getActiveLinkProperties();
    910         } catch (RemoteException e) {
    911             // ignored; service lives in system_server
    912             return;
    913         }
    914 
    915         mActiveIface = activeLink != null ? activeLink.getInterfaceName() : null;
    916 
    917         // Rebuild active interfaces based on connected networks
    918         mActiveIfaces.clear();
    919         mActiveUidIfaces.clear();
    920 
    921         final ArraySet<String> mobileIfaces = new ArraySet<>();
    922         for (NetworkState state : states) {
    923             if (state.networkInfo.isConnected()) {
    924                 final boolean isMobile = isNetworkTypeMobile(state.networkInfo.getType());
    925                 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);
    926 
    927                 // Traffic occurring on the base interface is always counted for
    928                 // both total usage and UID details.
    929                 final String baseIface = state.linkProperties.getInterfaceName();
    930                 if (baseIface != null) {
    931                     findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident);
    932                     findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident);
    933                     if (isMobile) {
    934                         mobileIfaces.add(baseIface);
    935                     }
    936                 }
    937 
    938                 // Traffic occurring on stacked interfaces is usually clatd,
    939                 // which is already accounted against its final egress interface
    940                 // by the kernel. Thus, we only need to collect stacked
    941                 // interface stats at the UID level.
    942                 final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks();
    943                 for (LinkProperties stackedLink : stackedLinks) {
    944                     final String stackedIface = stackedLink.getInterfaceName();
    945                     if (stackedIface != null) {
    946                         findOrCreateNetworkIdentitySet(mActiveUidIfaces, stackedIface).add(ident);
    947                         if (isMobile) {
    948                             mobileIfaces.add(stackedIface);
    949                         }
    950                     }
    951                 }
    952             }
    953         }
    954 
    955         mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]);
    956     }
    957 
    958     private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet(
    959             ArrayMap<K, NetworkIdentitySet> map, K key) {
    960         NetworkIdentitySet ident = map.get(key);
    961         if (ident == null) {
    962             ident = new NetworkIdentitySet();
    963             map.put(key, ident);
    964         }
    965         return ident;
    966     }
    967 
    968     private void recordSnapshotLocked(long currentTime) throws RemoteException {
    969         // snapshot and record current counters; read UID stats first to
    970         // avoid overcounting dev stats.
    971         final NetworkStats uidSnapshot = getNetworkStatsUidDetail();
    972         final NetworkStats xtSnapshot = mNetworkManager.getNetworkStatsSummaryXt();
    973         final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev();
    974 
    975         VpnInfo[] vpnArray = mConnManager.getAllVpnInfo();
    976         mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, null, currentTime);
    977         mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, null, currentTime);
    978         mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, vpnArray, currentTime);
    979         mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, vpnArray, currentTime);
    980     }
    981 
    982     /**
    983      * Bootstrap initial stats snapshot, usually during {@link #systemReady()}
    984      * so we have baseline values without double-counting.
    985      */
    986     private void bootstrapStatsLocked() {
    987         final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
    988                 : System.currentTimeMillis();
    989 
    990         try {
    991             recordSnapshotLocked(currentTime);
    992         } catch (IllegalStateException e) {
    993             Slog.w(TAG, "problem reading network stats: " + e);
    994         } catch (RemoteException e) {
    995             // ignored; service lives in system_server
    996         }
    997     }
    998 
    999     private void performPoll(int flags) {
   1000         // try refreshing time source when stale
   1001         if (mTime.getCacheAge() > mSettings.getTimeCacheMaxAge()) {
   1002             mTime.forceRefresh();
   1003         }
   1004 
   1005         synchronized (mStatsLock) {
   1006             mWakeLock.acquire();
   1007 
   1008             try {
   1009                 performPollLocked(flags);
   1010             } finally {
   1011                 mWakeLock.release();
   1012             }
   1013         }
   1014     }
   1015 
   1016     /**
   1017      * Periodic poll operation, reading current statistics and recording into
   1018      * {@link NetworkStatsHistory}.
   1019      */
   1020     private void performPollLocked(int flags) {
   1021         if (!mSystemReady) return;
   1022         if (LOGV) Slog.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")");
   1023 
   1024         final long startRealtime = SystemClock.elapsedRealtime();
   1025 
   1026         final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0;
   1027         final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
   1028         final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
   1029 
   1030         // TODO: consider marking "untrusted" times in historical stats
   1031         final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
   1032                 : System.currentTimeMillis();
   1033 
   1034         try {
   1035             recordSnapshotLocked(currentTime);
   1036         } catch (IllegalStateException e) {
   1037             Log.wtf(TAG, "problem reading network stats", e);
   1038             return;
   1039         } catch (RemoteException e) {
   1040             // ignored; service lives in system_server
   1041             return;
   1042         }
   1043 
   1044         // persist any pending data depending on requested flags
   1045         if (persistForce) {
   1046             mDevRecorder.forcePersistLocked(currentTime);
   1047             mXtRecorder.forcePersistLocked(currentTime);
   1048             mUidRecorder.forcePersistLocked(currentTime);
   1049             mUidTagRecorder.forcePersistLocked(currentTime);
   1050         } else {
   1051             if (persistNetwork) {
   1052                 mDevRecorder.maybePersistLocked(currentTime);
   1053                 mXtRecorder.maybePersistLocked(currentTime);
   1054             }
   1055             if (persistUid) {
   1056                 mUidRecorder.maybePersistLocked(currentTime);
   1057                 mUidTagRecorder.maybePersistLocked(currentTime);
   1058             }
   1059         }
   1060 
   1061         if (LOGV) {
   1062             final long duration = SystemClock.elapsedRealtime() - startRealtime;
   1063             Slog.v(TAG, "performPollLocked() took " + duration + "ms");
   1064         }
   1065 
   1066         if (mSettings.getSampleEnabled()) {
   1067             // sample stats after each full poll
   1068             performSampleLocked();
   1069         }
   1070 
   1071         // finally, dispatch updated event to any listeners
   1072         final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
   1073         updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
   1074         mContext.sendBroadcastAsUser(updatedIntent, UserHandle.ALL,
   1075                 READ_NETWORK_USAGE_HISTORY);
   1076     }
   1077 
   1078     /**
   1079      * Sample recent statistics summary into {@link EventLog}.
   1080      */
   1081     private void performSampleLocked() {
   1082         // TODO: migrate trustedtime fixes to separate binary log events
   1083         final long trustedTime = mTime.hasCache() ? mTime.currentTimeMillis() : -1;
   1084 
   1085         NetworkTemplate template;
   1086         NetworkStats.Entry devTotal;
   1087         NetworkStats.Entry xtTotal;
   1088         NetworkStats.Entry uidTotal;
   1089 
   1090         // collect mobile sample
   1091         template = buildTemplateMobileWildcard();
   1092         devTotal = mDevRecorder.getTotalSinceBootLocked(template);
   1093         xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
   1094         uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
   1095 
   1096         EventLogTags.writeNetstatsMobileSample(
   1097                 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
   1098                 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
   1099                 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
   1100                 trustedTime);
   1101 
   1102         // collect wifi sample
   1103         template = buildTemplateWifiWildcard();
   1104         devTotal = mDevRecorder.getTotalSinceBootLocked(template);
   1105         xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
   1106         uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
   1107 
   1108         EventLogTags.writeNetstatsWifiSample(
   1109                 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
   1110                 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
   1111                 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
   1112                 trustedTime);
   1113     }
   1114 
   1115     /**
   1116      * Clean up {@link #mUidRecorder} after UID is removed.
   1117      */
   1118     private void removeUidsLocked(int... uids) {
   1119         if (LOGV) Slog.v(TAG, "removeUidsLocked() for UIDs " + Arrays.toString(uids));
   1120 
   1121         // Perform one last poll before removing
   1122         performPollLocked(FLAG_PERSIST_ALL);
   1123 
   1124         mUidRecorder.removeUidsLocked(uids);
   1125         mUidTagRecorder.removeUidsLocked(uids);
   1126 
   1127         // Clear kernel stats associated with UID
   1128         for (int uid : uids) {
   1129             resetKernelUidStats(uid);
   1130         }
   1131     }
   1132 
   1133     /**
   1134      * Clean up {@link #mUidRecorder} after user is removed.
   1135      */
   1136     private void removeUserLocked(int userId) {
   1137         if (LOGV) Slog.v(TAG, "removeUserLocked() for userId=" + userId);
   1138 
   1139         // Build list of UIDs that we should clean up
   1140         int[] uids = new int[0];
   1141         final List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
   1142                 PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_DISABLED_COMPONENTS);
   1143         for (ApplicationInfo app : apps) {
   1144             final int uid = UserHandle.getUid(userId, app.uid);
   1145             uids = ArrayUtils.appendInt(uids, uid);
   1146         }
   1147 
   1148         removeUidsLocked(uids);
   1149     }
   1150 
   1151     @Override
   1152     protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) {
   1153         mContext.enforceCallingOrSelfPermission(DUMP, TAG);
   1154 
   1155         long duration = DateUtils.DAY_IN_MILLIS;
   1156         final HashSet<String> argSet = new HashSet<String>();
   1157         for (String arg : args) {
   1158             argSet.add(arg);
   1159 
   1160             if (arg.startsWith("--duration=")) {
   1161                 try {
   1162                     duration = Long.parseLong(arg.substring(11));
   1163                 } catch (NumberFormatException ignored) {
   1164                 }
   1165             }
   1166         }
   1167 
   1168         // usage: dumpsys netstats --full --uid --tag --poll --checkin
   1169         final boolean poll = argSet.contains("--poll") || argSet.contains("poll");
   1170         final boolean checkin = argSet.contains("--checkin");
   1171         final boolean fullHistory = argSet.contains("--full") || argSet.contains("full");
   1172         final boolean includeUid = argSet.contains("--uid") || argSet.contains("detail");
   1173         final boolean includeTag = argSet.contains("--tag") || argSet.contains("detail");
   1174 
   1175         final IndentingPrintWriter pw = new IndentingPrintWriter(rawWriter, "  ");
   1176 
   1177         synchronized (mStatsLock) {
   1178             if (poll) {
   1179                 performPollLocked(FLAG_PERSIST_ALL | FLAG_PERSIST_FORCE);
   1180                 pw.println("Forced poll");
   1181                 return;
   1182             }
   1183 
   1184             if (checkin) {
   1185                 final long end = System.currentTimeMillis();
   1186                 final long start = end - duration;
   1187 
   1188                 pw.print("v1,");
   1189                 pw.print(start / SECOND_IN_MILLIS); pw.print(',');
   1190                 pw.print(end / SECOND_IN_MILLIS); pw.println();
   1191 
   1192                 pw.println("xt");
   1193                 mXtRecorder.dumpCheckin(rawWriter, start, end);
   1194 
   1195                 if (includeUid) {
   1196                     pw.println("uid");
   1197                     mUidRecorder.dumpCheckin(rawWriter, start, end);
   1198                 }
   1199                 if (includeTag) {
   1200                     pw.println("tag");
   1201                     mUidTagRecorder.dumpCheckin(rawWriter, start, end);
   1202                 }
   1203                 return;
   1204             }
   1205 
   1206             pw.println("Active interfaces:");
   1207             pw.increaseIndent();
   1208             for (int i = 0; i < mActiveIfaces.size(); i++) {
   1209                 pw.printPair("iface", mActiveIfaces.keyAt(i));
   1210                 pw.printPair("ident", mActiveIfaces.valueAt(i));
   1211                 pw.println();
   1212             }
   1213             pw.decreaseIndent();
   1214 
   1215             pw.println("Active UID interfaces:");
   1216             pw.increaseIndent();
   1217             for (int i = 0; i < mActiveUidIfaces.size(); i++) {
   1218                 pw.printPair("iface", mActiveUidIfaces.keyAt(i));
   1219                 pw.printPair("ident", mActiveUidIfaces.valueAt(i));
   1220                 pw.println();
   1221             }
   1222             pw.decreaseIndent();
   1223 
   1224             pw.println("Dev stats:");
   1225             pw.increaseIndent();
   1226             mDevRecorder.dumpLocked(pw, fullHistory);
   1227             pw.decreaseIndent();
   1228 
   1229             pw.println("Xt stats:");
   1230             pw.increaseIndent();
   1231             mXtRecorder.dumpLocked(pw, fullHistory);
   1232             pw.decreaseIndent();
   1233 
   1234             if (includeUid) {
   1235                 pw.println("UID stats:");
   1236                 pw.increaseIndent();
   1237                 mUidRecorder.dumpLocked(pw, fullHistory);
   1238                 pw.decreaseIndent();
   1239             }
   1240 
   1241             if (includeTag) {
   1242                 pw.println("UID tag stats:");
   1243                 pw.increaseIndent();
   1244                 mUidTagRecorder.dumpLocked(pw, fullHistory);
   1245                 pw.decreaseIndent();
   1246             }
   1247         }
   1248     }
   1249 
   1250     /**
   1251      * Return snapshot of current UID statistics, including any
   1252      * {@link TrafficStats#UID_TETHERING} and {@link #mUidOperations} values.
   1253      */
   1254     private NetworkStats getNetworkStatsUidDetail() throws RemoteException {
   1255         final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL);
   1256 
   1257         // fold tethering stats and operations into uid snapshot
   1258         final NetworkStats tetherSnapshot = getNetworkStatsTethering();
   1259         uidSnapshot.combineAllValues(tetherSnapshot);
   1260         uidSnapshot.combineAllValues(mUidOperations);
   1261 
   1262         return uidSnapshot;
   1263     }
   1264 
   1265     /**
   1266      * Return snapshot of current tethering statistics. Will return empty
   1267      * {@link NetworkStats} if any problems are encountered.
   1268      */
   1269     private NetworkStats getNetworkStatsTethering() throws RemoteException {
   1270         try {
   1271             return mNetworkManager.getNetworkStatsTethering();
   1272         } catch (IllegalStateException e) {
   1273             Log.wtf(TAG, "problem reading network stats", e);
   1274             return new NetworkStats(0L, 10);
   1275         }
   1276     }
   1277 
   1278     private Handler.Callback mHandlerCallback = new Handler.Callback() {
   1279         @Override
   1280         public boolean handleMessage(Message msg) {
   1281             switch (msg.what) {
   1282                 case MSG_PERFORM_POLL: {
   1283                     final int flags = msg.arg1;
   1284                     performPoll(flags);
   1285                     return true;
   1286                 }
   1287                 case MSG_UPDATE_IFACES: {
   1288                     updateIfaces();
   1289                     return true;
   1290                 }
   1291                 case MSG_REGISTER_GLOBAL_ALERT: {
   1292                     registerGlobalAlert();
   1293                     return true;
   1294                 }
   1295                 default: {
   1296                     return false;
   1297                 }
   1298             }
   1299         }
   1300     };
   1301 
   1302     private void assertBandwidthControlEnabled() {
   1303         if (!isBandwidthControlEnabled()) {
   1304             throw new IllegalStateException("Bandwidth module disabled");
   1305         }
   1306     }
   1307 
   1308     private boolean isBandwidthControlEnabled() {
   1309         final long token = Binder.clearCallingIdentity();
   1310         try {
   1311             return mNetworkManager.isBandwidthControlEnabled();
   1312         } catch (RemoteException e) {
   1313             // ignored; service lives in system_server
   1314             return false;
   1315         } finally {
   1316             Binder.restoreCallingIdentity(token);
   1317         }
   1318     }
   1319 
   1320     private class DropBoxNonMonotonicObserver implements NonMonotonicObserver<String> {
   1321         @Override
   1322         public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
   1323                 int rightIndex, String cookie) {
   1324             Log.w(TAG, "found non-monotonic values; saving to dropbox");
   1325 
   1326             // record error for debugging
   1327             final StringBuilder builder = new StringBuilder();
   1328             builder.append("found non-monotonic " + cookie + " values at left[" + leftIndex
   1329                     + "] - right[" + rightIndex + "]\n");
   1330             builder.append("left=").append(left).append('\n');
   1331             builder.append("right=").append(right).append('\n');
   1332 
   1333             final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
   1334                     Context.DROPBOX_SERVICE);
   1335             dropBox.addText(TAG_NETSTATS_ERROR, builder.toString());
   1336         }
   1337     }
   1338 
   1339     /**
   1340      * Default external settings that read from
   1341      * {@link android.provider.Settings.Global}.
   1342      */
   1343     private static class DefaultNetworkStatsSettings implements NetworkStatsSettings {
   1344         private final ContentResolver mResolver;
   1345 
   1346         public DefaultNetworkStatsSettings(Context context) {
   1347             mResolver = checkNotNull(context.getContentResolver());
   1348             // TODO: adjust these timings for production builds
   1349         }
   1350 
   1351         private long getGlobalLong(String name, long def) {
   1352             return Settings.Global.getLong(mResolver, name, def);
   1353         }
   1354         private boolean getGlobalBoolean(String name, boolean def) {
   1355             final int defInt = def ? 1 : 0;
   1356             return Settings.Global.getInt(mResolver, name, defInt) != 0;
   1357         }
   1358 
   1359         @Override
   1360         public long getPollInterval() {
   1361             return getGlobalLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS);
   1362         }
   1363         @Override
   1364         public long getTimeCacheMaxAge() {
   1365             return getGlobalLong(NETSTATS_TIME_CACHE_MAX_AGE, DAY_IN_MILLIS);
   1366         }
   1367         @Override
   1368         public long getGlobalAlertBytes(long def) {
   1369             return getGlobalLong(NETSTATS_GLOBAL_ALERT_BYTES, def);
   1370         }
   1371         @Override
   1372         public boolean getSampleEnabled() {
   1373             return getGlobalBoolean(NETSTATS_SAMPLE_ENABLED, true);
   1374         }
   1375         @Override
   1376         public Config getDevConfig() {
   1377             return new Config(getGlobalLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
   1378                     getGlobalLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
   1379                     getGlobalLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS));
   1380         }
   1381         @Override
   1382         public Config getXtConfig() {
   1383             return getDevConfig();
   1384         }
   1385         @Override
   1386         public Config getUidConfig() {
   1387             return new Config(getGlobalLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
   1388                     getGlobalLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS),
   1389                     getGlobalLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS));
   1390         }
   1391         @Override
   1392         public Config getUidTagConfig() {
   1393             return new Config(getGlobalLong(NETSTATS_UID_TAG_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
   1394                     getGlobalLong(NETSTATS_UID_TAG_ROTATE_AGE, 5 * DAY_IN_MILLIS),
   1395                     getGlobalLong(NETSTATS_UID_TAG_DELETE_AGE, 15 * DAY_IN_MILLIS));
   1396         }
   1397         @Override
   1398         public long getDevPersistBytes(long def) {
   1399             return getGlobalLong(NETSTATS_DEV_PERSIST_BYTES, def);
   1400         }
   1401         @Override
   1402         public long getXtPersistBytes(long def) {
   1403             return getDevPersistBytes(def);
   1404         }
   1405         @Override
   1406         public long getUidPersistBytes(long def) {
   1407             return getGlobalLong(NETSTATS_UID_PERSIST_BYTES, def);
   1408         }
   1409         @Override
   1410         public long getUidTagPersistBytes(long def) {
   1411             return getGlobalLong(NETSTATS_UID_TAG_PERSIST_BYTES, def);
   1412         }
   1413     }
   1414 }
   1415