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