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