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