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