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