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