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