1 /* 2 * Copyright 2020 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.stats.pull; 18 19 import static android.app.AppOpsManager.OP_FLAG_SELF; 20 import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXIED; 21 import static android.app.usage.NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN; 22 import static android.app.usage.NetworkStatsManager.FLAG_POLL_FORCE; 23 import static android.app.usage.NetworkStatsManager.FLAG_POLL_ON_OPEN; 24 import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; 25 import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS; 26 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 27 import static android.net.NetworkCapabilities.TRANSPORT_WIFI; 28 import static android.net.NetworkIdentity.OEM_PAID; 29 import static android.net.NetworkIdentity.OEM_PRIVATE; 30 import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; 31 import static android.net.NetworkStats.METERED_ALL; 32 import static android.net.NetworkStats.ROAMING_ALL; 33 import static android.net.NetworkTemplate.MATCH_ETHERNET; 34 import static android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD; 35 import static android.net.NetworkTemplate.MATCH_WIFI_WILDCARD; 36 import static android.net.NetworkTemplate.NETWORK_TYPE_ALL; 37 import static android.net.NetworkTemplate.OEM_MANAGED_ALL; 38 import static android.net.NetworkTemplate.buildTemplateMobileWildcard; 39 import static android.net.NetworkTemplate.buildTemplateMobileWithRatType; 40 import static android.net.NetworkTemplate.buildTemplateWifiWildcard; 41 import static android.net.NetworkTemplate.getAllCollapsedRatTypes; 42 import static android.os.Debug.getIonHeapsSizeKb; 43 import static android.os.Process.LAST_SHARED_APPLICATION_GID; 44 import static android.os.Process.getUidForPid; 45 import static android.os.storage.VolumeInfo.TYPE_PRIVATE; 46 import static android.os.storage.VolumeInfo.TYPE_PUBLIC; 47 import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION; 48 import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID; 49 import static android.util.MathUtils.constrain; 50 51 import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; 52 import static com.android.internal.util.FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER__OPPORTUNISTIC_DATA_SUB__NOT_OPPORTUNISTIC; 53 import static com.android.internal.util.FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER__OPPORTUNISTIC_DATA_SUB__OPPORTUNISTIC; 54 import static com.android.internal.util.FrameworkStatsLog.TIME_ZONE_DETECTOR_STATE__DETECTION_MODE__GEO; 55 import static com.android.internal.util.FrameworkStatsLog.TIME_ZONE_DETECTOR_STATE__DETECTION_MODE__MANUAL; 56 import static com.android.internal.util.FrameworkStatsLog.TIME_ZONE_DETECTOR_STATE__DETECTION_MODE__TELEPHONY; 57 import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem; 58 import static com.android.server.stats.pull.IonMemoryUtil.readProcessSystemIonHeapSizesFromDebugfs; 59 import static com.android.server.stats.pull.IonMemoryUtil.readSystemIonHeapSizeFromDebugfs; 60 import static com.android.server.stats.pull.ProcfsMemoryUtil.getProcessCmdlines; 61 import static com.android.server.stats.pull.ProcfsMemoryUtil.readCmdlineFromProcfs; 62 import static com.android.server.stats.pull.ProcfsMemoryUtil.readMemorySnapshotFromProcfs; 63 64 import static java.lang.Math.min; 65 import static java.util.concurrent.TimeUnit.HOURS; 66 import static java.util.concurrent.TimeUnit.MICROSECONDS; 67 68 import android.annotation.NonNull; 69 import android.annotation.Nullable; 70 import android.app.ActivityManagerInternal; 71 import android.app.AppOpsManager; 72 import android.app.AppOpsManager.HistoricalOp; 73 import android.app.AppOpsManager.HistoricalOps; 74 import android.app.AppOpsManager.HistoricalOpsRequest; 75 import android.app.AppOpsManager.HistoricalPackageOps; 76 import android.app.AppOpsManager.HistoricalUidOps; 77 import android.app.INotificationManager; 78 import android.app.ProcessMemoryState; 79 import android.app.RuntimeAppOpAccessMessage; 80 import android.app.StatsManager; 81 import android.app.StatsManager.PullAtomMetadata; 82 import android.bluetooth.BluetoothActivityEnergyInfo; 83 import android.bluetooth.BluetoothAdapter; 84 import android.bluetooth.UidTraffic; 85 import android.content.Context; 86 import android.content.pm.ApplicationInfo; 87 import android.content.pm.PackageInfo; 88 import android.content.pm.PackageManager; 89 import android.content.pm.PermissionInfo; 90 import android.content.pm.UserInfo; 91 import android.hardware.biometrics.BiometricsProtoEnums; 92 import android.hardware.face.FaceManager; 93 import android.hardware.fingerprint.FingerprintManager; 94 import android.hardware.health.V2_0.IHealth; 95 import android.net.ConnectivityManager; 96 import android.net.INetworkStatsService; 97 import android.net.INetworkStatsSession; 98 import android.net.Network; 99 import android.net.NetworkRequest; 100 import android.net.NetworkStats; 101 import android.net.NetworkTemplate; 102 import android.net.wifi.WifiManager; 103 import android.os.AsyncTask; 104 import android.os.BatteryStats; 105 import android.os.BatteryStatsInternal; 106 import android.os.Binder; 107 import android.os.Build; 108 import android.os.Bundle; 109 import android.os.CoolingDevice; 110 import android.os.Environment; 111 import android.os.IStoraged; 112 import android.os.IThermalEventListener; 113 import android.os.IThermalService; 114 import android.os.OutcomeReceiver; 115 import android.os.ParcelFileDescriptor; 116 import android.os.Parcelable; 117 import android.os.Process; 118 import android.os.RemoteException; 119 import android.os.ServiceManager; 120 import android.os.ServiceSpecificException; 121 import android.os.StatFs; 122 import android.os.SynchronousResultReceiver; 123 import android.os.SystemClock; 124 import android.os.SystemProperties; 125 import android.os.Temperature; 126 import android.os.Trace; 127 import android.os.UserHandle; 128 import android.os.UserManager; 129 import android.os.connectivity.WifiActivityEnergyInfo; 130 import android.os.incremental.IncrementalManager; 131 import android.os.storage.DiskInfo; 132 import android.os.storage.StorageManager; 133 import android.os.storage.VolumeInfo; 134 import android.provider.DeviceConfig; 135 import android.provider.Settings; 136 import android.security.metrics.CrashStats; 137 import android.security.metrics.IKeystoreMetrics; 138 import android.security.metrics.KeyCreationWithAuthInfo; 139 import android.security.metrics.KeyCreationWithGeneralInfo; 140 import android.security.metrics.KeyCreationWithPurposeAndModesInfo; 141 import android.security.metrics.KeyOperationWithGeneralInfo; 142 import android.security.metrics.KeyOperationWithPurposeAndModesInfo; 143 import android.security.metrics.Keystore2AtomWithOverflow; 144 import android.security.metrics.KeystoreAtom; 145 import android.security.metrics.KeystoreAtomPayload; 146 import android.security.metrics.RkpErrorStats; 147 import android.security.metrics.RkpPoolStats; 148 import android.security.metrics.StorageStats; 149 import android.stats.storage.StorageEnums; 150 import android.telephony.ModemActivityInfo; 151 import android.telephony.SubscriptionInfo; 152 import android.telephony.SubscriptionManager; 153 import android.telephony.TelephonyManager; 154 import android.text.TextUtils; 155 import android.util.ArrayMap; 156 import android.util.ArraySet; 157 import android.util.Log; 158 import android.util.Slog; 159 import android.util.SparseArray; 160 import android.util.StatsEvent; 161 import android.util.proto.ProtoOutputStream; 162 163 import com.android.internal.annotations.GuardedBy; 164 import com.android.internal.app.procstats.IProcessStats; 165 import com.android.internal.app.procstats.ProcessStats; 166 import com.android.internal.os.BackgroundThread; 167 import com.android.internal.os.BatterySipper; 168 import com.android.internal.os.BatteryStatsHelper; 169 import com.android.internal.os.BinderCallsStats.ExportedCallStat; 170 import com.android.internal.os.DmabufInfoReader; 171 import com.android.internal.os.KernelCpuBpfTracking; 172 import com.android.internal.os.KernelCpuThreadReader; 173 import com.android.internal.os.KernelCpuThreadReaderDiff; 174 import com.android.internal.os.KernelCpuThreadReaderSettingsObserver; 175 import com.android.internal.os.KernelCpuTotalBpfMapReader; 176 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader; 177 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader; 178 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader; 179 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader; 180 import com.android.internal.os.KernelSingleProcessCpuThreadReader.ProcessCpuUsage; 181 import com.android.internal.os.KernelWakelockReader; 182 import com.android.internal.os.KernelWakelockStats; 183 import com.android.internal.os.LooperStats; 184 import com.android.internal.os.PowerProfile; 185 import com.android.internal.os.ProcessCpuTracker; 186 import com.android.internal.os.SelectedProcessCpuThreadReader; 187 import com.android.internal.os.StoragedUidIoStatsReader; 188 import com.android.internal.os.SystemServerCpuThreadReader.SystemServiceCpuThreadTimes; 189 import com.android.internal.util.CollectionUtils; 190 import com.android.internal.util.FrameworkStatsLog; 191 import com.android.role.RoleManagerLocal; 192 import com.android.server.BatteryService; 193 import com.android.server.BinderCallsStatsService; 194 import com.android.server.LocalManagerRegistry; 195 import com.android.server.LocalServices; 196 import com.android.server.SystemService; 197 import com.android.server.SystemServiceManager; 198 import com.android.server.am.MemoryStatUtil.MemoryStat; 199 import com.android.server.notification.NotificationManagerService; 200 import com.android.server.stats.pull.IonMemoryUtil.IonAllocations; 201 import com.android.server.stats.pull.ProcfsMemoryUtil.MemorySnapshot; 202 import com.android.server.stats.pull.netstats.NetworkStatsExt; 203 import com.android.server.stats.pull.netstats.SubInfo; 204 import com.android.server.storage.DiskStatsFileLogger; 205 import com.android.server.storage.DiskStatsLoggingService; 206 import com.android.server.timezonedetector.MetricsTimeZoneDetectorState; 207 import com.android.server.timezonedetector.TimeZoneDetectorInternal; 208 209 import libcore.io.IoUtils; 210 211 import org.json.JSONArray; 212 import org.json.JSONException; 213 import org.json.JSONObject; 214 215 import java.io.File; 216 import java.io.FileOutputStream; 217 import java.io.IOException; 218 import java.io.InputStream; 219 import java.time.Instant; 220 import java.time.temporal.ChronoUnit; 221 import java.util.ArrayList; 222 import java.util.Arrays; 223 import java.util.Comparator; 224 import java.util.HashSet; 225 import java.util.List; 226 import java.util.Map; 227 import java.util.MissingResourceException; 228 import java.util.Random; 229 import java.util.Set; 230 import java.util.UUID; 231 import java.util.concurrent.CompletableFuture; 232 import java.util.concurrent.ExecutionException; 233 import java.util.concurrent.Executor; 234 import java.util.concurrent.ThreadLocalRandom; 235 import java.util.concurrent.TimeUnit; 236 import java.util.concurrent.TimeoutException; 237 import java.util.function.BiConsumer; 238 239 /** 240 * SystemService containing PullAtomCallbacks that are registered with statsd. 241 * 242 * @hide 243 */ 244 public class StatsPullAtomService extends SystemService { 245 private static final String TAG = "StatsPullAtomService"; 246 private static final boolean DEBUG = true; 247 248 // Random seed stable for StatsPullAtomService life cycle - can be used for stable sampling 249 private static final int RANDOM_SEED = new Random().nextInt(); 250 251 private static final int DIMENSION_KEY_SIZE_HARD_LIMIT = 800; 252 private static final int DIMENSION_KEY_SIZE_SOFT_LIMIT = 500; 253 private static final long APP_OPS_SAMPLING_INITIALIZATION_DELAY_MILLIS = 45000; 254 private static final int APP_OPS_SIZE_ESTIMATE = 2000; 255 256 private static final String RESULT_RECEIVER_CONTROLLER_KEY = "controller_activity"; 257 /** 258 * How long to wait on an individual subsystem to return its stats. 259 */ 260 private static final long EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS = 2000; 261 private static final long MILLIS_PER_SEC = 1000; 262 private static final long MILLI_AMP_HR_TO_NANO_AMP_SECS = 1_000_000L * 3600L; 263 264 /** 265 * The default bucket duration used when query a snapshot from NetworkStatsService. 266 * The value should be sync with NetworkStatsService#DefaultNetworkStatsSettings#getUidConfig. 267 */ 268 private static final long NETSTATS_UID_DEFAULT_BUCKET_DURATION_MS = HOURS.toMillis(2); 269 270 private static final int MAX_BATTERY_STATS_HELPER_FREQUENCY_MS = 1000; 271 private static final int CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES = 8; 272 private static final int OP_FLAGS_PULLED = OP_FLAG_SELF | OP_FLAG_TRUSTED_PROXIED; 273 private static final String COMMON_PERMISSION_PREFIX = "android.permission."; 274 private static final String APP_OPS_TARGET_COLLECTION_SIZE = "app_ops_target_collection_size"; 275 private static final String DANGEROUS_PERMISSION_STATE_SAMPLE_RATE = 276 "dangerous_permission_state_sample_rate"; 277 278 /** Parameters relating to ProcStats data upload. */ 279 // Maximum shards to use when generating StatsEvent objects from ProcStats. 280 private static final int MAX_PROCSTATS_SHARDS = 5; 281 // Should match MAX_PAYLOAD_SIZE in StatsEvent, minus a small amount for overhead/metadata. 282 private static final int MAX_PROCSTATS_SHARD_SIZE = 48 * 1024; // 48 KB 283 // In ProcessStats, we measure the size of a raw ProtoOutputStream, before compaction. This 284 // typically runs 35-45% larger than the compacted size that will be written to StatsEvent. 285 // Hence, we can allow a little more room in each shard before moving to the next. Make this 286 // 20% as a conservative estimate. 287 private static final int MAX_PROCSTATS_RAW_SHARD_SIZE = (int) (MAX_PROCSTATS_SHARD_SIZE * 1.20); 288 289 /** 290 * Threshold to filter out small CPU times at frequency per UID. Those small values appear 291 * because of more precise accounting in a BPF program. Discarding them reduces the data by at 292 * least 20% with negligible error. 293 */ 294 private static final int MIN_CPU_TIME_PER_UID_FREQ = 10; 295 296 /** Number of entries in CpuCyclesPerUidCluster atom stored in an array for each cluster. */ 297 private static final int CPU_CYCLES_PER_UID_CLUSTER_VALUES = 3; 298 299 private final Object mThermalLock = new Object(); 300 @GuardedBy("mThermalLock") 301 private IThermalService mThermalService; 302 303 private final Object mStoragedLock = new Object(); 304 @GuardedBy("mStoragedLock") 305 private IStoraged mStorageService; 306 307 private final Object mNotificationStatsLock = new Object(); 308 @GuardedBy("mNotificationStatsLock") 309 private INotificationManager mNotificationManagerService; 310 311 @GuardedBy("mProcStatsLock") 312 private IProcessStats mProcessStatsService; 313 314 @GuardedBy("mProcessCpuTimeLock") 315 private ProcessCpuTracker mProcessCpuTracker; 316 317 @GuardedBy("mDebugElapsedClockLock") 318 private long mDebugElapsedClockPreviousValue = 0; 319 @GuardedBy("mDebugElapsedClockLock") 320 private long mDebugElapsedClockPullCount = 0; 321 322 @GuardedBy("mDebugFailingElapsedClockLock") 323 private long mDebugFailingElapsedClockPreviousValue = 0; 324 @GuardedBy("mDebugFailingElapsedClockLock") 325 private long mDebugFailingElapsedClockPullCount = 0; 326 327 private final Context mContext; 328 private StatsManager mStatsManager; 329 private StorageManager mStorageManager; 330 private WifiManager mWifiManager; 331 private TelephonyManager mTelephony; 332 private SubscriptionManager mSubscriptionManager; 333 334 @GuardedBy("mKernelWakelockLock") 335 private KernelWakelockReader mKernelWakelockReader; 336 @GuardedBy("mKernelWakelockLock") 337 private KernelWakelockStats mTmpWakelockStats; 338 339 @GuardedBy("mDiskIoLock") 340 private StoragedUidIoStatsReader mStoragedUidIoStatsReader; 341 342 // Disables throttler on CPU time readers. 343 @GuardedBy("mCpuTimePerUidLock") 344 private KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader; 345 @GuardedBy("mCpuTimePerUidFreqLock") 346 private KernelCpuUidFreqTimeReader mCpuUidFreqTimeReader; 347 @GuardedBy("mCpuActiveTimeLock") 348 private KernelCpuUidActiveTimeReader mCpuUidActiveTimeReader; 349 @GuardedBy("mClusterTimeLock") 350 private KernelCpuUidClusterTimeReader mCpuUidClusterTimeReader; 351 352 @GuardedBy("mProcStatsLock") 353 private File mBaseDir; 354 355 @GuardedBy("mHealthHalLock") 356 private BatteryService.HealthServiceWrapper mHealthService; 357 358 @Nullable 359 @GuardedBy("mCpuTimePerThreadFreqLock") 360 private KernelCpuThreadReaderDiff mKernelCpuThreadReader; 361 362 private final Object mBatteryStatsHelperLock = new Object(); 363 @GuardedBy("mBatteryStatsHelperLock") 364 private BatteryStatsHelper mBatteryStatsHelper = null; 365 @GuardedBy("mBatteryStatsHelperLock") 366 private long mBatteryStatsHelperTimestampMs = -MAX_BATTERY_STATS_HELPER_FREQUENCY_MS; 367 368 private StatsPullAtomCallbackImpl mStatsCallbackImpl; 369 370 @GuardedBy("mAttributedAppOpsLock") 371 private int mAppOpsSamplingRate = 0; 372 private final Object mDangerousAppOpsListLock = new Object(); 373 @GuardedBy("mDangerousAppOpsListLock") 374 private final ArraySet<Integer> mDangerousAppOpsList = new ArraySet<>(); 375 376 // Baselines that stores list of NetworkStats right after initializing, with associated 377 // information. This is used to calculate difference when pulling BytesTransfer atoms. 378 @NonNull 379 @GuardedBy("mDataBytesTransferLock") 380 private final ArrayList<NetworkStatsExt> mNetworkStatsBaselines = new ArrayList<>(); 381 382 // Listener for monitoring subscriptions changed event. 383 private StatsSubscriptionsListener mStatsSubscriptionsListener; 384 // List that stores SubInfo of subscriptions that ever appeared since boot. 385 @GuardedBy("mDataBytesTransferLock") 386 private final ArrayList<SubInfo> mHistoricalSubs = new ArrayList<>(); 387 388 private SelectedProcessCpuThreadReader mSurfaceFlingerProcessCpuThreadReader; 389 390 // Only access via getIKeystoreMetricsService 391 @GuardedBy("mKeystoreLock") 392 private IKeystoreMetrics mIKeystoreMetrics; 393 394 // Puller locks 395 private final Object mDataBytesTransferLock = new Object(); 396 private final Object mBluetoothBytesTransferLock = new Object(); 397 private final Object mKernelWakelockLock = new Object(); 398 private final Object mCpuTimePerClusterFreqLock = new Object(); 399 private final Object mCpuTimePerUidLock = new Object(); 400 private final Object mCpuTimePerUidFreqLock = new Object(); 401 private final Object mCpuActiveTimeLock = new Object(); 402 private final Object mCpuClusterTimeLock = new Object(); 403 private final Object mWifiActivityInfoLock = new Object(); 404 private final Object mModemActivityInfoLock = new Object(); 405 private final Object mBluetoothActivityInfoLock = new Object(); 406 private final Object mSystemElapsedRealtimeLock = new Object(); 407 private final Object mSystemUptimeLock = new Object(); 408 private final Object mProcessMemoryStateLock = new Object(); 409 private final Object mProcessMemoryHighWaterMarkLock = new Object(); 410 private final Object mProcessMemorySnapshotLock = new Object(); 411 private final Object mSystemIonHeapSizeLock = new Object(); 412 private final Object mIonHeapSizeLock = new Object(); 413 private final Object mProcessSystemIonHeapSizeLock = new Object(); 414 private final Object mTemperatureLock = new Object(); 415 private final Object mCooldownDeviceLock = new Object(); 416 private final Object mBinderCallsStatsLock = new Object(); 417 private final Object mBinderCallsStatsExceptionsLock = new Object(); 418 private final Object mLooperStatsLock = new Object(); 419 private final Object mDiskStatsLock = new Object(); 420 private final Object mDirectoryUsageLock = new Object(); 421 private final Object mAppSizeLock = new Object(); 422 private final Object mCategorySizeLock = new Object(); 423 private final Object mNumBiometricsEnrolledLock = new Object(); 424 private final Object mProcStatsLock = new Object(); 425 private final Object mDiskIoLock = new Object(); 426 private final Object mPowerProfileLock = new Object(); 427 private final Object mProcessCpuTimeLock = new Object(); 428 private final Object mCpuTimePerThreadFreqLock = new Object(); 429 private final Object mDeviceCalculatedPowerUseLock = new Object(); 430 private final Object mDeviceCalculatedPowerBlameUidLock = new Object(); 431 private final Object mDeviceCalculatedPowerBlameOtherLock = new Object(); 432 private final Object mDebugElapsedClockLock = new Object(); 433 private final Object mDebugFailingElapsedClockLock = new Object(); 434 private final Object mBuildInformationLock = new Object(); 435 private final Object mRoleHolderLock = new Object(); 436 private final Object mTimeZoneDataInfoLock = new Object(); 437 private final Object mTimeZoneDetectionInfoLock = new Object(); 438 private final Object mExternalStorageInfoLock = new Object(); 439 private final Object mAppsOnExternalStorageInfoLock = new Object(); 440 private final Object mFaceSettingsLock = new Object(); 441 private final Object mAppOpsLock = new Object(); 442 private final Object mRuntimeAppOpAccessMessageLock = new Object(); 443 private final Object mNotificationRemoteViewsLock = new Object(); 444 private final Object mDangerousPermissionStateLock = new Object(); 445 private final Object mHealthHalLock = new Object(); 446 private final Object mAttributedAppOpsLock = new Object(); 447 private final Object mSettingsStatsLock = new Object(); 448 private final Object mInstalledIncrementalPackagesLock = new Object(); 449 private final Object mKeystoreLock = new Object(); 450 StatsPullAtomService(Context context)451 public StatsPullAtomService(Context context) { 452 super(context); 453 mContext = context; 454 } 455 initializeNativePullers()456 private native void initializeNativePullers(); 457 458 /** 459 * Use of this StatsPullAtomCallbackImpl means we avoid one class per tagId, which we would 460 * get if we used lambdas. 461 * 462 * The pull methods are intentionally left to be package private to avoid the creation 463 * of synthetic methods to save unnecessary bytecode. 464 */ 465 private class StatsPullAtomCallbackImpl implements StatsManager.StatsPullAtomCallback { 466 @Override onPullAtom(int atomTag, List<StatsEvent> data)467 public int onPullAtom(int atomTag, List<StatsEvent> data) { 468 if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) { 469 Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StatsPull-" + atomTag); 470 } 471 try { 472 switch (atomTag) { 473 case FrameworkStatsLog.WIFI_BYTES_TRANSFER: 474 case FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG: 475 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER: 476 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG: 477 case FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED: 478 case FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER: 479 case FrameworkStatsLog.OEM_MANAGED_BYTES_TRANSFER: 480 synchronized (mDataBytesTransferLock) { 481 return pullDataBytesTransferLocked(atomTag, data); 482 } 483 case FrameworkStatsLog.BLUETOOTH_BYTES_TRANSFER: 484 synchronized (mBluetoothBytesTransferLock) { 485 return pullBluetoothBytesTransferLocked(atomTag, data); 486 } 487 case FrameworkStatsLog.KERNEL_WAKELOCK: 488 synchronized (mKernelWakelockLock) { 489 return pullKernelWakelockLocked(atomTag, data); 490 } 491 case FrameworkStatsLog.CPU_TIME_PER_CLUSTER_FREQ: 492 synchronized (mCpuTimePerClusterFreqLock) { 493 return pullCpuTimePerClusterFreqLocked(atomTag, data); 494 } 495 case FrameworkStatsLog.CPU_TIME_PER_UID: 496 synchronized (mCpuTimePerUidLock) { 497 return pullCpuTimePerUidLocked(atomTag, data); 498 } 499 case FrameworkStatsLog.CPU_CYCLES_PER_UID_CLUSTER: 500 // Use the same lock as CPU_TIME_PER_UID_FREQ because data is pulled from 501 // the same source. 502 synchronized (mCpuTimePerUidFreqLock) { 503 return pullCpuCyclesPerUidClusterLocked(atomTag, data); 504 } 505 case FrameworkStatsLog.CPU_TIME_PER_UID_FREQ: 506 synchronized (mCpuTimePerUidFreqLock) { 507 return pullCpuTimePerUidFreqLocked(atomTag, data); 508 } 509 case FrameworkStatsLog.CPU_CYCLES_PER_THREAD_GROUP_CLUSTER: 510 return pullCpuCyclesPerThreadGroupCluster(atomTag, data); 511 case FrameworkStatsLog.CPU_ACTIVE_TIME: 512 synchronized (mCpuActiveTimeLock) { 513 return pullCpuActiveTimeLocked(atomTag, data); 514 } 515 case FrameworkStatsLog.CPU_CLUSTER_TIME: 516 synchronized (mCpuClusterTimeLock) { 517 return pullCpuClusterTimeLocked(atomTag, data); 518 } 519 case FrameworkStatsLog.WIFI_ACTIVITY_INFO: 520 synchronized (mWifiActivityInfoLock) { 521 return pullWifiActivityInfoLocked(atomTag, data); 522 } 523 case FrameworkStatsLog.MODEM_ACTIVITY_INFO: 524 synchronized (mModemActivityInfoLock) { 525 return pullModemActivityInfoLocked(atomTag, data); 526 } 527 case FrameworkStatsLog.BLUETOOTH_ACTIVITY_INFO: 528 synchronized (mBluetoothActivityInfoLock) { 529 return pullBluetoothActivityInfoLocked(atomTag, data); 530 } 531 case FrameworkStatsLog.SYSTEM_ELAPSED_REALTIME: 532 synchronized (mSystemElapsedRealtimeLock) { 533 return pullSystemElapsedRealtimeLocked(atomTag, data); 534 } 535 case FrameworkStatsLog.SYSTEM_UPTIME: 536 synchronized (mSystemUptimeLock) { 537 return pullSystemUptimeLocked(atomTag, data); 538 } 539 case FrameworkStatsLog.PROCESS_MEMORY_STATE: 540 synchronized (mProcessMemoryStateLock) { 541 return pullProcessMemoryStateLocked(atomTag, data); 542 } 543 case FrameworkStatsLog.PROCESS_MEMORY_HIGH_WATER_MARK: 544 synchronized (mProcessMemoryHighWaterMarkLock) { 545 return pullProcessMemoryHighWaterMarkLocked(atomTag, data); 546 } 547 case FrameworkStatsLog.PROCESS_MEMORY_SNAPSHOT: 548 synchronized (mProcessMemorySnapshotLock) { 549 return pullProcessMemorySnapshotLocked(atomTag, data); 550 } 551 case FrameworkStatsLog.SYSTEM_ION_HEAP_SIZE: 552 synchronized (mSystemIonHeapSizeLock) { 553 return pullSystemIonHeapSizeLocked(atomTag, data); 554 } 555 case FrameworkStatsLog.ION_HEAP_SIZE: 556 synchronized (mIonHeapSizeLock) { 557 return pullIonHeapSizeLocked(atomTag, data); 558 } 559 case FrameworkStatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE: 560 synchronized (mProcessSystemIonHeapSizeLock) { 561 return pullProcessSystemIonHeapSizeLocked(atomTag, data); 562 } 563 case FrameworkStatsLog.PROCESS_DMABUF_MEMORY: 564 return pullProcessDmabufMemory(atomTag, data); 565 case FrameworkStatsLog.SYSTEM_MEMORY: 566 return pullSystemMemory(atomTag, data); 567 case FrameworkStatsLog.VMSTAT: 568 return pullVmStat(atomTag, data); 569 case FrameworkStatsLog.TEMPERATURE: 570 synchronized (mTemperatureLock) { 571 return pullTemperatureLocked(atomTag, data); 572 } 573 case FrameworkStatsLog.COOLING_DEVICE: 574 synchronized (mCooldownDeviceLock) { 575 return pullCooldownDeviceLocked(atomTag, data); 576 } 577 case FrameworkStatsLog.BINDER_CALLS: 578 synchronized (mBinderCallsStatsLock) { 579 return pullBinderCallsStatsLocked(atomTag, data); 580 } 581 case FrameworkStatsLog.BINDER_CALLS_EXCEPTIONS: 582 synchronized (mBinderCallsStatsExceptionsLock) { 583 return pullBinderCallsStatsExceptionsLocked(atomTag, data); 584 } 585 case FrameworkStatsLog.LOOPER_STATS: 586 synchronized (mLooperStatsLock) { 587 return pullLooperStatsLocked(atomTag, data); 588 } 589 case FrameworkStatsLog.DISK_STATS: 590 synchronized (mDiskStatsLock) { 591 return pullDiskStatsLocked(atomTag, data); 592 } 593 case FrameworkStatsLog.DIRECTORY_USAGE: 594 synchronized (mDirectoryUsageLock) { 595 return pullDirectoryUsageLocked(atomTag, data); 596 } 597 case FrameworkStatsLog.APP_SIZE: 598 synchronized (mAppSizeLock) { 599 return pullAppSizeLocked(atomTag, data); 600 } 601 case FrameworkStatsLog.CATEGORY_SIZE: 602 synchronized (mCategorySizeLock) { 603 return pullCategorySizeLocked(atomTag, data); 604 } 605 case FrameworkStatsLog.NUM_FINGERPRINTS_ENROLLED: 606 synchronized (mNumBiometricsEnrolledLock) { 607 return pullNumBiometricsEnrolledLocked( 608 BiometricsProtoEnums.MODALITY_FINGERPRINT, atomTag, data); 609 } 610 case FrameworkStatsLog.NUM_FACES_ENROLLED: 611 synchronized (mNumBiometricsEnrolledLock) { 612 return pullNumBiometricsEnrolledLocked( 613 BiometricsProtoEnums.MODALITY_FACE, atomTag, data); 614 } 615 case FrameworkStatsLog.PROC_STATS: 616 synchronized (mProcStatsLock) { 617 return pullProcStatsLocked(ProcessStats.REPORT_ALL, atomTag, data); 618 } 619 case FrameworkStatsLog.PROC_STATS_PKG_PROC: 620 synchronized (mProcStatsLock) { 621 return pullProcStatsLocked(ProcessStats.REPORT_PKG_PROC_STATS, atomTag, 622 data); 623 } 624 case FrameworkStatsLog.DISK_IO: 625 synchronized (mDiskIoLock) { 626 return pullDiskIOLocked(atomTag, data); 627 } 628 case FrameworkStatsLog.POWER_PROFILE: 629 synchronized (mPowerProfileLock) { 630 return pullPowerProfileLocked(atomTag, data); 631 } 632 case FrameworkStatsLog.PROCESS_CPU_TIME: 633 synchronized (mProcessCpuTimeLock) { 634 return pullProcessCpuTimeLocked(atomTag, data); 635 } 636 case FrameworkStatsLog.CPU_TIME_PER_THREAD_FREQ: 637 synchronized (mCpuTimePerThreadFreqLock) { 638 return pullCpuTimePerThreadFreqLocked(atomTag, data); 639 } 640 case FrameworkStatsLog.DEVICE_CALCULATED_POWER_USE: 641 synchronized (mDeviceCalculatedPowerUseLock) { 642 return pullDeviceCalculatedPowerUseLocked(atomTag, data); 643 } 644 case FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_UID: 645 synchronized (mDeviceCalculatedPowerBlameUidLock) { 646 return pullDeviceCalculatedPowerBlameUidLocked(atomTag, data); 647 } 648 case FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_OTHER: 649 synchronized (mDeviceCalculatedPowerBlameOtherLock) { 650 return pullDeviceCalculatedPowerBlameOtherLocked(atomTag, data); 651 } 652 case FrameworkStatsLog.DEBUG_ELAPSED_CLOCK: 653 synchronized (mDebugElapsedClockLock) { 654 return pullDebugElapsedClockLocked(atomTag, data); 655 } 656 case FrameworkStatsLog.DEBUG_FAILING_ELAPSED_CLOCK: 657 synchronized (mDebugFailingElapsedClockLock) { 658 return pullDebugFailingElapsedClockLocked(atomTag, data); 659 } 660 case FrameworkStatsLog.BUILD_INFORMATION: 661 synchronized (mBuildInformationLock) { 662 return pullBuildInformationLocked(atomTag, data); 663 } 664 case FrameworkStatsLog.ROLE_HOLDER: 665 synchronized (mRoleHolderLock) { 666 return pullRoleHolderLocked(atomTag, data); 667 } 668 case FrameworkStatsLog.DANGEROUS_PERMISSION_STATE: 669 // fall-through - same call covers two cases 670 case FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED: 671 synchronized (mDangerousPermissionStateLock) { 672 return pullDangerousPermissionStateLocked(atomTag, data); 673 } 674 case FrameworkStatsLog.TIME_ZONE_DATA_INFO: 675 synchronized (mTimeZoneDataInfoLock) { 676 return pullTimeZoneDataInfoLocked(atomTag, data); 677 } 678 case FrameworkStatsLog.TIME_ZONE_DETECTOR_STATE: 679 synchronized (mTimeZoneDetectionInfoLock) { 680 return pullTimeZoneDetectorStateLocked(atomTag, data); 681 } 682 case FrameworkStatsLog.EXTERNAL_STORAGE_INFO: 683 synchronized (mExternalStorageInfoLock) { 684 return pullExternalStorageInfoLocked(atomTag, data); 685 } 686 case FrameworkStatsLog.APPS_ON_EXTERNAL_STORAGE_INFO: 687 synchronized (mAppsOnExternalStorageInfoLock) { 688 return pullAppsOnExternalStorageInfoLocked(atomTag, data); 689 } 690 case FrameworkStatsLog.FACE_SETTINGS: 691 synchronized (mFaceSettingsLock) { 692 return pullFaceSettingsLocked(atomTag, data); 693 } 694 case FrameworkStatsLog.APP_OPS: 695 synchronized (mAppOpsLock) { 696 return pullAppOpsLocked(atomTag, data); 697 } 698 case FrameworkStatsLog.RUNTIME_APP_OP_ACCESS: 699 synchronized (mRuntimeAppOpAccessMessageLock) { 700 return pullRuntimeAppOpAccessMessageLocked(atomTag, data); 701 } 702 case FrameworkStatsLog.NOTIFICATION_REMOTE_VIEWS: 703 synchronized (mNotificationRemoteViewsLock) { 704 return pullNotificationRemoteViewsLocked(atomTag, data); 705 } 706 case FrameworkStatsLog.BATTERY_LEVEL: 707 case FrameworkStatsLog.REMAINING_BATTERY_CAPACITY: 708 case FrameworkStatsLog.FULL_BATTERY_CAPACITY: 709 case FrameworkStatsLog.BATTERY_VOLTAGE: 710 case FrameworkStatsLog.BATTERY_CYCLE_COUNT: 711 synchronized (mHealthHalLock) { 712 return pullHealthHalLocked(atomTag, data); 713 } 714 case FrameworkStatsLog.ATTRIBUTED_APP_OPS: 715 synchronized (mAttributedAppOpsLock) { 716 return pullAttributedAppOpsLocked(atomTag, data); 717 } 718 case FrameworkStatsLog.SETTING_SNAPSHOT: 719 synchronized (mSettingsStatsLock) { 720 return pullSettingsStatsLocked(atomTag, data); 721 } 722 case FrameworkStatsLog.INSTALLED_INCREMENTAL_PACKAGE: 723 synchronized (mInstalledIncrementalPackagesLock) { 724 return pullInstalledIncrementalPackagesLocked(atomTag, data); 725 } 726 case FrameworkStatsLog.KEYSTORE2_STORAGE_STATS: 727 case FrameworkStatsLog.RKP_POOL_STATS: 728 case FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_GENERAL_INFO: 729 case FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_AUTH_INFO: 730 case FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO: 731 case FrameworkStatsLog.KEYSTORE2_ATOM_WITH_OVERFLOW: 732 case FrameworkStatsLog.KEYSTORE2_KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO: 733 case FrameworkStatsLog.KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO: 734 case FrameworkStatsLog.RKP_ERROR_STATS: 735 case FrameworkStatsLog.KEYSTORE2_CRASH_STATS: 736 return pullKeystoreAtoms(atomTag, data); 737 default: 738 throw new UnsupportedOperationException("Unknown tagId=" + atomTag); 739 } 740 } finally { 741 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); 742 } 743 } 744 } 745 746 @Override onStart()747 public void onStart() { 748 // no op 749 } 750 751 @Override onBootPhase(int phase)752 public void onBootPhase(int phase) { 753 super.onBootPhase(phase); 754 if (phase == PHASE_SYSTEM_SERVICES_READY) { 755 BackgroundThread.getHandler().post(() -> { 756 initializeNativePullers(); // Initialize pullers that need JNI. 757 initializePullersState(); 758 registerPullers(); 759 registerEventListeners(); 760 }); 761 } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { 762 // Network stats related pullers can only be initialized after service is ready. 763 BackgroundThread.getHandler().post(() -> initAndRegisterNetworkStatsPullers()); 764 } 765 } 766 767 // We do not hold locks within this function because it is guaranteed to be called before the 768 // pullers are ever run, as the pullers are not yet registered with statsd. initializePullersState()769 void initializePullersState() { 770 // Get Context Managers 771 mStatsManager = (StatsManager) mContext.getSystemService(Context.STATS_MANAGER); 772 mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 773 mTelephony = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 774 mSubscriptionManager = (SubscriptionManager) 775 mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); 776 mStatsSubscriptionsListener = new StatsSubscriptionsListener(mSubscriptionManager); 777 mStorageManager = (StorageManager) mContext.getSystemService(StorageManager.class); 778 779 // Initialize DiskIO 780 mStoragedUidIoStatsReader = new StoragedUidIoStatsReader(); 781 782 // Initialize PROC_STATS 783 mBaseDir = new File(SystemServiceManager.ensureSystemDir(), "stats_pull"); 784 mBaseDir.mkdirs(); 785 786 // Disables throttler on CPU time readers. 787 mCpuUidUserSysTimeReader = new KernelCpuUidUserSysTimeReader(false); 788 mCpuUidFreqTimeReader = new KernelCpuUidFreqTimeReader(false); 789 mCpuUidActiveTimeReader = new KernelCpuUidActiveTimeReader(false); 790 mCpuUidClusterTimeReader = new KernelCpuUidClusterTimeReader(false); 791 792 // Initialize state for KERNEL_WAKELOCK 793 mKernelWakelockReader = new KernelWakelockReader(); 794 mTmpWakelockStats = new KernelWakelockStats(); 795 796 // Used for CPU_TIME_PER_THREAD_FREQ 797 mKernelCpuThreadReader = 798 KernelCpuThreadReaderSettingsObserver.getSettingsModifiedReader(mContext); 799 800 // Initialize HealthService 801 mHealthService = new BatteryService.HealthServiceWrapper(); 802 try { 803 mHealthService.init(); 804 } catch (RemoteException e) { 805 Slog.e(TAG, "failed to initialize healthHalWrapper"); 806 } 807 808 // Initialize list of AppOps related to DangerousPermissions 809 PackageManager pm = mContext.getPackageManager(); 810 for (int op = 0; op < AppOpsManager._NUM_OP; op++) { 811 String perm = AppOpsManager.opToPermission(op); 812 if (perm == null) { 813 continue; 814 } else { 815 PermissionInfo permInfo; 816 try { 817 permInfo = pm.getPermissionInfo(perm, 0); 818 if (permInfo.getProtection() == PROTECTION_DANGEROUS) { 819 mDangerousAppOpsList.add(op); 820 } 821 } catch (PackageManager.NameNotFoundException exception) { 822 continue; 823 } 824 } 825 } 826 827 mSurfaceFlingerProcessCpuThreadReader = 828 new SelectedProcessCpuThreadReader("/system/bin/surfaceflinger"); 829 830 getIKeystoreMetricsService(); 831 } 832 registerEventListeners()833 void registerEventListeners() { 834 final ConnectivityManager connectivityManager = 835 (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); 836 // Default NetworkRequest should cover all transport types. 837 final NetworkRequest request = new NetworkRequest.Builder().build(); 838 connectivityManager.registerNetworkCallback(request, new ConnectivityStatsCallback()); 839 840 // Enable push notifications of throttling from vendor thermal 841 // management subsystem via thermalservice. 842 IThermalService thermalService = getIThermalService(); 843 if (thermalService != null) { 844 try { 845 thermalService.registerThermalEventListener(new ThermalEventListener()); 846 Slog.i(TAG, "register thermal listener successfully"); 847 } catch (RemoteException e) { 848 Slog.i(TAG, "failed to register thermal listener"); 849 } 850 } 851 } 852 registerPullers()853 void registerPullers() { 854 if (DEBUG) { 855 Slog.d(TAG, "Registering pullers with statsd"); 856 } 857 mStatsCallbackImpl = new StatsPullAtomCallbackImpl(); 858 registerBluetoothBytesTransfer(); 859 registerKernelWakelock(); 860 registerCpuTimePerClusterFreq(); 861 registerCpuTimePerUid(); 862 registerCpuCyclesPerUidCluster(); 863 registerCpuTimePerUidFreq(); 864 registerCpuCyclesPerThreadGroupCluster(); 865 registerCpuActiveTime(); 866 registerCpuClusterTime(); 867 registerWifiActivityInfo(); 868 registerModemActivityInfo(); 869 registerBluetoothActivityInfo(); 870 registerSystemElapsedRealtime(); 871 registerSystemUptime(); 872 registerProcessMemoryState(); 873 registerProcessMemoryHighWaterMark(); 874 registerProcessMemorySnapshot(); 875 registerSystemIonHeapSize(); 876 registerIonHeapSize(); 877 registerProcessSystemIonHeapSize(); 878 registerSystemMemory(); 879 registerProcessDmabufMemory(); 880 registerVmStat(); 881 registerTemperature(); 882 registerCoolingDevice(); 883 registerBinderCallsStats(); 884 registerBinderCallsStatsExceptions(); 885 registerLooperStats(); 886 registerDiskStats(); 887 registerDirectoryUsage(); 888 registerAppSize(); 889 registerCategorySize(); 890 registerNumFingerprintsEnrolled(); 891 registerNumFacesEnrolled(); 892 registerProcStats(); 893 registerProcStatsPkgProc(); 894 registerDiskIO(); 895 registerPowerProfile(); 896 registerProcessCpuTime(); 897 registerCpuTimePerThreadFreq(); 898 registerDeviceCalculatedPowerUse(); 899 registerDeviceCalculatedPowerBlameUid(); 900 registerDeviceCalculatedPowerBlameOther(); 901 registerDebugElapsedClock(); 902 registerDebugFailingElapsedClock(); 903 registerBuildInformation(); 904 registerRoleHolder(); 905 registerTimeZoneDataInfo(); 906 registerTimeZoneDetectorState(); 907 registerExternalStorageInfo(); 908 registerAppsOnExternalStorageInfo(); 909 registerFaceSettings(); 910 registerAppOps(); 911 registerAttributedAppOps(); 912 registerRuntimeAppOpAccessMessage(); 913 registerNotificationRemoteViews(); 914 registerDangerousPermissionState(); 915 registerDangerousPermissionStateSampled(); 916 registerBatteryLevel(); 917 registerRemainingBatteryCapacity(); 918 registerFullBatteryCapacity(); 919 registerBatteryVoltage(); 920 registerBatteryCycleCount(); 921 registerSettingsStats(); 922 registerInstalledIncrementalPackages(); 923 registerKeystoreStorageStats(); 924 registerRkpPoolStats(); 925 registerKeystoreKeyCreationWithGeneralInfo(); 926 registerKeystoreKeyCreationWithAuthInfo(); 927 registerKeystoreKeyCreationWithPurposeModesInfo(); 928 registerKeystoreAtomWithOverflow(); 929 registerKeystoreKeyOperationWithPurposeAndModesInfo(); 930 registerKeystoreKeyOperationWithGeneralInfo(); 931 registerRkpErrorStats(); 932 registerKeystoreCrashStats(); 933 } 934 initAndRegisterNetworkStatsPullers()935 private void initAndRegisterNetworkStatsPullers() { 936 if (DEBUG) { 937 Slog.d(TAG, "Registering NetworkStats pullers with statsd"); 938 } 939 // Initialize NetworkStats baselines. 940 mNetworkStatsBaselines.addAll( 941 collectNetworkStatsSnapshotForAtom(FrameworkStatsLog.WIFI_BYTES_TRANSFER)); 942 mNetworkStatsBaselines.addAll( 943 collectNetworkStatsSnapshotForAtom(FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG)); 944 mNetworkStatsBaselines.addAll( 945 collectNetworkStatsSnapshotForAtom(FrameworkStatsLog.MOBILE_BYTES_TRANSFER)); 946 mNetworkStatsBaselines.addAll(collectNetworkStatsSnapshotForAtom( 947 FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG)); 948 mNetworkStatsBaselines.addAll(collectNetworkStatsSnapshotForAtom( 949 FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED)); 950 mNetworkStatsBaselines.addAll( 951 collectNetworkStatsSnapshotForAtom(FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER)); 952 mNetworkStatsBaselines.addAll( 953 collectNetworkStatsSnapshotForAtom(FrameworkStatsLog.OEM_MANAGED_BYTES_TRANSFER)); 954 955 // Listen to subscription changes to record historical subscriptions that activated before 956 // pulling, this is used by {@code DATA_USAGE_BYTES_TRANSFER}. 957 mSubscriptionManager.addOnSubscriptionsChangedListener( 958 BackgroundThread.getExecutor(), mStatsSubscriptionsListener); 959 960 registerWifiBytesTransfer(); 961 registerWifiBytesTransferBackground(); 962 registerMobileBytesTransfer(); 963 registerMobileBytesTransferBackground(); 964 registerBytesTransferByTagAndMetered(); 965 registerDataUsageBytesTransfer(); 966 registerOemManagedBytesTransfer(); 967 } 968 969 /** 970 * Return the {@code INetworkStatsSession} object that holds the necessary properties needed 971 * for the subsequent queries to {@link com.android.server.net.NetworkStatsService}. Or 972 * null if the service or binder cannot be obtained. Calling this method will trigger poll 973 * in NetworkStatsService with once per 15 seconds rate-limit, unless {@code bypassRateLimit} 974 * is set to true. This is needed in {@link #getUidNetworkStatsSnapshotForTemplate}, where 975 * bypassing the limit is necessary for perfd to supply realtime stats to developers looking at 976 * the network usage of their app. 977 */ 978 @Nullable getNetworkStatsSession(boolean bypassRateLimit)979 private INetworkStatsSession getNetworkStatsSession(boolean bypassRateLimit) { 980 final INetworkStatsService networkStatsService = 981 INetworkStatsService.Stub.asInterface( 982 ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); 983 if (networkStatsService == null) return null; 984 985 try { 986 return networkStatsService.openSessionForUsageStats( 987 FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN | (bypassRateLimit ? FLAG_POLL_FORCE 988 : FLAG_POLL_ON_OPEN), mContext.getOpPackageName()); 989 } catch (RemoteException e) { 990 Slog.e(TAG, "Cannot get NetworkStats session", e); 991 return null; 992 } 993 } 994 getIThermalService()995 private IThermalService getIThermalService() { 996 synchronized (mThermalLock) { 997 if (mThermalService == null) { 998 mThermalService = IThermalService.Stub.asInterface( 999 ServiceManager.getService(Context.THERMAL_SERVICE)); 1000 if (mThermalService != null) { 1001 try { 1002 mThermalService.asBinder().linkToDeath(() -> { 1003 synchronized (mThermalLock) { 1004 mThermalService = null; 1005 } 1006 }, /* flags */ 0); 1007 } catch (RemoteException e) { 1008 Slog.e(TAG, "linkToDeath with thermalService failed", e); 1009 mThermalService = null; 1010 } 1011 } 1012 } 1013 return mThermalService; 1014 } 1015 } 1016 getIKeystoreMetricsService()1017 private IKeystoreMetrics getIKeystoreMetricsService() { 1018 synchronized (mKeystoreLock) { 1019 if (mIKeystoreMetrics == null) { 1020 mIKeystoreMetrics = IKeystoreMetrics.Stub.asInterface( 1021 ServiceManager.getService("android.security.metrics")); 1022 if (mIKeystoreMetrics != null) { 1023 try { 1024 mIKeystoreMetrics.asBinder().linkToDeath(() -> { 1025 synchronized (mKeystoreLock) { 1026 mIKeystoreMetrics = null; 1027 } 1028 }, /* flags */ 0); 1029 } catch (RemoteException e) { 1030 Slog.e(TAG, "linkToDeath with IKeystoreMetrics failed", e); 1031 mIKeystoreMetrics = null; 1032 } 1033 } 1034 } 1035 return mIKeystoreMetrics; 1036 } 1037 } 1038 getIStoragedService()1039 private IStoraged getIStoragedService() { 1040 synchronized (mStoragedLock) { 1041 if (mStorageService == null) { 1042 mStorageService = IStoraged.Stub.asInterface( 1043 ServiceManager.getService("storaged")); 1044 } 1045 if (mStorageService != null) { 1046 try { 1047 mStorageService.asBinder().linkToDeath(() -> { 1048 synchronized (mStoragedLock) { 1049 mStorageService = null; 1050 } 1051 }, /* flags */ 0); 1052 } catch (RemoteException e) { 1053 Slog.e(TAG, "linkToDeath with storagedService failed", e); 1054 mStorageService = null; 1055 } 1056 } 1057 } 1058 return mStorageService; 1059 } 1060 getINotificationManagerService()1061 private INotificationManager getINotificationManagerService() { 1062 synchronized (mNotificationStatsLock) { 1063 if (mNotificationManagerService == null) { 1064 mNotificationManagerService = INotificationManager.Stub.asInterface( 1065 ServiceManager.getService(Context.NOTIFICATION_SERVICE)); 1066 } 1067 if (mNotificationManagerService != null) { 1068 try { 1069 mNotificationManagerService.asBinder().linkToDeath(() -> { 1070 synchronized (mNotificationStatsLock) { 1071 mNotificationManagerService = null; 1072 } 1073 }, /* flags */ 0); 1074 } catch (RemoteException e) { 1075 Slog.e(TAG, "linkToDeath with notificationManager failed", e); 1076 mNotificationManagerService = null; 1077 } 1078 } 1079 } 1080 return mNotificationManagerService; 1081 } 1082 getIProcessStatsService()1083 private IProcessStats getIProcessStatsService() { 1084 synchronized (mProcStatsLock) { 1085 if (mProcessStatsService == null) { 1086 mProcessStatsService = IProcessStats.Stub.asInterface( 1087 ServiceManager.getService(ProcessStats.SERVICE_NAME)); 1088 } 1089 if (mProcessStatsService != null) { 1090 try { 1091 mProcessStatsService.asBinder().linkToDeath(() -> { 1092 synchronized (mProcStatsLock) { 1093 mProcessStatsService = null; 1094 } 1095 }, /* flags */ 0); 1096 } catch (RemoteException e) { 1097 Slog.e(TAG, "linkToDeath with ProcessStats failed", e); 1098 mProcessStatsService = null; 1099 } 1100 } 1101 } 1102 return mProcessStatsService; 1103 } 1104 registerWifiBytesTransfer()1105 private void registerWifiBytesTransfer() { 1106 int tagId = FrameworkStatsLog.WIFI_BYTES_TRANSFER; 1107 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 1108 .setAdditiveFields(new int[] {2, 3, 4, 5}) 1109 .build(); 1110 mStatsManager.setPullAtomCallback( 1111 tagId, 1112 metadata, 1113 DIRECT_EXECUTOR, 1114 mStatsCallbackImpl 1115 ); 1116 } 1117 1118 @NonNull collectNetworkStatsSnapshotForAtom(int atomTag)1119 private List<NetworkStatsExt> collectNetworkStatsSnapshotForAtom(int atomTag) { 1120 List<NetworkStatsExt> ret = new ArrayList<>(); 1121 switch(atomTag) { 1122 case FrameworkStatsLog.WIFI_BYTES_TRANSFER: { 1123 final NetworkStats stats = getUidNetworkStatsSnapshotForTransport(TRANSPORT_WIFI); 1124 if (stats != null) { 1125 ret.add(new NetworkStatsExt(stats.groupedByUid(), new int[] {TRANSPORT_WIFI}, 1126 /*slicedByFgbg=*/false)); 1127 } 1128 break; 1129 } 1130 case FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG: { 1131 final NetworkStats stats = getUidNetworkStatsSnapshotForTransport(TRANSPORT_WIFI); 1132 if (stats != null) { 1133 ret.add(new NetworkStatsExt(sliceNetworkStatsByUidAndFgbg(stats), 1134 new int[] {TRANSPORT_WIFI}, /*slicedByFgbg=*/true)); 1135 } 1136 break; 1137 } 1138 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER: { 1139 final NetworkStats stats = 1140 getUidNetworkStatsSnapshotForTransport(TRANSPORT_CELLULAR); 1141 if (stats != null) { 1142 ret.add(new NetworkStatsExt(stats.groupedByUid(), 1143 new int[] {TRANSPORT_CELLULAR}, /*slicedByFgbg=*/false)); 1144 } 1145 break; 1146 } 1147 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG: { 1148 final NetworkStats stats = 1149 getUidNetworkStatsSnapshotForTransport(TRANSPORT_CELLULAR); 1150 if (stats != null) { 1151 ret.add(new NetworkStatsExt(sliceNetworkStatsByUidAndFgbg(stats), 1152 new int[] {TRANSPORT_CELLULAR}, /*slicedByFgbg=*/true)); 1153 } 1154 break; 1155 } 1156 case FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED: { 1157 final NetworkStats wifiStats = getUidNetworkStatsSnapshotForTemplate( 1158 buildTemplateWifiWildcard(), /*includeTags=*/true); 1159 final NetworkStats cellularStats = getUidNetworkStatsSnapshotForTemplate( 1160 buildTemplateMobileWildcard(), /*includeTags=*/true); 1161 if (wifiStats != null && cellularStats != null) { 1162 final NetworkStats stats = wifiStats.add(cellularStats); 1163 ret.add(new NetworkStatsExt(sliceNetworkStatsByUidTagAndMetered(stats), 1164 new int[] {TRANSPORT_WIFI, TRANSPORT_CELLULAR}, 1165 /*slicedByFgbg=*/false, /*slicedByTag=*/true, 1166 /*slicedByMetered=*/true, TelephonyManager.NETWORK_TYPE_UNKNOWN, 1167 /*subInfo=*/null, OEM_MANAGED_ALL)); 1168 } 1169 break; 1170 } 1171 case FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER: { 1172 for (final SubInfo subInfo : mHistoricalSubs) { 1173 ret.addAll(getDataUsageBytesTransferSnapshotForSub(subInfo)); 1174 } 1175 break; 1176 } 1177 case FrameworkStatsLog.OEM_MANAGED_BYTES_TRANSFER: { 1178 ret.addAll(getDataUsageBytesTransferSnapshotForOemManaged()); 1179 break; 1180 } 1181 default: 1182 throw new IllegalArgumentException("Unknown atomTag " + atomTag); 1183 } 1184 return ret; 1185 } 1186 pullDataBytesTransferLocked(int atomTag, @NonNull List<StatsEvent> pulledData)1187 private int pullDataBytesTransferLocked(int atomTag, @NonNull List<StatsEvent> pulledData) { 1188 final List<NetworkStatsExt> current = collectNetworkStatsSnapshotForAtom(atomTag); 1189 1190 if (current == null) { 1191 Slog.e(TAG, "current snapshot is null for " + atomTag + ", return."); 1192 return StatsManager.PULL_SKIP; 1193 } 1194 1195 for (final NetworkStatsExt item : current) { 1196 final NetworkStatsExt baseline = CollectionUtils.find(mNetworkStatsBaselines, 1197 it -> it.hasSameSlicing(item)); 1198 1199 // No matched baseline indicates error has occurred during initialization stage, 1200 // skip reporting anything since the snapshot is invalid. 1201 if (baseline == null) { 1202 Slog.e(TAG, "baseline is null for " + atomTag + ", return."); 1203 return StatsManager.PULL_SKIP; 1204 } 1205 final NetworkStatsExt diff = new NetworkStatsExt( 1206 item.stats.subtract(baseline.stats).removeEmptyEntries(), item.transports, 1207 item.slicedByFgbg, item.slicedByTag, item.slicedByMetered, item.ratType, 1208 item.subInfo, item.oemManaged); 1209 1210 // If no diff, skip. 1211 if (diff.stats.size() == 0) continue; 1212 1213 switch (atomTag) { 1214 case FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED: 1215 addBytesTransferByTagAndMeteredAtoms(diff, pulledData); 1216 break; 1217 case FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER: 1218 addDataUsageBytesTransferAtoms(diff, pulledData); 1219 break; 1220 case FrameworkStatsLog.OEM_MANAGED_BYTES_TRANSFER: 1221 addOemDataUsageBytesTransferAtoms(diff, pulledData); 1222 break; 1223 default: 1224 addNetworkStats(atomTag, pulledData, diff); 1225 } 1226 } 1227 return StatsManager.PULL_SUCCESS; 1228 } 1229 addNetworkStats(int atomTag, @NonNull List<StatsEvent> ret, @NonNull NetworkStatsExt statsExt)1230 private void addNetworkStats(int atomTag, @NonNull List<StatsEvent> ret, 1231 @NonNull NetworkStatsExt statsExt) { 1232 int size = statsExt.stats.size(); 1233 final NetworkStats.Entry entry = new NetworkStats.Entry(); // For recycling 1234 for (int j = 0; j < size; j++) { 1235 statsExt.stats.getValues(j, entry); 1236 StatsEvent statsEvent; 1237 1238 if (statsExt.slicedByFgbg) { 1239 // MobileBytesTransferByFgBg atom or WifiBytesTransferByFgBg atom. 1240 statsEvent = FrameworkStatsLog.buildStatsEvent( 1241 atomTag, entry.uid, 1242 (entry.set > 0), entry.rxBytes, entry.rxPackets, entry.txBytes, 1243 entry.txPackets); 1244 } else { 1245 // MobileBytesTransfer atom or WifiBytesTransfer atom. 1246 statsEvent = FrameworkStatsLog.buildStatsEvent( 1247 atomTag, entry.uid, entry.rxBytes, 1248 entry.rxPackets, entry.txBytes, entry.txPackets); 1249 } 1250 ret.add(statsEvent); 1251 } 1252 } 1253 addBytesTransferByTagAndMeteredAtoms(@onNull NetworkStatsExt statsExt, @NonNull List<StatsEvent> pulledData)1254 private void addBytesTransferByTagAndMeteredAtoms(@NonNull NetworkStatsExt statsExt, 1255 @NonNull List<StatsEvent> pulledData) { 1256 final NetworkStats.Entry entry = new NetworkStats.Entry(); // for recycling 1257 for (int i = 0; i < statsExt.stats.size(); i++) { 1258 statsExt.stats.getValues(i, entry); 1259 pulledData.add(FrameworkStatsLog.buildStatsEvent( 1260 FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED, entry.uid, 1261 entry.metered == NetworkStats.METERED_YES, entry.tag, entry.rxBytes, 1262 entry.rxPackets, entry.txBytes, entry.txPackets)); 1263 } 1264 } 1265 addDataUsageBytesTransferAtoms(@onNull NetworkStatsExt statsExt, @NonNull List<StatsEvent> pulledData)1266 private void addDataUsageBytesTransferAtoms(@NonNull NetworkStatsExt statsExt, 1267 @NonNull List<StatsEvent> pulledData) { 1268 1269 // Workaround for 5G NSA mode, see {@link NetworkTemplate#NETWORK_TYPE_5G_NSA}. 1270 // 5G NSA mode means the primary cell is LTE with a secondary connection to an 1271 // NR cell. To mitigate risk, NetworkStats is currently storing this state as 1272 // a fake RAT type rather than storing the boolean separately. 1273 final boolean is5GNsa = statsExt.ratType == NetworkTemplate.NETWORK_TYPE_5G_NSA; 1274 // Report NR connected in 5G non-standalone mode, or if the RAT type is NR to begin with. 1275 final boolean isNR = is5GNsa || statsExt.ratType == TelephonyManager.NETWORK_TYPE_NR; 1276 1277 final NetworkStats.Entry entry = new NetworkStats.Entry(); // for recycling 1278 for (int i = 0; i < statsExt.stats.size(); i++) { 1279 statsExt.stats.getValues(i, entry); 1280 pulledData.add(FrameworkStatsLog.buildStatsEvent( 1281 FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER, entry.set, entry.rxBytes, 1282 entry.rxPackets, entry.txBytes, entry.txPackets, 1283 is5GNsa ? TelephonyManager.NETWORK_TYPE_LTE : statsExt.ratType, 1284 // Fill information about subscription, these cannot be null since invalid data 1285 // would be filtered when adding into subInfo list. 1286 statsExt.subInfo.mcc, statsExt.subInfo.mnc, statsExt.subInfo.carrierId, 1287 statsExt.subInfo.isOpportunistic 1288 ? DATA_USAGE_BYTES_TRANSFER__OPPORTUNISTIC_DATA_SUB__OPPORTUNISTIC 1289 : DATA_USAGE_BYTES_TRANSFER__OPPORTUNISTIC_DATA_SUB__NOT_OPPORTUNISTIC, 1290 isNR)); 1291 } 1292 } 1293 addOemDataUsageBytesTransferAtoms(@onNull NetworkStatsExt statsExt, @NonNull List<StatsEvent> pulledData)1294 private void addOemDataUsageBytesTransferAtoms(@NonNull NetworkStatsExt statsExt, 1295 @NonNull List<StatsEvent> pulledData) { 1296 final NetworkStats.Entry entry = new NetworkStats.Entry(); // for recycling 1297 final int oemManaged = statsExt.oemManaged; 1298 for (final int transport : statsExt.transports) { 1299 for (int i = 0; i < statsExt.stats.size(); i++) { 1300 statsExt.stats.getValues(i, entry); 1301 pulledData.add(FrameworkStatsLog.buildStatsEvent( 1302 FrameworkStatsLog.OEM_MANAGED_BYTES_TRANSFER, entry.uid, (entry.set > 0), 1303 oemManaged, transport, entry.rxBytes, entry.rxPackets, entry.txBytes, 1304 entry.txPackets)); 1305 } 1306 } 1307 } 1308 getDataUsageBytesTransferSnapshotForOemManaged()1309 @NonNull private List<NetworkStatsExt> getDataUsageBytesTransferSnapshotForOemManaged() { 1310 final int[] transports = new int[] {MATCH_ETHERNET, MATCH_MOBILE_WILDCARD, 1311 MATCH_WIFI_WILDCARD}; 1312 final int[] oemManagedTypes = new int[] {OEM_PAID | OEM_PRIVATE, OEM_PAID, OEM_PRIVATE}; 1313 1314 final List<NetworkStatsExt> ret = new ArrayList<>(); 1315 1316 for (final int transport : transports) { 1317 for (final int oemManaged : oemManagedTypes) { 1318 /* A null subscriberId will set wildcard=true, since we aren't trying to select a 1319 specific ssid or subscriber. */ 1320 final NetworkTemplate template = new NetworkTemplate(transport, 1321 /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null, 1322 METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, 1323 oemManaged); 1324 final NetworkStats stats = getUidNetworkStatsSnapshotForTemplate(template, true); 1325 if (stats != null) { 1326 ret.add(new NetworkStatsExt(sliceNetworkStatsByUidTagAndMetered(stats), 1327 new int[] {transport}, /*slicedByFgbg=*/true, /*slicedByTag=*/true, 1328 /*slicedByMetered=*/true, TelephonyManager.NETWORK_TYPE_UNKNOWN, 1329 /*subInfo=*/null, oemManaged)); 1330 } 1331 } 1332 } 1333 1334 return ret; 1335 } 1336 1337 /** 1338 * Create a snapshot of NetworkStats for a given transport. 1339 */ getUidNetworkStatsSnapshotForTransport(int transport)1340 @Nullable private NetworkStats getUidNetworkStatsSnapshotForTransport(int transport) { 1341 final NetworkTemplate template = (transport == TRANSPORT_CELLULAR) 1342 ? NetworkTemplate.buildTemplateMobileWithRatType( 1343 /*subscriptionId=*/null, NETWORK_TYPE_ALL) 1344 : NetworkTemplate.buildTemplateWifiWildcard(); 1345 return getUidNetworkStatsSnapshotForTemplate(template, /*includeTags=*/false); 1346 } 1347 1348 /** 1349 * Create a snapshot of NetworkStats since boot for the given template, but add 1 bucket 1350 * duration before boot as a buffer to ensure at least one full bucket will be included. 1351 * Note that this should be only used to calculate diff since the snapshot might contains 1352 * some traffic before boot. 1353 */ getUidNetworkStatsSnapshotForTemplate( @onNull NetworkTemplate template, boolean includeTags)1354 @Nullable private NetworkStats getUidNetworkStatsSnapshotForTemplate( 1355 @NonNull NetworkTemplate template, boolean includeTags) { 1356 final long elapsedMillisSinceBoot = SystemClock.elapsedRealtime(); 1357 final long currentTimeInMillis = MICROSECONDS.toMillis(SystemClock.currentTimeMicro()); 1358 final long bucketDuration = Settings.Global.getLong(mContext.getContentResolver(), 1359 NETSTATS_UID_BUCKET_DURATION, NETSTATS_UID_DEFAULT_BUCKET_DURATION_MS); 1360 try { 1361 // TODO (b/156313635): This is short-term hack to allow perfd gets updated networkStats 1362 // history when query in every second in order to show realtime statistics. However, 1363 // this is not a good long-term solution since NetworkStatsService will make frequent 1364 // I/O and also block main thread when polling. 1365 // Consider making perfd queries NetworkStatsService directly. 1366 final NetworkStats stats = getNetworkStatsSession(template.getMatchRule() 1367 == NetworkTemplate.MATCH_WIFI_WILDCARD).getSummaryForAllUid(template, 1368 currentTimeInMillis - elapsedMillisSinceBoot - bucketDuration, 1369 currentTimeInMillis, includeTags); 1370 return stats; 1371 } catch (RemoteException | NullPointerException e) { 1372 Slog.e(TAG, "Pulling netstats for template=" + template + " and includeTags=" 1373 + includeTags + " causes error", e); 1374 } 1375 return null; 1376 } 1377 getDataUsageBytesTransferSnapshotForSub( @onNull SubInfo subInfo)1378 @NonNull private List<NetworkStatsExt> getDataUsageBytesTransferSnapshotForSub( 1379 @NonNull SubInfo subInfo) { 1380 final List<NetworkStatsExt> ret = new ArrayList<>(); 1381 for (final int ratType : getAllCollapsedRatTypes()) { 1382 final NetworkTemplate template = 1383 buildTemplateMobileWithRatType(subInfo.subscriberId, ratType); 1384 final NetworkStats stats = 1385 getUidNetworkStatsSnapshotForTemplate(template, /*includeTags=*/false); 1386 if (stats != null) { 1387 ret.add(new NetworkStatsExt(sliceNetworkStatsByFgbg(stats), 1388 new int[] {TRANSPORT_CELLULAR}, /*slicedByFgbg=*/true, 1389 /*slicedByTag=*/false, /*slicedByMetered=*/false, ratType, subInfo, 1390 OEM_MANAGED_ALL)); 1391 } 1392 } 1393 return ret; 1394 } 1395 sliceNetworkStatsByFgbg(@onNull NetworkStats stats)1396 @NonNull private NetworkStats sliceNetworkStatsByFgbg(@NonNull NetworkStats stats) { 1397 return sliceNetworkStats(stats, 1398 (newEntry, oldEntry) -> { 1399 newEntry.set = oldEntry.set; 1400 }); 1401 } 1402 sliceNetworkStatsByUidAndFgbg(@onNull NetworkStats stats)1403 @NonNull private NetworkStats sliceNetworkStatsByUidAndFgbg(@NonNull NetworkStats stats) { 1404 return sliceNetworkStats(stats, 1405 (newEntry, oldEntry) -> { 1406 newEntry.uid = oldEntry.uid; 1407 newEntry.set = oldEntry.set; 1408 }); 1409 } 1410 1411 @NonNull private NetworkStats sliceNetworkStatsByUidTagAndMetered(@NonNull NetworkStats stats) { 1412 return sliceNetworkStats(stats, 1413 (newEntry, oldEntry) -> { 1414 newEntry.uid = oldEntry.uid; 1415 newEntry.tag = oldEntry.tag; 1416 newEntry.metered = oldEntry.metered; 1417 }); 1418 } 1419 1420 /** 1421 * Slices NetworkStats along the dimensions specified in the slicer lambda and aggregates over 1422 * non-sliced dimensions. 1423 * 1424 * This function iterates through each NetworkStats.Entry, sets its dimensions equal to the 1425 * default state (with the presumption that we don't want to slice on anything), and then 1426 * applies the slicer lambda to allow users to control which dimensions to slice on. This is 1427 * adapted from groupedByUid within NetworkStats.java 1428 * 1429 * @param slicer An operation taking into two parameters, new NetworkStats.Entry and old 1430 * NetworkStats.Entry, that should be used to copy state from the old to the new. 1431 * This is useful for slicing by particular dimensions. For example, if we wished 1432 * to slice by uid and tag, we could write the following lambda: 1433 * (new, old) -> { 1434 * new.uid = old.uid; 1435 * new.tag = old.tag; 1436 * } 1437 * If no slicer is provided, the data is not sliced by any dimensions. 1438 * @return new NeworkStats object appropriately sliced 1439 */ 1440 @NonNull private NetworkStats sliceNetworkStats(@NonNull NetworkStats stats, 1441 @Nullable BiConsumer<NetworkStats.Entry, NetworkStats.Entry> slicer) { 1442 final NetworkStats ret = new NetworkStats(stats.getElapsedRealtime(), 1); 1443 1444 final NetworkStats.Entry entry = new NetworkStats.Entry(); 1445 entry.uid = NetworkStats.UID_ALL; 1446 entry.iface = NetworkStats.IFACE_ALL; 1447 entry.set = NetworkStats.SET_ALL; 1448 entry.tag = NetworkStats.TAG_NONE; 1449 entry.metered = NetworkStats.METERED_ALL; 1450 entry.roaming = NetworkStats.ROAMING_ALL; 1451 entry.defaultNetwork = NetworkStats.DEFAULT_NETWORK_ALL; 1452 1453 final NetworkStats.Entry recycle = new NetworkStats.Entry(); // used for retrieving values 1454 for (int i = 0; i < stats.size(); i++) { 1455 stats.getValues(i, recycle); 1456 if (slicer != null) { 1457 slicer.accept(entry, recycle); 1458 } 1459 1460 entry.rxBytes = recycle.rxBytes; 1461 entry.rxPackets = recycle.rxPackets; 1462 entry.txBytes = recycle.txBytes; 1463 entry.txPackets = recycle.txPackets; 1464 // Operations purposefully omitted since we don't use them for statsd. 1465 ret.combineValues(entry); 1466 } 1467 return ret; 1468 } 1469 1470 private void registerWifiBytesTransferBackground() { 1471 int tagId = FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG; 1472 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 1473 .setAdditiveFields(new int[] {3, 4, 5, 6}) 1474 .build(); 1475 mStatsManager.setPullAtomCallback( 1476 tagId, 1477 metadata, 1478 DIRECT_EXECUTOR, 1479 mStatsCallbackImpl 1480 ); 1481 } 1482 1483 private void registerMobileBytesTransfer() { 1484 int tagId = FrameworkStatsLog.MOBILE_BYTES_TRANSFER; 1485 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 1486 .setAdditiveFields(new int[] {2, 3, 4, 5}) 1487 .build(); 1488 mStatsManager.setPullAtomCallback( 1489 tagId, 1490 metadata, 1491 DIRECT_EXECUTOR, 1492 mStatsCallbackImpl 1493 ); 1494 } 1495 1496 private void registerMobileBytesTransferBackground() { 1497 int tagId = FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG; 1498 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 1499 .setAdditiveFields(new int[] {3, 4, 5, 6}) 1500 .build(); 1501 mStatsManager.setPullAtomCallback( 1502 tagId, 1503 metadata, 1504 DIRECT_EXECUTOR, 1505 mStatsCallbackImpl 1506 ); 1507 } 1508 1509 private void registerBytesTransferByTagAndMetered() { 1510 int tagId = FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED; 1511 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 1512 .setAdditiveFields(new int[] {4, 5, 6, 7}) 1513 .build(); 1514 mStatsManager.setPullAtomCallback( 1515 tagId, 1516 metadata, 1517 BackgroundThread.getExecutor(), 1518 mStatsCallbackImpl 1519 ); 1520 } 1521 1522 private void registerDataUsageBytesTransfer() { 1523 int tagId = FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER; 1524 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 1525 .setAdditiveFields(new int[] {2, 3, 4, 5}) 1526 .build(); 1527 mStatsManager.setPullAtomCallback( 1528 tagId, 1529 metadata, 1530 BackgroundThread.getExecutor(), 1531 mStatsCallbackImpl 1532 ); 1533 } 1534 1535 private void registerOemManagedBytesTransfer() { 1536 int tagId = FrameworkStatsLog.OEM_MANAGED_BYTES_TRANSFER; 1537 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 1538 .setAdditiveFields(new int[] {5, 6, 7, 8}) 1539 .build(); 1540 mStatsManager.setPullAtomCallback( 1541 tagId, 1542 metadata, 1543 BackgroundThread.getExecutor(), 1544 mStatsCallbackImpl 1545 ); 1546 } 1547 1548 private void registerBluetoothBytesTransfer() { 1549 int tagId = FrameworkStatsLog.BLUETOOTH_BYTES_TRANSFER; 1550 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 1551 .setAdditiveFields(new int[] {2, 3}) 1552 .build(); 1553 mStatsManager.setPullAtomCallback( 1554 tagId, 1555 metadata, 1556 DIRECT_EXECUTOR, 1557 mStatsCallbackImpl 1558 ); 1559 } 1560 1561 /** 1562 * Helper method to extract the Parcelable controller info from a 1563 * SynchronousResultReceiver. 1564 */ 1565 private static <T extends Parcelable> T awaitControllerInfo( 1566 @Nullable SynchronousResultReceiver receiver) { 1567 if (receiver == null) { 1568 return null; 1569 } 1570 1571 try { 1572 final SynchronousResultReceiver.Result result = 1573 receiver.awaitResult(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS); 1574 if (result.bundle != null) { 1575 // This is the final destination for the Bundle. 1576 result.bundle.setDefusable(true); 1577 1578 final T data = result.bundle.getParcelable(RESULT_RECEIVER_CONTROLLER_KEY); 1579 if (data != null) { 1580 return data; 1581 } 1582 } 1583 } catch (TimeoutException e) { 1584 Slog.w(TAG, "timeout reading " + receiver.getName() + " stats"); 1585 } 1586 return null; 1587 } 1588 1589 private BluetoothActivityEnergyInfo fetchBluetoothData() { 1590 final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 1591 if (adapter != null) { 1592 SynchronousResultReceiver bluetoothReceiver = 1593 new SynchronousResultReceiver("bluetooth"); 1594 adapter.requestControllerActivityEnergyInfo(bluetoothReceiver); 1595 return awaitControllerInfo(bluetoothReceiver); 1596 } else { 1597 Slog.e(TAG, "Failed to get bluetooth adapter!"); 1598 return null; 1599 } 1600 } 1601 1602 int pullBluetoothBytesTransferLocked(int atomTag, List<StatsEvent> pulledData) { 1603 BluetoothActivityEnergyInfo info = fetchBluetoothData(); 1604 if (info == null || info.getUidTraffic() == null) { 1605 return StatsManager.PULL_SKIP; 1606 } 1607 for (UidTraffic traffic : info.getUidTraffic()) { 1608 pulledData.add(FrameworkStatsLog.buildStatsEvent( 1609 atomTag, traffic.getUid(), traffic.getRxBytes(), traffic.getTxBytes())); 1610 } 1611 return StatsManager.PULL_SUCCESS; 1612 } 1613 1614 private void registerKernelWakelock() { 1615 int tagId = FrameworkStatsLog.KERNEL_WAKELOCK; 1616 mStatsManager.setPullAtomCallback( 1617 tagId, 1618 /* PullAtomMetadata */ null, 1619 DIRECT_EXECUTOR, 1620 mStatsCallbackImpl 1621 ); 1622 } 1623 1624 int pullKernelWakelockLocked(int atomTag, List<StatsEvent> pulledData) { 1625 final KernelWakelockStats wakelockStats = 1626 mKernelWakelockReader.readKernelWakelockStats(mTmpWakelockStats); 1627 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) { 1628 String name = ent.getKey(); 1629 KernelWakelockStats.Entry kws = ent.getValue(); 1630 pulledData.add(FrameworkStatsLog.buildStatsEvent( 1631 atomTag, name, kws.mCount, kws.mVersion, kws.mTotalTime)); 1632 } 1633 return StatsManager.PULL_SUCCESS; 1634 } 1635 1636 private void registerCpuTimePerClusterFreq() { 1637 if (KernelCpuBpfTracking.isSupported()) { 1638 int tagId = FrameworkStatsLog.CPU_TIME_PER_CLUSTER_FREQ; 1639 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 1640 .setAdditiveFields(new int[] {3}) 1641 .build(); 1642 mStatsManager.setPullAtomCallback( 1643 tagId, 1644 metadata, 1645 DIRECT_EXECUTOR, 1646 mStatsCallbackImpl 1647 ); 1648 } 1649 } 1650 1651 int pullCpuTimePerClusterFreqLocked(int atomTag, List<StatsEvent> pulledData) { 1652 int[] freqsClusters = KernelCpuBpfTracking.getFreqsClusters(); 1653 long[] freqs = KernelCpuBpfTracking.getFreqs(); 1654 long[] timesMs = KernelCpuTotalBpfMapReader.read(); 1655 if (timesMs == null) { 1656 return StatsManager.PULL_SKIP; 1657 } 1658 for (int freqIndex = 0; freqIndex < timesMs.length; ++freqIndex) { 1659 int cluster = freqsClusters[freqIndex]; 1660 int freq = (int) freqs[freqIndex]; 1661 long timeMs = timesMs[freqIndex]; 1662 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, cluster, freq, timeMs)); 1663 } 1664 return StatsManager.PULL_SUCCESS; 1665 } 1666 1667 private void registerCpuTimePerUid() { 1668 int tagId = FrameworkStatsLog.CPU_TIME_PER_UID; 1669 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 1670 .setAdditiveFields(new int[] {2, 3}) 1671 .build(); 1672 mStatsManager.setPullAtomCallback( 1673 tagId, 1674 metadata, 1675 DIRECT_EXECUTOR, 1676 mStatsCallbackImpl 1677 ); 1678 } 1679 1680 int pullCpuTimePerUidLocked(int atomTag, List<StatsEvent> pulledData) { 1681 mCpuUidUserSysTimeReader.readAbsolute((uid, timesUs) -> { 1682 long userTimeUs = timesUs[0], systemTimeUs = timesUs[1]; 1683 pulledData.add( 1684 FrameworkStatsLog.buildStatsEvent(atomTag, uid, userTimeUs, systemTimeUs)); 1685 }); 1686 return StatsManager.PULL_SUCCESS; 1687 } 1688 1689 private void registerCpuCyclesPerUidCluster() { 1690 // If eBPF tracking is not support, the procfs fallback is used if the kernel knows about 1691 // CPU frequencies. 1692 if (KernelCpuBpfTracking.isSupported() || KernelCpuBpfTracking.getClusters() > 0) { 1693 int tagId = FrameworkStatsLog.CPU_CYCLES_PER_UID_CLUSTER; 1694 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 1695 .setAdditiveFields(new int[] {3, 4, 5}) 1696 .build(); 1697 mStatsManager.setPullAtomCallback( 1698 tagId, 1699 metadata, 1700 DIRECT_EXECUTOR, 1701 mStatsCallbackImpl 1702 ); 1703 } 1704 } 1705 1706 int pullCpuCyclesPerUidClusterLocked(int atomTag, List<StatsEvent> pulledData) { 1707 PowerProfile powerProfile = new PowerProfile(mContext); 1708 int[] freqsClusters = KernelCpuBpfTracking.getFreqsClusters(); 1709 int clusters = KernelCpuBpfTracking.getClusters(); 1710 long[] freqs = KernelCpuBpfTracking.getFreqs(); 1711 double[] freqsPowers = new double[freqs.length]; 1712 // Initialize frequency power mapping. 1713 { 1714 int freqClusterIndex = 0; 1715 int lastCluster = -1; 1716 for (int freqIndex = 0; freqIndex < freqs.length; ++freqIndex, ++freqClusterIndex) { 1717 int cluster = freqsClusters[freqIndex]; 1718 if (cluster != lastCluster) { 1719 freqClusterIndex = 0; 1720 } 1721 lastCluster = cluster; 1722 1723 freqsPowers[freqIndex] = 1724 powerProfile.getAveragePowerForCpuCore(cluster, freqClusterIndex); 1725 } 1726 } 1727 1728 // Aggregate 0: mcycles, 1: runtime ms, 2: power profile estimate for the same uids for 1729 // each cluster. 1730 SparseArray<double[]> aggregated = new SparseArray<>(); 1731 mCpuUidFreqTimeReader.readAbsolute((uid, cpuFreqTimeMs) -> { 1732 if (UserHandle.isIsolated(uid)) { 1733 // Skip individual isolated uids because they are recycled and quickly removed from 1734 // the underlying data source. 1735 return; 1736 } else if (UserHandle.isSharedAppGid(uid)) { 1737 // All shared app gids are accounted together. 1738 uid = LAST_SHARED_APPLICATION_GID; 1739 } else { 1740 // Everything else is accounted under their base uid. 1741 uid = UserHandle.getAppId(uid); 1742 } 1743 1744 double[] values = aggregated.get(uid); 1745 if (values == null) { 1746 values = new double[clusters * CPU_CYCLES_PER_UID_CLUSTER_VALUES]; 1747 aggregated.put(uid, values); 1748 } 1749 1750 for (int freqIndex = 0; freqIndex < cpuFreqTimeMs.length; ++freqIndex) { 1751 int cluster = freqsClusters[freqIndex]; 1752 long timeMs = cpuFreqTimeMs[freqIndex]; 1753 values[cluster * CPU_CYCLES_PER_UID_CLUSTER_VALUES] += freqs[freqIndex] * timeMs; 1754 values[cluster * CPU_CYCLES_PER_UID_CLUSTER_VALUES + 1] += timeMs; 1755 values[cluster * CPU_CYCLES_PER_UID_CLUSTER_VALUES + 2] += 1756 freqsPowers[freqIndex] * timeMs; 1757 } 1758 }); 1759 1760 int size = aggregated.size(); 1761 for (int i = 0; i < size; ++i) { 1762 int uid = aggregated.keyAt(i); 1763 double[] values = aggregated.valueAt(i); 1764 for (int cluster = 0; cluster < clusters; ++cluster) { 1765 pulledData.add(FrameworkStatsLog.buildStatsEvent( 1766 atomTag, uid, cluster, 1767 (long) (values[cluster * CPU_CYCLES_PER_UID_CLUSTER_VALUES] / 1e6), 1768 (long) values[cluster * CPU_CYCLES_PER_UID_CLUSTER_VALUES + 1], 1769 (long) (values[cluster * CPU_CYCLES_PER_UID_CLUSTER_VALUES + 2] / 1e3))); 1770 } 1771 } 1772 return StatsManager.PULL_SUCCESS; 1773 } 1774 1775 private void registerCpuTimePerUidFreq() { 1776 // the throttling is 3sec, handled in 1777 // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader 1778 int tagId = FrameworkStatsLog.CPU_TIME_PER_UID_FREQ; 1779 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 1780 .setAdditiveFields(new int[] {3}) 1781 .build(); 1782 mStatsManager.setPullAtomCallback( 1783 tagId, 1784 metadata, 1785 DIRECT_EXECUTOR, 1786 mStatsCallbackImpl 1787 ); 1788 } 1789 1790 int pullCpuTimePerUidFreqLocked(int atomTag, List<StatsEvent> pulledData) { 1791 // Aggregate times for the same uids. 1792 SparseArray<long[]> aggregated = new SparseArray<>(); 1793 mCpuUidFreqTimeReader.readAbsolute((uid, cpuFreqTimeMs) -> { 1794 if (UserHandle.isIsolated(uid)) { 1795 // Skip individual isolated uids because they are recycled and quickly removed from 1796 // the underlying data source. 1797 return; 1798 } else if (UserHandle.isSharedAppGid(uid)) { 1799 // All shared app gids are accounted together. 1800 uid = LAST_SHARED_APPLICATION_GID; 1801 } else { 1802 // Everything else is accounted under their base uid. 1803 uid = UserHandle.getAppId(uid); 1804 } 1805 1806 long[] aggCpuFreqTimeMs = aggregated.get(uid); 1807 if (aggCpuFreqTimeMs == null) { 1808 aggCpuFreqTimeMs = new long[cpuFreqTimeMs.length]; 1809 aggregated.put(uid, aggCpuFreqTimeMs); 1810 } 1811 for (int freqIndex = 0; freqIndex < cpuFreqTimeMs.length; ++freqIndex) { 1812 aggCpuFreqTimeMs[freqIndex] += cpuFreqTimeMs[freqIndex]; 1813 } 1814 }); 1815 1816 int size = aggregated.size(); 1817 for (int i = 0; i < size; ++i) { 1818 int uid = aggregated.keyAt(i); 1819 long[] aggCpuFreqTimeMs = aggregated.valueAt(i); 1820 for (int freqIndex = 0; freqIndex < aggCpuFreqTimeMs.length; ++freqIndex) { 1821 if (aggCpuFreqTimeMs[freqIndex] >= MIN_CPU_TIME_PER_UID_FREQ) { 1822 pulledData.add(FrameworkStatsLog.buildStatsEvent( 1823 atomTag, uid, freqIndex, aggCpuFreqTimeMs[freqIndex])); 1824 } 1825 } 1826 } 1827 return StatsManager.PULL_SUCCESS; 1828 } 1829 1830 private void registerCpuCyclesPerThreadGroupCluster() { 1831 if (KernelCpuBpfTracking.isSupported()) { 1832 int tagId = FrameworkStatsLog.CPU_CYCLES_PER_THREAD_GROUP_CLUSTER; 1833 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 1834 .setAdditiveFields(new int[] {3, 4}) 1835 .build(); 1836 mStatsManager.setPullAtomCallback( 1837 tagId, 1838 metadata, 1839 DIRECT_EXECUTOR, 1840 mStatsCallbackImpl 1841 ); 1842 } 1843 } 1844 1845 int pullCpuCyclesPerThreadGroupCluster(int atomTag, List<StatsEvent> pulledData) { 1846 SystemServiceCpuThreadTimes times = LocalServices.getService(BatteryStatsInternal.class) 1847 .getSystemServiceCpuThreadTimes(); 1848 if (times == null) { 1849 return StatsManager.PULL_SKIP; 1850 } 1851 1852 addCpuCyclesPerThreadGroupClusterAtoms(atomTag, pulledData, 1853 FrameworkStatsLog.CPU_CYCLES_PER_THREAD_GROUP_CLUSTER__THREAD_GROUP__SYSTEM_SERVER, 1854 times.threadCpuTimesUs); 1855 addCpuCyclesPerThreadGroupClusterAtoms(atomTag, pulledData, 1856 FrameworkStatsLog.CPU_CYCLES_PER_THREAD_GROUP_CLUSTER__THREAD_GROUP__SYSTEM_SERVER_BINDER, 1857 times.binderThreadCpuTimesUs); 1858 1859 ProcessCpuUsage surfaceFlingerTimes = mSurfaceFlingerProcessCpuThreadReader.readAbsolute(); 1860 if (surfaceFlingerTimes != null && surfaceFlingerTimes.threadCpuTimesMillis != null) { 1861 long[] surfaceFlingerTimesUs = 1862 new long[surfaceFlingerTimes.threadCpuTimesMillis.length]; 1863 for (int i = 0; i < surfaceFlingerTimesUs.length; ++i) { 1864 surfaceFlingerTimesUs[i] = surfaceFlingerTimes.threadCpuTimesMillis[i] * 1_000; 1865 } 1866 addCpuCyclesPerThreadGroupClusterAtoms(atomTag, pulledData, 1867 FrameworkStatsLog.CPU_CYCLES_PER_THREAD_GROUP_CLUSTER__THREAD_GROUP__SURFACE_FLINGER, 1868 surfaceFlingerTimesUs); 1869 } 1870 1871 return StatsManager.PULL_SUCCESS; 1872 } 1873 1874 private static void addCpuCyclesPerThreadGroupClusterAtoms( 1875 int atomTag, List<StatsEvent> pulledData, int threadGroup, long[] cpuTimesUs) { 1876 int[] freqsClusters = KernelCpuBpfTracking.getFreqsClusters(); 1877 int clusters = KernelCpuBpfTracking.getClusters(); 1878 long[] freqs = KernelCpuBpfTracking.getFreqs(); 1879 long[] aggregatedCycles = new long[clusters]; 1880 long[] aggregatedTimesUs = new long[clusters]; 1881 for (int i = 0; i < cpuTimesUs.length; ++i) { 1882 aggregatedCycles[freqsClusters[i]] += freqs[i] * cpuTimesUs[i] / 1_000; 1883 aggregatedTimesUs[freqsClusters[i]] += cpuTimesUs[i]; 1884 } 1885 for (int cluster = 0; cluster < clusters; ++cluster) { 1886 pulledData.add(FrameworkStatsLog.buildStatsEvent( 1887 atomTag, threadGroup, cluster, aggregatedCycles[cluster] / 1_000_000L, 1888 aggregatedTimesUs[cluster] / 1_000)); 1889 } 1890 } 1891 1892 private void registerCpuActiveTime() { 1893 // the throttling is 3sec, handled in 1894 // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader 1895 int tagId = FrameworkStatsLog.CPU_ACTIVE_TIME; 1896 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 1897 .setAdditiveFields(new int[] {2}) 1898 .build(); 1899 mStatsManager.setPullAtomCallback( 1900 tagId, 1901 metadata, 1902 DIRECT_EXECUTOR, 1903 mStatsCallbackImpl 1904 ); 1905 } 1906 1907 int pullCpuActiveTimeLocked(int atomTag, List<StatsEvent> pulledData) { 1908 mCpuUidActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> { 1909 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, uid, cpuActiveTimesMs)); 1910 }); 1911 return StatsManager.PULL_SUCCESS; 1912 } 1913 1914 private void registerCpuClusterTime() { 1915 // the throttling is 3sec, handled in 1916 // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader 1917 int tagId = FrameworkStatsLog.CPU_CLUSTER_TIME; 1918 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 1919 .setAdditiveFields(new int[] {3}) 1920 .build(); 1921 mStatsManager.setPullAtomCallback( 1922 tagId, 1923 metadata, 1924 DIRECT_EXECUTOR, 1925 mStatsCallbackImpl 1926 ); 1927 } 1928 1929 int pullCpuClusterTimeLocked(int atomTag, List<StatsEvent> pulledData) { 1930 mCpuUidClusterTimeReader.readAbsolute((uid, cpuClusterTimesMs) -> { 1931 for (int i = 0; i < cpuClusterTimesMs.length; i++) { 1932 pulledData.add( 1933 FrameworkStatsLog.buildStatsEvent(atomTag, uid, i, cpuClusterTimesMs[i])); 1934 } 1935 }); 1936 return StatsManager.PULL_SUCCESS; 1937 } 1938 1939 private void registerWifiActivityInfo() { 1940 int tagId = FrameworkStatsLog.WIFI_ACTIVITY_INFO; 1941 mStatsManager.setPullAtomCallback( 1942 tagId, 1943 null, // use default PullAtomMetadata values 1944 DIRECT_EXECUTOR, 1945 mStatsCallbackImpl 1946 ); 1947 } 1948 1949 int pullWifiActivityInfoLocked(int atomTag, List<StatsEvent> pulledData) { 1950 final long token = Binder.clearCallingIdentity(); 1951 try { 1952 SynchronousResultReceiver wifiReceiver = new SynchronousResultReceiver("wifi"); 1953 mWifiManager.getWifiActivityEnergyInfoAsync( 1954 new Executor() { 1955 @Override 1956 public void execute(Runnable runnable) { 1957 // run the listener on the binder thread, if it was run on the main 1958 // thread it would deadlock since we would be waiting on ourselves 1959 runnable.run(); 1960 } 1961 }, 1962 info -> { 1963 Bundle bundle = new Bundle(); 1964 bundle.putParcelable(BatteryStats.RESULT_RECEIVER_CONTROLLER_KEY, info); 1965 wifiReceiver.send(0, bundle); 1966 } 1967 ); 1968 final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver); 1969 if (wifiInfo == null) { 1970 return StatsManager.PULL_SKIP; 1971 } 1972 pulledData.add( 1973 FrameworkStatsLog.buildStatsEvent(atomTag, wifiInfo.getTimeSinceBootMillis(), 1974 wifiInfo.getStackState(), wifiInfo.getControllerTxDurationMillis(), 1975 wifiInfo.getControllerRxDurationMillis(), 1976 wifiInfo.getControllerIdleDurationMillis(), 1977 wifiInfo.getControllerEnergyUsedMicroJoules())); 1978 } catch (RuntimeException e) { 1979 Slog.e(TAG, "failed to getWifiActivityEnergyInfoAsync", e); 1980 return StatsManager.PULL_SKIP; 1981 } finally { 1982 Binder.restoreCallingIdentity(token); 1983 } 1984 return StatsManager.PULL_SUCCESS; 1985 } 1986 1987 private void registerModemActivityInfo() { 1988 int tagId = FrameworkStatsLog.MODEM_ACTIVITY_INFO; 1989 mStatsManager.setPullAtomCallback( 1990 tagId, 1991 null, // use default PullAtomMetadata values 1992 DIRECT_EXECUTOR, 1993 mStatsCallbackImpl 1994 ); 1995 } 1996 1997 int pullModemActivityInfoLocked(int atomTag, List<StatsEvent> pulledData) { 1998 final long token = Binder.clearCallingIdentity(); 1999 try { 2000 CompletableFuture<ModemActivityInfo> modemFuture = new CompletableFuture<>(); 2001 mTelephony.requestModemActivityInfo(Runnable::run, 2002 new OutcomeReceiver<ModemActivityInfo, 2003 TelephonyManager.ModemActivityInfoException>() { 2004 @Override 2005 public void onResult(ModemActivityInfo result) { 2006 modemFuture.complete(result); 2007 } 2008 2009 @Override 2010 public void onError(TelephonyManager.ModemActivityInfoException e) { 2011 Slog.w(TAG, "error reading modem stats:" + e); 2012 modemFuture.complete(null); 2013 } 2014 }); 2015 2016 ModemActivityInfo modemInfo; 2017 try { 2018 modemInfo = modemFuture.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS, 2019 TimeUnit.MILLISECONDS); 2020 } catch (TimeoutException | InterruptedException e) { 2021 Slog.w(TAG, "timeout or interrupt reading modem stats: " + e); 2022 return StatsManager.PULL_SKIP; 2023 } catch (ExecutionException e) { 2024 Slog.w(TAG, "exception reading modem stats: " + e.getCause()); 2025 return StatsManager.PULL_SKIP; 2026 } 2027 2028 if (modemInfo == null) { 2029 return StatsManager.PULL_SKIP; 2030 } 2031 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, 2032 modemInfo.getTimestampMillis(), 2033 modemInfo.getSleepTimeMillis(), modemInfo.getIdleTimeMillis(), 2034 modemInfo.getTransmitDurationMillisAtPowerLevel(0), 2035 modemInfo.getTransmitDurationMillisAtPowerLevel(1), 2036 modemInfo.getTransmitDurationMillisAtPowerLevel(2), 2037 modemInfo.getTransmitDurationMillisAtPowerLevel(3), 2038 modemInfo.getTransmitDurationMillisAtPowerLevel(4), 2039 modemInfo.getReceiveTimeMillis(), 2040 -1 /*`energy_used` field name deprecated, use -1 to indicate as unused.*/)); 2041 } finally { 2042 Binder.restoreCallingIdentity(token); 2043 } 2044 return StatsManager.PULL_SUCCESS; 2045 } 2046 2047 private void registerBluetoothActivityInfo() { 2048 int tagId = FrameworkStatsLog.BLUETOOTH_ACTIVITY_INFO; 2049 mStatsManager.setPullAtomCallback( 2050 tagId, 2051 /* metadata */ null, 2052 DIRECT_EXECUTOR, 2053 mStatsCallbackImpl 2054 ); 2055 } 2056 2057 int pullBluetoothActivityInfoLocked(int atomTag, List<StatsEvent> pulledData) { 2058 BluetoothActivityEnergyInfo info = fetchBluetoothData(); 2059 if (info == null) { 2060 return StatsManager.PULL_SKIP; 2061 } 2062 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, info.getTimeStamp(), 2063 info.getBluetoothStackState(), info.getControllerTxTimeMillis(), 2064 info.getControllerRxTimeMillis(), info.getControllerIdleTimeMillis(), 2065 info.getControllerEnergyUsed())); 2066 return StatsManager.PULL_SUCCESS; 2067 } 2068 2069 private void registerSystemElapsedRealtime() { 2070 int tagId = FrameworkStatsLog.SYSTEM_ELAPSED_REALTIME; 2071 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 2072 .setCoolDownMillis(MILLIS_PER_SEC) 2073 .setTimeoutMillis(MILLIS_PER_SEC / 2) 2074 .build(); 2075 mStatsManager.setPullAtomCallback( 2076 tagId, 2077 metadata, 2078 DIRECT_EXECUTOR, 2079 mStatsCallbackImpl 2080 ); 2081 } 2082 2083 int pullSystemElapsedRealtimeLocked(int atomTag, List<StatsEvent> pulledData) { 2084 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, SystemClock.elapsedRealtime())); 2085 return StatsManager.PULL_SUCCESS; 2086 } 2087 2088 private void registerSystemUptime() { 2089 int tagId = FrameworkStatsLog.SYSTEM_UPTIME; 2090 mStatsManager.setPullAtomCallback( 2091 tagId, 2092 null, // use default PullAtomMetadata values 2093 DIRECT_EXECUTOR, 2094 mStatsCallbackImpl 2095 ); 2096 } 2097 2098 int pullSystemUptimeLocked(int atomTag, List<StatsEvent> pulledData) { 2099 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, SystemClock.uptimeMillis())); 2100 return StatsManager.PULL_SUCCESS; 2101 } 2102 2103 private void registerProcessMemoryState() { 2104 int tagId = FrameworkStatsLog.PROCESS_MEMORY_STATE; 2105 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 2106 .setAdditiveFields(new int[] {4, 5, 6, 7, 8}) 2107 .build(); 2108 mStatsManager.setPullAtomCallback( 2109 tagId, 2110 metadata, 2111 DIRECT_EXECUTOR, 2112 mStatsCallbackImpl 2113 ); 2114 } 2115 2116 int pullProcessMemoryStateLocked(int atomTag, List<StatsEvent> pulledData) { 2117 List<ProcessMemoryState> processMemoryStates = 2118 LocalServices.getService(ActivityManagerInternal.class) 2119 .getMemoryStateForProcesses(); 2120 for (ProcessMemoryState processMemoryState : processMemoryStates) { 2121 final MemoryStat memoryStat = readMemoryStatFromFilesystem(processMemoryState.uid, 2122 processMemoryState.pid); 2123 if (memoryStat == null) { 2124 continue; 2125 } 2126 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, processMemoryState.uid, 2127 processMemoryState.processName, processMemoryState.oomScore, memoryStat.pgfault, 2128 memoryStat.pgmajfault, memoryStat.rssInBytes, memoryStat.cacheInBytes, 2129 memoryStat.swapInBytes, -1 /*unused*/, -1 /*unused*/, -1 /*unused*/)); 2130 } 2131 return StatsManager.PULL_SUCCESS; 2132 } 2133 2134 private void registerProcessMemoryHighWaterMark() { 2135 int tagId = FrameworkStatsLog.PROCESS_MEMORY_HIGH_WATER_MARK; 2136 mStatsManager.setPullAtomCallback( 2137 tagId, 2138 null, // use default PullAtomMetadata values 2139 DIRECT_EXECUTOR, 2140 mStatsCallbackImpl 2141 ); 2142 } 2143 2144 int pullProcessMemoryHighWaterMarkLocked(int atomTag, List<StatsEvent> pulledData) { 2145 List<ProcessMemoryState> managedProcessList = 2146 LocalServices.getService(ActivityManagerInternal.class) 2147 .getMemoryStateForProcesses(); 2148 for (ProcessMemoryState managedProcess : managedProcessList) { 2149 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(managedProcess.pid); 2150 if (snapshot == null) { 2151 continue; 2152 } 2153 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, managedProcess.uid, 2154 managedProcess.processName, 2155 // RSS high-water mark in bytes. 2156 snapshot.rssHighWaterMarkInKilobytes * 1024L, 2157 snapshot.rssHighWaterMarkInKilobytes)); 2158 } 2159 // Complement the data with native system processes 2160 SparseArray<String> processCmdlines = getProcessCmdlines(); 2161 managedProcessList.forEach(managedProcess -> processCmdlines.delete(managedProcess.pid)); 2162 int size = processCmdlines.size(); 2163 for (int i = 0; i < size; ++i) { 2164 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(processCmdlines.keyAt(i)); 2165 if (snapshot == null) { 2166 continue; 2167 } 2168 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, snapshot.uid, 2169 processCmdlines.valueAt(i), 2170 // RSS high-water mark in bytes. 2171 snapshot.rssHighWaterMarkInKilobytes * 1024L, 2172 snapshot.rssHighWaterMarkInKilobytes)); 2173 } 2174 // Invoke rss_hwm_reset binary to reset RSS HWM counters for all processes. 2175 SystemProperties.set("sys.rss_hwm_reset.on", "1"); 2176 return StatsManager.PULL_SUCCESS; 2177 } 2178 2179 private void registerProcessMemorySnapshot() { 2180 int tagId = FrameworkStatsLog.PROCESS_MEMORY_SNAPSHOT; 2181 mStatsManager.setPullAtomCallback( 2182 tagId, 2183 null, // use default PullAtomMetadata values 2184 DIRECT_EXECUTOR, 2185 mStatsCallbackImpl 2186 ); 2187 } 2188 2189 int pullProcessMemorySnapshotLocked(int atomTag, List<StatsEvent> pulledData) { 2190 List<ProcessMemoryState> managedProcessList = 2191 LocalServices.getService(ActivityManagerInternal.class) 2192 .getMemoryStateForProcesses(); 2193 for (ProcessMemoryState managedProcess : managedProcessList) { 2194 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(managedProcess.pid); 2195 if (snapshot == null) { 2196 continue; 2197 } 2198 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, managedProcess.uid, 2199 managedProcess.processName, managedProcess.pid, managedProcess.oomScore, 2200 snapshot.rssInKilobytes, snapshot.anonRssInKilobytes, snapshot.swapInKilobytes, 2201 snapshot.anonRssInKilobytes + snapshot.swapInKilobytes)); 2202 } 2203 // Complement the data with native system processes. Given these measurements can be taken 2204 // in response to LMKs happening, we want to first collect the managed app stats (to 2205 // maximize the probability that a heavyweight process will be sampled before it dies). 2206 SparseArray<String> processCmdlines = getProcessCmdlines(); 2207 managedProcessList.forEach(managedProcess -> processCmdlines.delete(managedProcess.pid)); 2208 int size = processCmdlines.size(); 2209 for (int i = 0; i < size; ++i) { 2210 int pid = processCmdlines.keyAt(i); 2211 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(pid); 2212 if (snapshot == null) { 2213 continue; 2214 } 2215 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, snapshot.uid, 2216 processCmdlines.valueAt(i), pid, 2217 -1001 /*Placeholder for native processes, OOM_SCORE_ADJ_MIN - 1.*/, 2218 snapshot.rssInKilobytes, snapshot.anonRssInKilobytes, snapshot.swapInKilobytes, 2219 snapshot.anonRssInKilobytes + snapshot.swapInKilobytes)); 2220 } 2221 return StatsManager.PULL_SUCCESS; 2222 } 2223 2224 private void registerSystemIonHeapSize() { 2225 int tagId = FrameworkStatsLog.SYSTEM_ION_HEAP_SIZE; 2226 mStatsManager.setPullAtomCallback( 2227 tagId, 2228 null, // use default PullAtomMetadata values 2229 DIRECT_EXECUTOR, 2230 mStatsCallbackImpl 2231 ); 2232 } 2233 2234 int pullSystemIonHeapSizeLocked(int atomTag, List<StatsEvent> pulledData) { 2235 final long systemIonHeapSizeInBytes = readSystemIonHeapSizeFromDebugfs(); 2236 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, systemIonHeapSizeInBytes)); 2237 return StatsManager.PULL_SUCCESS; 2238 } 2239 2240 private void registerIonHeapSize() { 2241 if (!new File("/sys/kernel/ion/total_heaps_kb").exists()) { 2242 return; 2243 } 2244 int tagId = FrameworkStatsLog.ION_HEAP_SIZE; 2245 mStatsManager.setPullAtomCallback( 2246 tagId, 2247 /* PullAtomMetadata */ null, 2248 DIRECT_EXECUTOR, 2249 mStatsCallbackImpl 2250 ); 2251 } 2252 2253 int pullIonHeapSizeLocked(int atomTag, List<StatsEvent> pulledData) { 2254 int ionHeapSizeInKilobytes = (int) getIonHeapsSizeKb(); 2255 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, ionHeapSizeInKilobytes)); 2256 return StatsManager.PULL_SUCCESS; 2257 } 2258 2259 private void registerProcessSystemIonHeapSize() { 2260 int tagId = FrameworkStatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE; 2261 mStatsManager.setPullAtomCallback( 2262 tagId, 2263 null, // use default PullAtomMetadata values 2264 DIRECT_EXECUTOR, 2265 mStatsCallbackImpl 2266 ); 2267 } 2268 2269 int pullProcessSystemIonHeapSizeLocked(int atomTag, List<StatsEvent> pulledData) { 2270 List<IonAllocations> result = readProcessSystemIonHeapSizesFromDebugfs(); 2271 for (IonAllocations allocations : result) { 2272 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, getUidForPid(allocations.pid), 2273 readCmdlineFromProcfs(allocations.pid), 2274 (int) (allocations.totalSizeInBytes / 1024), allocations.count, 2275 (int) (allocations.maxSizeInBytes / 1024))); 2276 } 2277 return StatsManager.PULL_SUCCESS; 2278 } 2279 2280 private void registerProcessDmabufMemory() { 2281 int tagId = FrameworkStatsLog.PROCESS_DMABUF_MEMORY; 2282 mStatsManager.setPullAtomCallback( 2283 tagId, 2284 null, // use default PullAtomMetadata values 2285 DIRECT_EXECUTOR, 2286 mStatsCallbackImpl 2287 ); 2288 } 2289 2290 int pullProcessDmabufMemory(int atomTag, List<StatsEvent> pulledData) { 2291 List<ProcessMemoryState> managedProcessList = 2292 LocalServices.getService(ActivityManagerInternal.class) 2293 .getMemoryStateForProcesses(); 2294 managedProcessList.sort(Comparator.comparingInt(x -> x.oomScore)); 2295 for (ProcessMemoryState process : managedProcessList) { 2296 if (process.uid == Process.SYSTEM_UID) { 2297 continue; 2298 } 2299 DmabufInfoReader.ProcessDmabuf proc = DmabufInfoReader.getProcessStats(process.pid); 2300 if (proc == null || (proc.retainedBuffersCount <= 0 && proc.mappedBuffersCount <= 0)) { 2301 continue; 2302 } 2303 pulledData.add( 2304 FrameworkStatsLog.buildStatsEvent( 2305 atomTag, 2306 process.uid, 2307 process.processName, 2308 process.oomScore, 2309 proc.retainedSizeKb, 2310 proc.retainedBuffersCount, 2311 proc.mappedSizeKb, 2312 proc.mappedBuffersCount)); 2313 } 2314 return StatsManager.PULL_SUCCESS; 2315 } 2316 2317 private void registerSystemMemory() { 2318 int tagId = FrameworkStatsLog.SYSTEM_MEMORY; 2319 mStatsManager.setPullAtomCallback( 2320 tagId, 2321 null, // use default PullAtomMetadata values 2322 DIRECT_EXECUTOR, 2323 mStatsCallbackImpl 2324 ); 2325 } 2326 2327 int pullSystemMemory(int atomTag, List<StatsEvent> pulledData) { 2328 SystemMemoryUtil.Metrics metrics = SystemMemoryUtil.getMetrics(); 2329 pulledData.add( 2330 FrameworkStatsLog.buildStatsEvent( 2331 atomTag, 2332 metrics.unreclaimableSlabKb, 2333 metrics.vmallocUsedKb, 2334 metrics.pageTablesKb, 2335 metrics.kernelStackKb, 2336 metrics.totalIonKb, 2337 metrics.unaccountedKb, 2338 metrics.gpuTotalUsageKb, 2339 metrics.gpuPrivateAllocationsKb, 2340 metrics.dmaBufTotalExportedKb)); 2341 return StatsManager.PULL_SUCCESS; 2342 } 2343 2344 private void registerVmStat() { 2345 int tagId = FrameworkStatsLog.VMSTAT; 2346 mStatsManager.setPullAtomCallback( 2347 tagId, 2348 null, // use default PullAtomMetadata values 2349 DIRECT_EXECUTOR, 2350 mStatsCallbackImpl 2351 ); 2352 } 2353 2354 int pullVmStat(int atomTag, List<StatsEvent> pulledData) { 2355 ProcfsMemoryUtil.VmStat vmStat = ProcfsMemoryUtil.readVmStat(); 2356 if (vmStat != null) { 2357 pulledData.add( 2358 FrameworkStatsLog.buildStatsEvent( 2359 atomTag, 2360 vmStat.oomKillCount)); 2361 } 2362 return StatsManager.PULL_SUCCESS; 2363 } 2364 2365 private void registerTemperature() { 2366 int tagId = FrameworkStatsLog.TEMPERATURE; 2367 mStatsManager.setPullAtomCallback( 2368 tagId, 2369 null, // use default PullAtomMetadata values 2370 DIRECT_EXECUTOR, 2371 mStatsCallbackImpl 2372 ); 2373 } 2374 2375 int pullTemperatureLocked(int atomTag, List<StatsEvent> pulledData) { 2376 IThermalService thermalService = getIThermalService(); 2377 if (thermalService == null) { 2378 return StatsManager.PULL_SKIP; 2379 } 2380 final long callingToken = Binder.clearCallingIdentity(); 2381 try { 2382 Temperature temperatures[] = thermalService.getCurrentTemperatures(); 2383 for (Temperature temp : temperatures) { 2384 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, temp.getType(), 2385 temp.getName(), (int) (temp.getValue() * 10), temp.getStatus())); 2386 } 2387 } catch (RemoteException e) { 2388 // Should not happen. 2389 Slog.e(TAG, "Disconnected from thermal service. Cannot pull temperatures."); 2390 return StatsManager.PULL_SKIP; 2391 } finally { 2392 Binder.restoreCallingIdentity(callingToken); 2393 } 2394 return StatsManager.PULL_SUCCESS; 2395 } 2396 2397 private void registerCoolingDevice() { 2398 int tagId = FrameworkStatsLog.COOLING_DEVICE; 2399 mStatsManager.setPullAtomCallback( 2400 tagId, 2401 null, // use default PullAtomMetadata values 2402 DIRECT_EXECUTOR, 2403 mStatsCallbackImpl 2404 ); 2405 } 2406 2407 int pullCooldownDeviceLocked(int atomTag, List<StatsEvent> pulledData) { 2408 IThermalService thermalService = getIThermalService(); 2409 if (thermalService == null) { 2410 return StatsManager.PULL_SKIP; 2411 } 2412 final long callingToken = Binder.clearCallingIdentity(); 2413 try { 2414 CoolingDevice devices[] = thermalService.getCurrentCoolingDevices(); 2415 for (CoolingDevice device : devices) { 2416 pulledData.add(FrameworkStatsLog.buildStatsEvent( 2417 atomTag, device.getType(), device.getName(), (int) (device.getValue()))); 2418 } 2419 } catch (RemoteException e) { 2420 // Should not happen. 2421 Slog.e(TAG, "Disconnected from thermal service. Cannot pull temperatures."); 2422 return StatsManager.PULL_SKIP; 2423 } finally { 2424 Binder.restoreCallingIdentity(callingToken); 2425 } 2426 return StatsManager.PULL_SUCCESS; 2427 } 2428 2429 private void registerBinderCallsStats() { 2430 int tagId = FrameworkStatsLog.BINDER_CALLS; 2431 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 2432 .setAdditiveFields(new int[] {4, 5, 6, 8, 12}) 2433 .build(); 2434 mStatsManager.setPullAtomCallback( 2435 tagId, 2436 metadata, 2437 DIRECT_EXECUTOR, 2438 mStatsCallbackImpl 2439 ); 2440 } 2441 2442 int pullBinderCallsStatsLocked(int atomTag, List<StatsEvent> pulledData) { 2443 BinderCallsStatsService.Internal binderStats = 2444 LocalServices.getService(BinderCallsStatsService.Internal.class); 2445 if (binderStats == null) { 2446 Slog.e(TAG, "failed to get binderStats"); 2447 return StatsManager.PULL_SKIP; 2448 } 2449 2450 List<ExportedCallStat> callStats = binderStats.getExportedCallStats(); 2451 binderStats.reset(); 2452 for (ExportedCallStat callStat : callStats) { 2453 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, callStat.workSourceUid, 2454 callStat.className, callStat.methodName, callStat.callCount, 2455 callStat.exceptionCount, callStat.latencyMicros, callStat.maxLatencyMicros, 2456 callStat.cpuTimeMicros, callStat.maxCpuTimeMicros, callStat.maxReplySizeBytes, 2457 callStat.maxRequestSizeBytes, callStat.recordedCallCount, 2458 callStat.screenInteractive, callStat.callingUid)); 2459 } 2460 return StatsManager.PULL_SUCCESS; 2461 } 2462 2463 private void registerBinderCallsStatsExceptions() { 2464 int tagId = FrameworkStatsLog.BINDER_CALLS_EXCEPTIONS; 2465 mStatsManager.setPullAtomCallback( 2466 tagId, 2467 null, // use default PullAtomMetadata values 2468 DIRECT_EXECUTOR, 2469 mStatsCallbackImpl 2470 ); 2471 } 2472 2473 int pullBinderCallsStatsExceptionsLocked(int atomTag, List<StatsEvent> pulledData) { 2474 BinderCallsStatsService.Internal binderStats = 2475 LocalServices.getService(BinderCallsStatsService.Internal.class); 2476 if (binderStats == null) { 2477 Slog.e(TAG, "failed to get binderStats"); 2478 return StatsManager.PULL_SKIP; 2479 } 2480 2481 ArrayMap<String, Integer> exceptionStats = binderStats.getExportedExceptionStats(); 2482 // TODO: decouple binder calls exceptions with the rest of the binder calls data so that we 2483 // can reset the exception stats. 2484 for (Map.Entry<String, Integer> entry : exceptionStats.entrySet()) { 2485 pulledData.add( 2486 FrameworkStatsLog.buildStatsEvent(atomTag, entry.getKey(), entry.getValue())); 2487 } 2488 return StatsManager.PULL_SUCCESS; 2489 } 2490 2491 private void registerLooperStats() { 2492 int tagId = FrameworkStatsLog.LOOPER_STATS; 2493 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 2494 .setAdditiveFields(new int[] {5, 6, 7, 8, 9}) 2495 .build(); 2496 mStatsManager.setPullAtomCallback( 2497 tagId, 2498 metadata, 2499 DIRECT_EXECUTOR, 2500 mStatsCallbackImpl 2501 ); 2502 } 2503 2504 int pullLooperStatsLocked(int atomTag, List<StatsEvent> pulledData) { 2505 LooperStats looperStats = LocalServices.getService(LooperStats.class); 2506 if (looperStats == null) { 2507 return StatsManager.PULL_SKIP; 2508 } 2509 2510 List<LooperStats.ExportedEntry> entries = looperStats.getEntries(); 2511 looperStats.reset(); 2512 for (LooperStats.ExportedEntry entry : entries) { 2513 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, entry.workSourceUid, 2514 entry.handlerClassName, entry.threadName, entry.messageName, entry.messageCount, 2515 entry.exceptionCount, entry.recordedMessageCount, entry.totalLatencyMicros, 2516 entry.cpuUsageMicros, entry.isInteractive, entry.maxCpuUsageMicros, 2517 entry.maxLatencyMicros, entry.recordedDelayMessageCount, entry.delayMillis, 2518 entry.maxDelayMillis)); 2519 } 2520 return StatsManager.PULL_SUCCESS; 2521 } 2522 2523 private void registerDiskStats() { 2524 int tagId = FrameworkStatsLog.DISK_STATS; 2525 mStatsManager.setPullAtomCallback( 2526 tagId, 2527 null, // use default PullAtomMetadata values 2528 DIRECT_EXECUTOR, 2529 mStatsCallbackImpl 2530 ); 2531 } 2532 2533 int pullDiskStatsLocked(int atomTag, List<StatsEvent> pulledData) { 2534 // Run a quick-and-dirty performance test: write 512 bytes 2535 byte[] junk = new byte[512]; 2536 for (int i = 0; i < junk.length; i++) junk[i] = (byte) i; // Write nonzero bytes 2537 2538 File tmp = new File(Environment.getDataDirectory(), "system/statsdperftest.tmp"); 2539 FileOutputStream fos = null; 2540 IOException error = null; 2541 2542 long before = SystemClock.elapsedRealtime(); 2543 try { 2544 fos = new FileOutputStream(tmp); 2545 fos.write(junk); 2546 } catch (IOException e) { 2547 error = e; 2548 } finally { 2549 try { 2550 if (fos != null) fos.close(); 2551 } catch (IOException e) { 2552 // Do nothing. 2553 } 2554 } 2555 2556 long latency = SystemClock.elapsedRealtime() - before; 2557 if (tmp.exists()) tmp.delete(); 2558 2559 if (error != null) { 2560 Slog.e(TAG, "Error performing diskstats latency test"); 2561 latency = -1; 2562 } 2563 // File based encryption. 2564 boolean fileBased = StorageManager.isFileEncryptedNativeOnly(); 2565 2566 //Recent disk write speed. Binder call to storaged. 2567 int writeSpeed = -1; 2568 IStoraged storaged = getIStoragedService(); 2569 if (storaged == null) { 2570 return StatsManager.PULL_SKIP; 2571 } 2572 try { 2573 writeSpeed = storaged.getRecentPerf(); 2574 } catch (RemoteException e) { 2575 Slog.e(TAG, "storaged not found"); 2576 } 2577 2578 // Add info pulledData. 2579 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, latency, fileBased, writeSpeed)); 2580 return StatsManager.PULL_SUCCESS; 2581 } 2582 2583 private void registerDirectoryUsage() { 2584 int tagId = FrameworkStatsLog.DIRECTORY_USAGE; 2585 mStatsManager.setPullAtomCallback( 2586 tagId, 2587 null, // use default PullAtomMetadata values 2588 DIRECT_EXECUTOR, 2589 mStatsCallbackImpl 2590 ); 2591 } 2592 2593 int pullDirectoryUsageLocked(int atomTag, List<StatsEvent> pulledData) { 2594 StatFs statFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath()); 2595 StatFs statFsSystem = new StatFs(Environment.getRootDirectory().getAbsolutePath()); 2596 StatFs statFsCache = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath()); 2597 2598 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, 2599 FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__DATA, statFsData.getAvailableBytes(), 2600 statFsData.getTotalBytes())); 2601 2602 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, 2603 FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__CACHE, 2604 statFsCache.getAvailableBytes(), statFsCache.getTotalBytes())); 2605 2606 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, 2607 FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__SYSTEM, 2608 statFsSystem.getAvailableBytes(), statFsSystem.getTotalBytes())); 2609 return StatsManager.PULL_SUCCESS; 2610 } 2611 2612 private void registerAppSize() { 2613 int tagId = FrameworkStatsLog.APP_SIZE; 2614 mStatsManager.setPullAtomCallback( 2615 tagId, 2616 null, // use default PullAtomMetadata values 2617 DIRECT_EXECUTOR, 2618 mStatsCallbackImpl 2619 ); 2620 } 2621 2622 int pullAppSizeLocked(int atomTag, List<StatsEvent> pulledData) { 2623 try { 2624 String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH); 2625 JSONObject json = new JSONObject(jsonStr); 2626 long cache_time = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L); 2627 JSONArray pkg_names = json.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY); 2628 JSONArray app_sizes = json.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY); 2629 JSONArray app_data_sizes = json.getJSONArray(DiskStatsFileLogger.APP_DATA_KEY); 2630 JSONArray app_cache_sizes = json.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY); 2631 // Validity check: Ensure all 4 lists have the same length. 2632 int length = pkg_names.length(); 2633 if (app_sizes.length() != length || app_data_sizes.length() != length 2634 || app_cache_sizes.length() != length) { 2635 Slog.e(TAG, "formatting error in diskstats cache file!"); 2636 return StatsManager.PULL_SKIP; 2637 } 2638 for (int i = 0; i < length; i++) { 2639 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, pkg_names.getString(i), 2640 app_sizes.optLong(i, /* fallback */ -1L), 2641 app_data_sizes.optLong(i, /* fallback */ -1L), 2642 app_cache_sizes.optLong(i, /* fallback */ -1L), cache_time)); 2643 } 2644 } catch (IOException | JSONException e) { 2645 Slog.w(TAG, "Unable to read diskstats cache file within pullAppSize"); 2646 return StatsManager.PULL_SKIP; 2647 } 2648 return StatsManager.PULL_SUCCESS; 2649 } 2650 2651 private void registerCategorySize() { 2652 int tagId = FrameworkStatsLog.CATEGORY_SIZE; 2653 mStatsManager.setPullAtomCallback( 2654 tagId, 2655 null, // use default PullAtomMetadata values 2656 DIRECT_EXECUTOR, 2657 mStatsCallbackImpl 2658 ); 2659 } 2660 2661 int pullCategorySizeLocked(int atomTag, List<StatsEvent> pulledData) { 2662 try { 2663 String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH); 2664 JSONObject json = new JSONObject(jsonStr); 2665 long cacheTime = json.optLong( 2666 DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, /* fallback */ -1L); 2667 2668 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, 2669 FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__APP_SIZE, 2670 json.optLong(DiskStatsFileLogger.APP_SIZE_AGG_KEY, /* fallback */ -1L), 2671 cacheTime)); 2672 2673 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, 2674 FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__APP_DATA_SIZE, 2675 json.optLong(DiskStatsFileLogger.APP_DATA_SIZE_AGG_KEY, /* fallback */ -1L), 2676 cacheTime)); 2677 2678 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, 2679 FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__APP_CACHE_SIZE, 2680 json.optLong(DiskStatsFileLogger.APP_CACHE_AGG_KEY, /* fallback */ -1L), 2681 cacheTime)); 2682 2683 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, 2684 FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__PHOTOS, 2685 json.optLong(DiskStatsFileLogger.PHOTOS_KEY, /* fallback */ -1L), cacheTime)); 2686 2687 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, 2688 FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__VIDEOS, 2689 json.optLong(DiskStatsFileLogger.VIDEOS_KEY, /* fallback */ -1L), cacheTime)); 2690 2691 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, 2692 FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__AUDIO, 2693 json.optLong(DiskStatsFileLogger.AUDIO_KEY, /* fallback */ -1L), cacheTime)); 2694 2695 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, 2696 FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__DOWNLOADS, 2697 json.optLong(DiskStatsFileLogger.DOWNLOADS_KEY, /* fallback */ -1L), 2698 cacheTime)); 2699 2700 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, 2701 FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__SYSTEM, 2702 json.optLong(DiskStatsFileLogger.SYSTEM_KEY, /* fallback */ -1L), cacheTime)); 2703 2704 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, 2705 FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__OTHER, 2706 json.optLong(DiskStatsFileLogger.MISC_KEY, /* fallback */ -1L), cacheTime)); 2707 } catch (IOException | JSONException e) { 2708 Slog.w(TAG, "Unable to read diskstats cache file within pullCategorySize"); 2709 return StatsManager.PULL_SKIP; 2710 } 2711 return StatsManager.PULL_SUCCESS; 2712 } 2713 2714 private void registerNumFingerprintsEnrolled() { 2715 int tagId = FrameworkStatsLog.NUM_FINGERPRINTS_ENROLLED; 2716 mStatsManager.setPullAtomCallback( 2717 tagId, 2718 null, // use default PullAtomMetadata values 2719 DIRECT_EXECUTOR, 2720 mStatsCallbackImpl 2721 ); 2722 } 2723 2724 private void registerNumFacesEnrolled() { 2725 int tagId = FrameworkStatsLog.NUM_FACES_ENROLLED; 2726 mStatsManager.setPullAtomCallback( 2727 tagId, 2728 null, // use default PullAtomMetadata values 2729 DIRECT_EXECUTOR, 2730 mStatsCallbackImpl 2731 ); 2732 } 2733 2734 private int pullNumBiometricsEnrolledLocked(int modality, int atomTag, 2735 List<StatsEvent> pulledData) { 2736 final PackageManager pm = mContext.getPackageManager(); 2737 FingerprintManager fingerprintManager = null; 2738 FaceManager faceManager = null; 2739 2740 if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) { 2741 fingerprintManager = mContext.getSystemService(FingerprintManager.class); 2742 } 2743 if (pm.hasSystemFeature(PackageManager.FEATURE_FACE)) { 2744 faceManager = mContext.getSystemService(FaceManager.class); 2745 } 2746 2747 if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT && fingerprintManager == null) { 2748 return StatsManager.PULL_SKIP; 2749 } 2750 if (modality == BiometricsProtoEnums.MODALITY_FACE && faceManager == null) { 2751 return StatsManager.PULL_SKIP; 2752 } 2753 UserManager userManager = mContext.getSystemService(UserManager.class); 2754 if (userManager == null) { 2755 return StatsManager.PULL_SKIP; 2756 } 2757 2758 final long token = Binder.clearCallingIdentity(); 2759 try { 2760 for (UserInfo user : userManager.getUsers()) { 2761 final int userId = user.getUserHandle().getIdentifier(); 2762 int numEnrolled = 0; 2763 if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT) { 2764 numEnrolled = fingerprintManager.getEnrolledFingerprints(userId).size(); 2765 } else if (modality == BiometricsProtoEnums.MODALITY_FACE) { 2766 numEnrolled = faceManager.getEnrolledFaces(userId).size(); 2767 } else { 2768 return StatsManager.PULL_SKIP; 2769 } 2770 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, userId, numEnrolled)); 2771 } 2772 } finally { 2773 Binder.restoreCallingIdentity(token); 2774 } 2775 return StatsManager.PULL_SUCCESS; 2776 } 2777 2778 private void registerProcStats() { 2779 int tagId = FrameworkStatsLog.PROC_STATS; 2780 mStatsManager.setPullAtomCallback( 2781 tagId, 2782 null, // use default PullAtomMetadata values 2783 DIRECT_EXECUTOR, 2784 mStatsCallbackImpl 2785 ); 2786 } 2787 2788 private void registerProcStatsPkgProc() { 2789 int tagId = FrameworkStatsLog.PROC_STATS_PKG_PROC; 2790 mStatsManager.setPullAtomCallback( 2791 tagId, 2792 null, // use default PullAtomMetadata values 2793 DIRECT_EXECUTOR, 2794 mStatsCallbackImpl 2795 ); 2796 } 2797 2798 private int pullProcStatsLocked(int section, int atomTag, List<StatsEvent> pulledData) { 2799 IProcessStats processStatsService = getIProcessStatsService(); 2800 if (processStatsService == null) { 2801 return StatsManager.PULL_SKIP; 2802 } 2803 2804 final long token = Binder.clearCallingIdentity(); 2805 try { 2806 // force procstats to flush & combine old files into one store 2807 long lastHighWaterMark = readProcStatsHighWaterMark(section); 2808 2809 ProtoOutputStream[] protoStreams = new ProtoOutputStream[MAX_PROCSTATS_SHARDS]; 2810 for (int i = 0; i < protoStreams.length; i++) { 2811 protoStreams[i] = new ProtoOutputStream(); 2812 } 2813 2814 ProcessStats procStats = new ProcessStats(false); 2815 // Force processStatsService to aggregate all in-storage and in-memory data. 2816 long highWaterMark = processStatsService.getCommittedStatsMerged( 2817 lastHighWaterMark, section, true, null, procStats); 2818 procStats.dumpAggregatedProtoForStatsd(protoStreams, MAX_PROCSTATS_RAW_SHARD_SIZE); 2819 2820 for (int i = 0; i < protoStreams.length; i++) { 2821 byte[] bytes = protoStreams[i].getBytes(); // cache the value 2822 if (bytes.length > 0) { 2823 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, bytes, 2824 // This is a shard ID, and is specified in the metric definition to be 2825 // a dimension. This will result in statsd using RANDOM_ONE_SAMPLE to 2826 // keep all the shards, as it thinks each shard is a different dimension 2827 // of data. 2828 i)); 2829 } 2830 } 2831 2832 new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + lastHighWaterMark) 2833 .delete(); 2834 new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + highWaterMark) 2835 .createNewFile(); 2836 } catch (RemoteException | IOException e) { 2837 Slog.e(TAG, "Getting procstats failed: ", e); 2838 return StatsManager.PULL_SKIP; 2839 } finally { 2840 Binder.restoreCallingIdentity(token); 2841 } 2842 return StatsManager.PULL_SUCCESS; 2843 } 2844 2845 // read high watermark for section 2846 private long readProcStatsHighWaterMark(int section) { 2847 try { 2848 File[] files = mBaseDir.listFiles((d, name) -> { 2849 return name.toLowerCase().startsWith(String.valueOf(section) + '_'); 2850 }); 2851 if (files == null || files.length == 0) { 2852 return 0; 2853 } 2854 if (files.length > 1) { 2855 Slog.e(TAG, "Only 1 file expected for high water mark. Found " + files.length); 2856 } 2857 return Long.valueOf(files[0].getName().split("_")[1]); 2858 } catch (SecurityException e) { 2859 Slog.e(TAG, "Failed to get procstats high watermark file.", e); 2860 } catch (NumberFormatException e) { 2861 Slog.e(TAG, "Failed to parse file name.", e); 2862 } 2863 return 0; 2864 } 2865 2866 private void registerDiskIO() { 2867 int tagId = FrameworkStatsLog.DISK_IO; 2868 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 2869 .setAdditiveFields(new int[] {2, 3, 4, 5, 6, 7, 8, 9, 10, 11}) 2870 .setCoolDownMillis(3 * MILLIS_PER_SEC) 2871 .build(); 2872 mStatsManager.setPullAtomCallback( 2873 tagId, 2874 metadata, 2875 DIRECT_EXECUTOR, 2876 mStatsCallbackImpl 2877 ); 2878 } 2879 2880 int pullDiskIOLocked(int atomTag, List<StatsEvent> pulledData) { 2881 mStoragedUidIoStatsReader.readAbsolute( 2882 (uid, fgCharsRead, fgCharsWrite, fgBytesRead, fgBytesWrite, bgCharsRead, 2883 bgCharsWrite, bgBytesRead, bgBytesWrite, fgFsync, bgFsync) -> { 2884 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, uid, fgCharsRead, 2885 fgCharsWrite, fgBytesRead, fgBytesWrite, bgCharsRead, bgCharsWrite, 2886 bgBytesRead, bgBytesWrite, fgFsync, bgFsync)); 2887 }); 2888 return StatsManager.PULL_SUCCESS; 2889 } 2890 2891 private void registerPowerProfile() { 2892 int tagId = FrameworkStatsLog.POWER_PROFILE; 2893 mStatsManager.setPullAtomCallback( 2894 tagId, 2895 /* PullAtomMetadata */ null, 2896 DIRECT_EXECUTOR, 2897 mStatsCallbackImpl 2898 ); 2899 } 2900 2901 int pullPowerProfileLocked(int atomTag, List<StatsEvent> pulledData) { 2902 PowerProfile powerProfile = new PowerProfile(mContext); 2903 ProtoOutputStream proto = new ProtoOutputStream(); 2904 powerProfile.dumpDebug(proto); 2905 proto.flush(); 2906 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, proto.getBytes())); 2907 return StatsManager.PULL_SUCCESS; 2908 } 2909 2910 private void registerProcessCpuTime() { 2911 int tagId = FrameworkStatsLog.PROCESS_CPU_TIME; 2912 // Min cool-down is 5 sec, in line with what ActivityManagerService uses. 2913 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 2914 .setCoolDownMillis(5 * MILLIS_PER_SEC) 2915 .build(); 2916 mStatsManager.setPullAtomCallback( 2917 tagId, 2918 metadata, 2919 DIRECT_EXECUTOR, 2920 mStatsCallbackImpl 2921 ); 2922 } 2923 2924 int pullProcessCpuTimeLocked(int atomTag, List<StatsEvent> pulledData) { 2925 if (mProcessCpuTracker == null) { 2926 mProcessCpuTracker = new ProcessCpuTracker(false); 2927 mProcessCpuTracker.init(); 2928 } 2929 mProcessCpuTracker.update(); 2930 for (int i = 0; i < mProcessCpuTracker.countStats(); i++) { 2931 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2932 pulledData.add(FrameworkStatsLog.buildStatsEvent( 2933 atomTag, st.uid, st.name, st.base_utime, st.base_stime)); 2934 } 2935 return StatsManager.PULL_SUCCESS; 2936 } 2937 2938 private void registerCpuTimePerThreadFreq() { 2939 int tagId = FrameworkStatsLog.CPU_TIME_PER_THREAD_FREQ; 2940 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 2941 .setAdditiveFields(new int[] {7, 9, 11, 13, 15, 17, 19, 21}) 2942 .build(); 2943 mStatsManager.setPullAtomCallback( 2944 tagId, 2945 metadata, 2946 DIRECT_EXECUTOR, 2947 mStatsCallbackImpl 2948 ); 2949 } 2950 2951 int pullCpuTimePerThreadFreqLocked(int atomTag, List<StatsEvent> pulledData) { 2952 if (this.mKernelCpuThreadReader == null) { 2953 Slog.e(TAG, "mKernelCpuThreadReader is null"); 2954 return StatsManager.PULL_SKIP; 2955 } 2956 ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages = 2957 this.mKernelCpuThreadReader.getProcessCpuUsageDiffed(); 2958 if (processCpuUsages == null) { 2959 Slog.e(TAG, "processCpuUsages is null"); 2960 return StatsManager.PULL_SKIP; 2961 } 2962 int[] cpuFrequencies = mKernelCpuThreadReader.getCpuFrequenciesKhz(); 2963 if (cpuFrequencies.length > CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES) { 2964 String message = "Expected maximum " + CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES 2965 + " frequencies, but got " + cpuFrequencies.length; 2966 Slog.w(TAG, message); 2967 return StatsManager.PULL_SKIP; 2968 } 2969 for (int i = 0; i < processCpuUsages.size(); i++) { 2970 KernelCpuThreadReader.ProcessCpuUsage processCpuUsage = processCpuUsages.get(i); 2971 ArrayList<KernelCpuThreadReader.ThreadCpuUsage> threadCpuUsages = 2972 processCpuUsage.threadCpuUsages; 2973 for (int j = 0; j < threadCpuUsages.size(); j++) { 2974 KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage = threadCpuUsages.get(j); 2975 if (threadCpuUsage.usageTimesMillis.length != cpuFrequencies.length) { 2976 String message = "Unexpected number of usage times," 2977 + " expected " + cpuFrequencies.length 2978 + " but got " + threadCpuUsage.usageTimesMillis.length; 2979 Slog.w(TAG, message); 2980 return StatsManager.PULL_SKIP; 2981 } 2982 2983 int[] frequencies = new int[CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES]; 2984 int[] usageTimesMillis = new int[CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES]; 2985 for (int k = 0; k < CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES; k++) { 2986 if (k < cpuFrequencies.length) { 2987 frequencies[k] = cpuFrequencies[k]; 2988 usageTimesMillis[k] = threadCpuUsage.usageTimesMillis[k]; 2989 } else { 2990 // If we have no more frequencies to write, we still must write empty data. 2991 // We know that this data is empty (and not just zero) because all 2992 // frequencies are expected to be greater than zero 2993 frequencies[k] = 0; 2994 usageTimesMillis[k] = 0; 2995 } 2996 } 2997 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, processCpuUsage.uid, 2998 processCpuUsage.processId, threadCpuUsage.threadId, 2999 processCpuUsage.processName, threadCpuUsage.threadName, frequencies[0], 3000 usageTimesMillis[0], frequencies[1], usageTimesMillis[1], frequencies[2], 3001 usageTimesMillis[2], frequencies[3], usageTimesMillis[3], frequencies[4], 3002 usageTimesMillis[4], frequencies[5], usageTimesMillis[5], frequencies[6], 3003 usageTimesMillis[6], frequencies[7], usageTimesMillis[7])); 3004 } 3005 } 3006 return StatsManager.PULL_SUCCESS; 3007 } 3008 3009 private BatteryStatsHelper getBatteryStatsHelper() { 3010 synchronized (mBatteryStatsHelperLock) { 3011 if (mBatteryStatsHelper == null) { 3012 final long callingToken = Binder.clearCallingIdentity(); 3013 try { 3014 // clearCallingIdentity required for BatteryStatsHelper.checkWifiOnly(). 3015 mBatteryStatsHelper = new BatteryStatsHelper(mContext, false); 3016 } finally { 3017 Binder.restoreCallingIdentity(callingToken); 3018 } 3019 mBatteryStatsHelper.create((Bundle) null); 3020 } 3021 long currentTime = SystemClock.elapsedRealtime(); 3022 if (currentTime - mBatteryStatsHelperTimestampMs 3023 >= MAX_BATTERY_STATS_HELPER_FREQUENCY_MS) { 3024 // Load BatteryStats and do all the calculations. 3025 mBatteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, 3026 UserHandle.USER_ALL); 3027 // Calculations are done so we don't need to save the raw BatteryStats data in RAM. 3028 mBatteryStatsHelper.clearStats(); 3029 mBatteryStatsHelperTimestampMs = currentTime; 3030 } 3031 } 3032 return mBatteryStatsHelper; 3033 } 3034 3035 private long milliAmpHrsToNanoAmpSecs(double mAh) { 3036 return (long) (mAh * MILLI_AMP_HR_TO_NANO_AMP_SECS + 0.5); 3037 } 3038 3039 private void registerDeviceCalculatedPowerUse() { 3040 int tagId = FrameworkStatsLog.DEVICE_CALCULATED_POWER_USE; 3041 mStatsManager.setPullAtomCallback( 3042 tagId, 3043 null, // use default PullAtomMetadata values 3044 DIRECT_EXECUTOR, 3045 mStatsCallbackImpl 3046 ); 3047 } 3048 3049 int pullDeviceCalculatedPowerUseLocked(int atomTag, List<StatsEvent> pulledData) { 3050 BatteryStatsHelper bsHelper = getBatteryStatsHelper(); 3051 pulledData.add(FrameworkStatsLog.buildStatsEvent( 3052 atomTag, milliAmpHrsToNanoAmpSecs(bsHelper.getComputedPower()))); 3053 return StatsManager.PULL_SUCCESS; 3054 } 3055 3056 private void registerDeviceCalculatedPowerBlameUid() { 3057 int tagId = FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_UID; 3058 mStatsManager.setPullAtomCallback( 3059 tagId, 3060 null, // use default PullAtomMetadata values 3061 DIRECT_EXECUTOR, 3062 mStatsCallbackImpl 3063 ); 3064 } 3065 3066 int pullDeviceCalculatedPowerBlameUidLocked(int atomTag, List<StatsEvent> pulledData) { 3067 final List<BatterySipper> sippers = getBatteryStatsHelper().getUsageList(); 3068 if (sippers == null) { 3069 return StatsManager.PULL_SKIP; 3070 } 3071 3072 for (BatterySipper bs : sippers) { 3073 if (bs.drainType != bs.drainType.APP) { 3074 continue; 3075 } 3076 pulledData.add(FrameworkStatsLog.buildStatsEvent( 3077 atomTag, bs.uidObj.getUid(), milliAmpHrsToNanoAmpSecs(bs.totalPowerMah))); 3078 } 3079 return StatsManager.PULL_SUCCESS; 3080 } 3081 3082 private void registerDeviceCalculatedPowerBlameOther() { 3083 int tagId = FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_OTHER; 3084 mStatsManager.setPullAtomCallback( 3085 tagId, 3086 null, // use default PullAtomMetadata values 3087 DIRECT_EXECUTOR, 3088 mStatsCallbackImpl 3089 ); 3090 } 3091 3092 int pullDeviceCalculatedPowerBlameOtherLocked(int atomTag, List<StatsEvent> pulledData) { 3093 final List<BatterySipper> sippers = getBatteryStatsHelper().getUsageList(); 3094 if (sippers == null) { 3095 return StatsManager.PULL_SKIP; 3096 } 3097 3098 for (BatterySipper bs : sippers) { 3099 if (bs.drainType == bs.drainType.APP) { 3100 continue; // This is a separate atom; see pullDeviceCalculatedPowerBlameUid(). 3101 } 3102 if (bs.drainType == bs.drainType.USER) { 3103 continue; // This is not supported. We purposefully calculate over USER_ALL. 3104 } 3105 pulledData.add(FrameworkStatsLog.buildStatsEvent( 3106 atomTag, bs.drainType.ordinal(), milliAmpHrsToNanoAmpSecs(bs.totalPowerMah))); 3107 } 3108 return StatsManager.PULL_SUCCESS; 3109 } 3110 3111 private void registerDebugElapsedClock() { 3112 int tagId = FrameworkStatsLog.DEBUG_ELAPSED_CLOCK; 3113 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 3114 .setAdditiveFields(new int[] {1, 2, 3, 4}) 3115 .build(); 3116 mStatsManager.setPullAtomCallback( 3117 tagId, 3118 metadata, 3119 DIRECT_EXECUTOR, 3120 mStatsCallbackImpl 3121 ); 3122 } 3123 3124 int pullDebugElapsedClockLocked(int atomTag, List<StatsEvent> pulledData) { 3125 final long elapsedMillis = SystemClock.elapsedRealtime(); 3126 final long clockDiffMillis = mDebugElapsedClockPreviousValue == 0 3127 ? 0 : elapsedMillis - mDebugElapsedClockPreviousValue; 3128 3129 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, mDebugElapsedClockPullCount, 3130 elapsedMillis, 3131 // Log it twice to be able to test multi-value aggregation from ValueMetric. 3132 elapsedMillis, clockDiffMillis, 1 /* always set */)); 3133 3134 if (mDebugElapsedClockPullCount % 2 == 1) { 3135 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, mDebugElapsedClockPullCount, 3136 elapsedMillis, 3137 // Log it twice to be able to test multi-value aggregation from ValueMetric. 3138 elapsedMillis, clockDiffMillis, 2 /* set on odd pulls */)); 3139 } 3140 3141 mDebugElapsedClockPullCount++; 3142 mDebugElapsedClockPreviousValue = elapsedMillis; 3143 return StatsManager.PULL_SUCCESS; 3144 } 3145 3146 private void registerDebugFailingElapsedClock() { 3147 int tagId = FrameworkStatsLog.DEBUG_FAILING_ELAPSED_CLOCK; 3148 PullAtomMetadata metadata = new PullAtomMetadata.Builder() 3149 .setAdditiveFields(new int[] {1, 2, 3, 4}) 3150 .build(); 3151 mStatsManager.setPullAtomCallback( 3152 tagId, 3153 metadata, 3154 DIRECT_EXECUTOR, 3155 mStatsCallbackImpl 3156 ); 3157 } 3158 3159 int pullDebugFailingElapsedClockLocked(int atomTag, List<StatsEvent> pulledData) { 3160 final long elapsedMillis = SystemClock.elapsedRealtime(); 3161 // Fails every 5 buckets. 3162 if (mDebugFailingElapsedClockPullCount++ % 5 == 0) { 3163 mDebugFailingElapsedClockPreviousValue = elapsedMillis; 3164 Slog.e(TAG, "Failing debug elapsed clock"); 3165 return StatsManager.PULL_SKIP; 3166 } 3167 3168 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, 3169 mDebugFailingElapsedClockPullCount, elapsedMillis, 3170 // Log it twice to be able to test multi-value aggregation from ValueMetric. 3171 elapsedMillis, 3172 mDebugFailingElapsedClockPreviousValue == 0 3173 ? 0 3174 : elapsedMillis - mDebugFailingElapsedClockPreviousValue)); 3175 3176 mDebugFailingElapsedClockPreviousValue = elapsedMillis; 3177 return StatsManager.PULL_SUCCESS; 3178 } 3179 3180 private void registerBuildInformation() { 3181 int tagId = FrameworkStatsLog.BUILD_INFORMATION; 3182 mStatsManager.setPullAtomCallback( 3183 tagId, 3184 null, // use default PullAtomMetadata values 3185 DIRECT_EXECUTOR, 3186 mStatsCallbackImpl 3187 ); 3188 } 3189 3190 int pullBuildInformationLocked(int atomTag, List<StatsEvent> pulledData) { 3191 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, Build.FINGERPRINT, Build.BRAND, 3192 Build.PRODUCT, Build.DEVICE, Build.VERSION.RELEASE_OR_CODENAME, Build.ID, 3193 Build.VERSION.INCREMENTAL, Build.TYPE, Build.TAGS)); 3194 return StatsManager.PULL_SUCCESS; 3195 } 3196 3197 private void registerRoleHolder() { 3198 int tagId = FrameworkStatsLog.ROLE_HOLDER; 3199 mStatsManager.setPullAtomCallback( 3200 tagId, 3201 null, // use default PullAtomMetadata values 3202 DIRECT_EXECUTOR, 3203 mStatsCallbackImpl 3204 ); 3205 } 3206 3207 // Add a RoleHolder atom for each package that holds a role. 3208 int pullRoleHolderLocked(int atomTag, List<StatsEvent> pulledData) { 3209 final long callingToken = Binder.clearCallingIdentity(); 3210 try { 3211 PackageManager pm = mContext.getPackageManager(); 3212 RoleManagerLocal roleManagerLocal = LocalManagerRegistry.getManager( 3213 RoleManagerLocal.class); 3214 3215 List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers(); 3216 3217 int numUsers = users.size(); 3218 for (int userNum = 0; userNum < numUsers; userNum++) { 3219 int userId = users.get(userNum).getUserHandle().getIdentifier(); 3220 3221 Map<String, Set<String>> roles = roleManagerLocal.getRolesAndHolders(userId); 3222 3223 for (Map.Entry<String, Set<String>> roleEntry : roles.entrySet()) { 3224 String roleName = roleEntry.getKey(); 3225 Set<String> packageNames = roleEntry.getValue(); 3226 3227 for (String packageName : packageNames) { 3228 PackageInfo pkg; 3229 try { 3230 pkg = pm.getPackageInfoAsUser(packageName, 0, userId); 3231 } catch (PackageManager.NameNotFoundException e) { 3232 Slog.w(TAG, "Role holder " + packageName + " not found"); 3233 return StatsManager.PULL_SKIP; 3234 } 3235 3236 pulledData.add(FrameworkStatsLog.buildStatsEvent( 3237 atomTag, pkg.applicationInfo.uid, packageName, roleName)); 3238 } 3239 } 3240 } 3241 } finally { 3242 Binder.restoreCallingIdentity(callingToken); 3243 } 3244 return StatsManager.PULL_SUCCESS; 3245 } 3246 3247 private void registerDangerousPermissionState() { 3248 int tagId = FrameworkStatsLog.DANGEROUS_PERMISSION_STATE; 3249 mStatsManager.setPullAtomCallback( 3250 tagId, 3251 null, // use default PullAtomMetadata values 3252 DIRECT_EXECUTOR, 3253 mStatsCallbackImpl 3254 ); 3255 } 3256 3257 int pullDangerousPermissionStateLocked(int atomTag, List<StatsEvent> pulledData) { 3258 final long token = Binder.clearCallingIdentity(); 3259 float samplingRate = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_PERMISSIONS, 3260 DANGEROUS_PERMISSION_STATE_SAMPLE_RATE, 0.015f); 3261 Set<Integer> reportedUids = new HashSet<>(); 3262 try { 3263 PackageManager pm = mContext.getPackageManager(); 3264 3265 List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers(); 3266 3267 int numUsers = users.size(); 3268 for (int userNum = 0; userNum < numUsers; userNum++) { 3269 UserHandle user = users.get(userNum).getUserHandle(); 3270 3271 List<PackageInfo> pkgs = pm.getInstalledPackagesAsUser( 3272 PackageManager.GET_PERMISSIONS, user.getIdentifier()); 3273 3274 int numPkgs = pkgs.size(); 3275 for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) { 3276 PackageInfo pkg = pkgs.get(pkgNum); 3277 3278 if (pkg.requestedPermissions == null) { 3279 continue; 3280 } 3281 3282 if (reportedUids.contains(pkg.applicationInfo.uid)) { 3283 // do not report same uid twice 3284 continue; 3285 } 3286 reportedUids.add(pkg.applicationInfo.uid); 3287 3288 if (atomTag == FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED 3289 && ThreadLocalRandom.current().nextFloat() > samplingRate) { 3290 continue; 3291 } 3292 3293 int numPerms = pkg.requestedPermissions.length; 3294 for (int permNum = 0; permNum < numPerms; permNum++) { 3295 String permName = pkg.requestedPermissions[permNum]; 3296 3297 PermissionInfo permissionInfo; 3298 int permissionFlags = 0; 3299 try { 3300 permissionInfo = pm.getPermissionInfo(permName, 0); 3301 permissionFlags = 3302 pm.getPermissionFlags(permName, pkg.packageName, user); 3303 } catch (PackageManager.NameNotFoundException ignored) { 3304 continue; 3305 } 3306 3307 if (permName.startsWith(COMMON_PERMISSION_PREFIX)) { 3308 permName = permName.substring(COMMON_PERMISSION_PREFIX.length()); 3309 } 3310 3311 StatsEvent e; 3312 if (atomTag == FrameworkStatsLog.DANGEROUS_PERMISSION_STATE) { 3313 e = FrameworkStatsLog.buildStatsEvent(atomTag, permName, 3314 pkg.applicationInfo.uid, "", 3315 (pkg.requestedPermissionsFlags[permNum] 3316 & REQUESTED_PERMISSION_GRANTED) 3317 != 0, 3318 permissionFlags, permissionInfo.getProtection() 3319 | permissionInfo.getProtectionFlags()); 3320 } else { 3321 // DangeorusPermissionStateSampled atom. 3322 e = FrameworkStatsLog.buildStatsEvent(atomTag, permName, 3323 pkg.applicationInfo.uid, 3324 (pkg.requestedPermissionsFlags[permNum] 3325 & REQUESTED_PERMISSION_GRANTED) 3326 != 0, 3327 permissionFlags, permissionInfo.getProtection() 3328 | permissionInfo.getProtectionFlags()); 3329 } 3330 pulledData.add(e); 3331 } 3332 } 3333 } 3334 } catch (Throwable t) { 3335 Log.e(TAG, "Could not read permissions", t); 3336 return StatsManager.PULL_SKIP; 3337 } finally { 3338 Binder.restoreCallingIdentity(token); 3339 } 3340 return StatsManager.PULL_SUCCESS; 3341 } 3342 3343 private void registerTimeZoneDataInfo() { 3344 int tagId = FrameworkStatsLog.TIME_ZONE_DATA_INFO; 3345 mStatsManager.setPullAtomCallback( 3346 tagId, 3347 null, // use default PullAtomMetadata values 3348 DIRECT_EXECUTOR, 3349 mStatsCallbackImpl 3350 ); 3351 } 3352 3353 int pullTimeZoneDataInfoLocked(int atomTag, List<StatsEvent> pulledData) { 3354 String tzDbVersion = "Unknown"; 3355 try { 3356 tzDbVersion = android.icu.util.TimeZone.getTZDataVersion(); 3357 } catch (MissingResourceException e) { 3358 Slog.e(TAG, "Getting tzdb version failed: ", e); 3359 return StatsManager.PULL_SKIP; 3360 } 3361 3362 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, tzDbVersion)); 3363 return StatsManager.PULL_SUCCESS; 3364 } 3365 3366 private void registerTimeZoneDetectorState() { 3367 int tagId = FrameworkStatsLog.TIME_ZONE_DETECTOR_STATE; 3368 mStatsManager.setPullAtomCallback( 3369 tagId, 3370 null, // use default PullAtomMetadata values 3371 DIRECT_EXECUTOR, 3372 mStatsCallbackImpl 3373 ); 3374 } 3375 3376 int pullTimeZoneDetectorStateLocked(int atomTag, List<StatsEvent> pulledData) { 3377 final long token = Binder.clearCallingIdentity(); 3378 try { 3379 TimeZoneDetectorInternal timeZoneDetectorInternal = 3380 LocalServices.getService(TimeZoneDetectorInternal.class); 3381 MetricsTimeZoneDetectorState metricsState = 3382 timeZoneDetectorInternal.generateMetricsState(); 3383 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, 3384 metricsState.isTelephonyDetectionSupported(), 3385 metricsState.isGeoDetectionSupported(), 3386 metricsState.isUserLocationEnabled(), 3387 metricsState.getAutoDetectionEnabledSetting(), 3388 metricsState.getGeoDetectionEnabledSetting(), 3389 convertToMetricsDetectionMode(metricsState.getDetectionMode()), 3390 metricsState.getDeviceTimeZoneIdOrdinal(), 3391 metricsState.getLatestManualSuggestionProtoBytes(), 3392 metricsState.getLatestTelephonySuggestionProtoBytes(), 3393 metricsState.getLatestGeolocationSuggestionProtoBytes() 3394 )); 3395 } catch (RuntimeException e) { 3396 Slog.e(TAG, "Getting time zone detection state failed: ", e); 3397 return StatsManager.PULL_SKIP; 3398 } finally { 3399 Binder.restoreCallingIdentity(token); 3400 } 3401 return StatsManager.PULL_SUCCESS; 3402 } 3403 3404 private int convertToMetricsDetectionMode(int detectionMode) { 3405 switch (detectionMode) { 3406 case MetricsTimeZoneDetectorState.DETECTION_MODE_MANUAL: 3407 return TIME_ZONE_DETECTOR_STATE__DETECTION_MODE__MANUAL; 3408 case MetricsTimeZoneDetectorState.DETECTION_MODE_GEO: 3409 return TIME_ZONE_DETECTOR_STATE__DETECTION_MODE__GEO; 3410 case MetricsTimeZoneDetectorState.DETECTION_MODE_TELEPHONY: 3411 return TIME_ZONE_DETECTOR_STATE__DETECTION_MODE__TELEPHONY; 3412 default: 3413 throw new IllegalArgumentException("" + detectionMode); 3414 } 3415 } 3416 3417 private void registerExternalStorageInfo() { 3418 int tagId = FrameworkStatsLog.EXTERNAL_STORAGE_INFO; 3419 mStatsManager.setPullAtomCallback( 3420 tagId, 3421 null, // use default PullAtomMetadata values 3422 DIRECT_EXECUTOR, 3423 mStatsCallbackImpl 3424 ); 3425 } 3426 3427 int pullExternalStorageInfoLocked(int atomTag, List<StatsEvent> pulledData) { 3428 if (mStorageManager == null) { 3429 return StatsManager.PULL_SKIP; 3430 } 3431 3432 List<VolumeInfo> volumes = mStorageManager.getVolumes(); 3433 for (VolumeInfo vol : volumes) { 3434 final String envState = VolumeInfo.getEnvironmentForState(vol.getState()); 3435 final DiskInfo diskInfo = vol.getDisk(); 3436 if (diskInfo != null && envState.equals(Environment.MEDIA_MOUNTED)) { 3437 // Get the type of the volume, if it is adoptable or portable. 3438 int volumeType = FrameworkStatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__OTHER; 3439 if (vol.getType() == TYPE_PUBLIC) { 3440 volumeType = FrameworkStatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PUBLIC; 3441 } else if (vol.getType() == TYPE_PRIVATE) { 3442 volumeType = FrameworkStatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PRIVATE; 3443 } 3444 3445 // Get the type of external storage inserted in the device (sd cards, usb, etc.) 3446 int externalStorageType; 3447 if (diskInfo.isSd()) { 3448 externalStorageType = StorageEnums.SD_CARD; 3449 } else if (diskInfo.isUsb()) { 3450 externalStorageType = StorageEnums.USB; 3451 } else { 3452 externalStorageType = StorageEnums.OTHER; 3453 } 3454 3455 pulledData.add(FrameworkStatsLog.buildStatsEvent( 3456 atomTag, externalStorageType, volumeType, diskInfo.size)); 3457 } 3458 } 3459 return StatsManager.PULL_SUCCESS; 3460 } 3461 3462 private void registerAppsOnExternalStorageInfo() { 3463 int tagId = FrameworkStatsLog.APPS_ON_EXTERNAL_STORAGE_INFO; 3464 mStatsManager.setPullAtomCallback( 3465 tagId, 3466 null, // use default PullAtomMetadata values 3467 DIRECT_EXECUTOR, 3468 mStatsCallbackImpl 3469 ); 3470 } 3471 3472 int pullAppsOnExternalStorageInfoLocked(int atomTag, List<StatsEvent> pulledData) { 3473 if (mStorageManager == null) { 3474 return StatsManager.PULL_SKIP; 3475 } 3476 3477 PackageManager pm = mContext.getPackageManager(); 3478 List<ApplicationInfo> apps = pm.getInstalledApplications(/*flags=*/ 0); 3479 for (ApplicationInfo appInfo : apps) { 3480 UUID storageUuid = appInfo.storageUuid; 3481 if (storageUuid == null) { 3482 continue; 3483 } 3484 3485 VolumeInfo volumeInfo = mStorageManager.findVolumeByUuid( 3486 appInfo.storageUuid.toString()); 3487 if (volumeInfo == null) { 3488 continue; 3489 } 3490 3491 DiskInfo diskInfo = volumeInfo.getDisk(); 3492 if (diskInfo == null) { 3493 continue; 3494 } 3495 3496 int externalStorageType = -1; 3497 if (diskInfo.isSd()) { 3498 externalStorageType = StorageEnums.SD_CARD; 3499 } else if (diskInfo.isUsb()) { 3500 externalStorageType = StorageEnums.USB; 3501 } else if (appInfo.isExternal()) { 3502 externalStorageType = StorageEnums.OTHER; 3503 } 3504 3505 // App is installed on external storage. 3506 if (externalStorageType != -1) { 3507 pulledData.add(FrameworkStatsLog.buildStatsEvent( 3508 atomTag, externalStorageType, appInfo.packageName)); 3509 } 3510 } 3511 return StatsManager.PULL_SUCCESS; 3512 } 3513 3514 private void registerFaceSettings() { 3515 int tagId = FrameworkStatsLog.FACE_SETTINGS; 3516 mStatsManager.setPullAtomCallback( 3517 tagId, 3518 null, // use default PullAtomMetadata values 3519 DIRECT_EXECUTOR, 3520 mStatsCallbackImpl 3521 ); 3522 } 3523 3524 int pullFaceSettingsLocked(int atomTag, List<StatsEvent> pulledData) { 3525 final long callingToken = Binder.clearCallingIdentity(); 3526 try { 3527 UserManager manager = mContext.getSystemService(UserManager.class); 3528 if (manager == null) { 3529 return StatsManager.PULL_SKIP; 3530 } 3531 List<UserInfo> users = manager.getUsers(); 3532 int numUsers = users.size(); 3533 for (int userNum = 0; userNum < numUsers; userNum++) { 3534 int userId = users.get(userNum).getUserHandle().getIdentifier(); 3535 3536 int unlockKeyguardEnabled = Settings.Secure.getIntForUser( 3537 mContext.getContentResolver(), 3538 Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED, 1, userId); 3539 int unlockDismissesKeyguard = Settings.Secure.getIntForUser( 3540 mContext.getContentResolver(), 3541 Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, 1, userId); 3542 int unlockAttentionRequired = Settings.Secure.getIntForUser( 3543 mContext.getContentResolver(), 3544 Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED, 0, userId); 3545 int unlockAppEnabled = Settings.Secure.getIntForUser( 3546 mContext.getContentResolver(), 3547 Settings.Secure.FACE_UNLOCK_APP_ENABLED, 1, userId); 3548 int unlockAlwaysRequireConfirmation = Settings.Secure.getIntForUser( 3549 mContext.getContentResolver(), 3550 Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, 0, userId); 3551 int unlockDiversityRequired = Settings.Secure.getIntForUser( 3552 mContext.getContentResolver(), 3553 Settings.Secure.FACE_UNLOCK_DIVERSITY_REQUIRED, 1, userId); 3554 3555 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, 3556 unlockKeyguardEnabled != 0, unlockDismissesKeyguard != 0, 3557 unlockAttentionRequired != 0, unlockAppEnabled != 0, 3558 unlockAlwaysRequireConfirmation != 0, unlockDiversityRequired != 0)); 3559 } 3560 } finally { 3561 Binder.restoreCallingIdentity(callingToken); 3562 } 3563 return StatsManager.PULL_SUCCESS; 3564 } 3565 3566 private void registerAppOps() { 3567 int tagId = FrameworkStatsLog.APP_OPS; 3568 mStatsManager.setPullAtomCallback( 3569 tagId, 3570 null, // use default PullAtomMetadata values 3571 DIRECT_EXECUTOR, 3572 mStatsCallbackImpl 3573 ); 3574 } 3575 3576 private void registerRuntimeAppOpAccessMessage() { 3577 int tagId = FrameworkStatsLog.RUNTIME_APP_OP_ACCESS; 3578 mStatsManager.setPullAtomCallback( 3579 tagId, 3580 null, // use default PullAtomMetadata values 3581 DIRECT_EXECUTOR, 3582 mStatsCallbackImpl 3583 ); 3584 } 3585 3586 private class AppOpEntry { 3587 public final String mPackageName; 3588 public final String mAttributionTag; 3589 public final int mUid; 3590 public final HistoricalOp mOp; 3591 public final int mHash; 3592 3593 AppOpEntry(String packageName, @Nullable String attributionTag, HistoricalOp op, int uid) { 3594 mPackageName = packageName; 3595 mAttributionTag = attributionTag; 3596 mUid = uid; 3597 mOp = op; 3598 mHash = ((packageName.hashCode() + RANDOM_SEED) & 0x7fffffff) % 100; 3599 } 3600 } 3601 3602 int pullAppOpsLocked(int atomTag, List<StatsEvent> pulledData) { 3603 final long token = Binder.clearCallingIdentity(); 3604 try { 3605 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class); 3606 3607 CompletableFuture<HistoricalOps> ops = new CompletableFuture<>(); 3608 HistoricalOpsRequest histOpsRequest = new HistoricalOpsRequest.Builder(0, 3609 Long.MAX_VALUE).setFlags(OP_FLAGS_PULLED).build(); 3610 appOps.getHistoricalOps(histOpsRequest, AsyncTask.THREAD_POOL_EXECUTOR, ops::complete); 3611 HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS, 3612 TimeUnit.MILLISECONDS); 3613 3614 List<AppOpEntry> opsList = processHistoricalOps(histOps, atomTag, 100); 3615 int samplingRate = sampleAppOps(pulledData, opsList, atomTag, 100); 3616 if (samplingRate != 100) { 3617 Slog.e(TAG, "Atom 10060 downsampled - too many dimensions"); 3618 } 3619 } catch (Throwable t) { 3620 // TODO: catch exceptions at a more granular level 3621 Slog.e(TAG, "Could not read appops", t); 3622 return StatsManager.PULL_SKIP; 3623 } finally { 3624 Binder.restoreCallingIdentity(token); 3625 } 3626 return StatsManager.PULL_SUCCESS; 3627 } 3628 3629 private int sampleAppOps(List<StatsEvent> pulledData, List<AppOpEntry> opsList, int atomTag, 3630 int samplingRate) { 3631 int nOps = opsList.size(); 3632 for (int i = 0; i < nOps; i++) { 3633 AppOpEntry entry = opsList.get(i); 3634 if (entry.mHash >= samplingRate) { 3635 continue; 3636 } 3637 StatsEvent e; 3638 if (atomTag == FrameworkStatsLog.ATTRIBUTED_APP_OPS) { 3639 e = FrameworkStatsLog.buildStatsEvent(atomTag, entry.mUid, entry.mPackageName, 3640 entry.mAttributionTag, entry.mOp.getOpCode(), 3641 entry.mOp.getForegroundAccessCount(OP_FLAGS_PULLED), 3642 entry.mOp.getBackgroundAccessCount(OP_FLAGS_PULLED), 3643 entry.mOp.getForegroundRejectCount(OP_FLAGS_PULLED), 3644 entry.mOp.getBackgroundRejectCount(OP_FLAGS_PULLED), 3645 entry.mOp.getForegroundAccessDuration(OP_FLAGS_PULLED), 3646 entry.mOp.getBackgroundAccessDuration(OP_FLAGS_PULLED), 3647 mDangerousAppOpsList.contains(entry.mOp.getOpCode()), samplingRate); 3648 } else { 3649 // AppOps atom. 3650 e = FrameworkStatsLog.buildStatsEvent(atomTag, entry.mUid, entry.mPackageName, 3651 entry.mOp.getOpCode(), entry.mOp.getForegroundAccessCount(OP_FLAGS_PULLED), 3652 entry.mOp.getBackgroundAccessCount(OP_FLAGS_PULLED), 3653 entry.mOp.getForegroundRejectCount(OP_FLAGS_PULLED), 3654 entry.mOp.getBackgroundRejectCount(OP_FLAGS_PULLED), 3655 entry.mOp.getForegroundAccessDuration(OP_FLAGS_PULLED), 3656 entry.mOp.getBackgroundAccessDuration(OP_FLAGS_PULLED), 3657 mDangerousAppOpsList.contains(entry.mOp.getOpCode())); 3658 } 3659 pulledData.add(e); 3660 } 3661 if (pulledData.size() > DIMENSION_KEY_SIZE_HARD_LIMIT) { 3662 int adjustedSamplingRate = constrain( 3663 samplingRate * DIMENSION_KEY_SIZE_SOFT_LIMIT / pulledData.size(), 0, 3664 samplingRate - 1); 3665 pulledData.clear(); 3666 return sampleAppOps(pulledData, opsList, atomTag, adjustedSamplingRate); 3667 } 3668 return samplingRate; 3669 } 3670 3671 private void registerAttributedAppOps() { 3672 int tagId = FrameworkStatsLog.ATTRIBUTED_APP_OPS; 3673 mStatsManager.setPullAtomCallback( 3674 tagId, 3675 null, // use default PullAtomMetadata values 3676 DIRECT_EXECUTOR, 3677 mStatsCallbackImpl 3678 ); 3679 } 3680 3681 int pullAttributedAppOpsLocked(int atomTag, List<StatsEvent> pulledData) { 3682 final long token = Binder.clearCallingIdentity(); 3683 try { 3684 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class); 3685 CompletableFuture<HistoricalOps> ops = new CompletableFuture<>(); 3686 HistoricalOpsRequest histOpsRequest = 3687 new HistoricalOpsRequest.Builder(0, Long.MAX_VALUE).setFlags( 3688 OP_FLAGS_PULLED).build(); 3689 3690 appOps.getHistoricalOps(histOpsRequest, AsyncTask.THREAD_POOL_EXECUTOR, ops::complete); 3691 HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS, 3692 TimeUnit.MILLISECONDS); 3693 3694 if (mAppOpsSamplingRate == 0) { 3695 mContext.getMainThreadHandler().postDelayed(new Runnable() { 3696 @Override 3697 public void run() { 3698 try { 3699 estimateAppOpsSamplingRate(); 3700 } catch (Throwable e) { 3701 Slog.e(TAG, "AppOps sampling ratio estimation failed: ", e); 3702 synchronized (mAttributedAppOpsLock) { 3703 mAppOpsSamplingRate = min(mAppOpsSamplingRate, 10); 3704 } 3705 } 3706 } 3707 }, APP_OPS_SAMPLING_INITIALIZATION_DELAY_MILLIS); 3708 mAppOpsSamplingRate = 100; 3709 } 3710 3711 List<AppOpEntry> opsList = 3712 processHistoricalOps(histOps, atomTag, mAppOpsSamplingRate); 3713 3714 int newSamplingRate = sampleAppOps(pulledData, opsList, atomTag, mAppOpsSamplingRate); 3715 3716 mAppOpsSamplingRate = min(mAppOpsSamplingRate, newSamplingRate); 3717 } catch (Throwable t) { 3718 // TODO: catch exceptions at a more granular level 3719 Slog.e(TAG, "Could not read appops", t); 3720 return StatsManager.PULL_SKIP; 3721 } finally { 3722 Binder.restoreCallingIdentity(token); 3723 } 3724 return StatsManager.PULL_SUCCESS; 3725 } 3726 3727 private void estimateAppOpsSamplingRate() throws Exception { 3728 int appOpsTargetCollectionSize = DeviceConfig.getInt( 3729 DeviceConfig.NAMESPACE_PERMISSIONS, APP_OPS_TARGET_COLLECTION_SIZE, 3730 APP_OPS_SIZE_ESTIMATE); 3731 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class); 3732 3733 CompletableFuture<HistoricalOps> ops = new CompletableFuture<>(); 3734 HistoricalOpsRequest histOpsRequest = 3735 new HistoricalOpsRequest.Builder( 3736 Math.max(Instant.now().minus(1, ChronoUnit.DAYS).toEpochMilli(), 0), 3737 Long.MAX_VALUE).setFlags( 3738 OP_FLAGS_PULLED).build(); 3739 appOps.getHistoricalOps(histOpsRequest, AsyncTask.THREAD_POOL_EXECUTOR, ops::complete); 3740 HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS, 3741 TimeUnit.MILLISECONDS); 3742 List<AppOpEntry> opsList = 3743 processHistoricalOps(histOps, FrameworkStatsLog.ATTRIBUTED_APP_OPS, 100); 3744 3745 long estimatedSize = 0; 3746 int nOps = opsList.size(); 3747 for (int i = 0; i < nOps; i++) { 3748 AppOpEntry entry = opsList.get(i); 3749 estimatedSize += 32 + entry.mPackageName.length() + (entry.mAttributionTag == null ? 1 3750 : entry.mAttributionTag.length()); 3751 3752 } 3753 int estimatedSamplingRate = (int) constrain( 3754 appOpsTargetCollectionSize * 100 / estimatedSize, 0, 100); 3755 synchronized (mAttributedAppOpsLock) { 3756 mAppOpsSamplingRate = min(mAppOpsSamplingRate, estimatedSamplingRate); 3757 } 3758 } 3759 3760 private List<AppOpEntry> processHistoricalOps( 3761 HistoricalOps histOps, int atomTag, int samplingRatio) { 3762 List<AppOpEntry> opsList = new ArrayList<>(); 3763 for (int uidIdx = 0; uidIdx < histOps.getUidCount(); uidIdx++) { 3764 final HistoricalUidOps uidOps = histOps.getUidOpsAt(uidIdx); 3765 final int uid = uidOps.getUid(); 3766 for (int pkgIdx = 0; pkgIdx < uidOps.getPackageCount(); pkgIdx++) { 3767 final HistoricalPackageOps packageOps = uidOps.getPackageOpsAt(pkgIdx); 3768 if (atomTag == FrameworkStatsLog.ATTRIBUTED_APP_OPS) { 3769 for (int attributionIdx = 0; 3770 attributionIdx < packageOps.getAttributedOpsCount(); attributionIdx++) { 3771 final AppOpsManager.AttributedHistoricalOps attributedOps = 3772 packageOps.getAttributedOpsAt(attributionIdx); 3773 for (int opIdx = 0; opIdx < attributedOps.getOpCount(); opIdx++) { 3774 final AppOpsManager.HistoricalOp op = attributedOps.getOpAt(opIdx); 3775 processHistoricalOp(op, opsList, uid, samplingRatio, 3776 packageOps.getPackageName(), attributedOps.getTag()); 3777 } 3778 } 3779 } else if (atomTag == FrameworkStatsLog.APP_OPS) { 3780 for (int opIdx = 0; opIdx < packageOps.getOpCount(); opIdx++) { 3781 final AppOpsManager.HistoricalOp op = packageOps.getOpAt(opIdx); 3782 processHistoricalOp(op, opsList, uid, samplingRatio, 3783 packageOps.getPackageName(), null); 3784 } 3785 } 3786 } 3787 } 3788 return opsList; 3789 } 3790 3791 private void processHistoricalOp(AppOpsManager.HistoricalOp op, 3792 List<AppOpEntry> opsList, int uid, int samplingRatio, String packageName, 3793 @Nullable String attributionTag) { 3794 int firstChar = 0; 3795 if (attributionTag != null && attributionTag.startsWith(packageName)) { 3796 firstChar = packageName.length(); 3797 if (firstChar < attributionTag.length() && attributionTag.charAt(firstChar) == '.') { 3798 firstChar++; 3799 } 3800 } 3801 AppOpEntry entry = new AppOpEntry(packageName, 3802 attributionTag == null ? null : attributionTag.substring(firstChar), op, 3803 uid); 3804 if (entry.mHash < samplingRatio) { 3805 opsList.add(entry); 3806 } 3807 } 3808 3809 int pullRuntimeAppOpAccessMessageLocked(int atomTag, List<StatsEvent> pulledData) { 3810 final long token = Binder.clearCallingIdentity(); 3811 try { 3812 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class); 3813 3814 RuntimeAppOpAccessMessage message = appOps.collectRuntimeAppOpAccessMessage(); 3815 if (message == null) { 3816 Slog.i(TAG, "No runtime appop access message collected"); 3817 return StatsManager.PULL_SUCCESS; 3818 } 3819 3820 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, message.getUid(), 3821 message.getPackageName(), "", 3822 message.getAttributionTag() == null ? "" : message.getAttributionTag(), 3823 message.getMessage(), message.getSamplingStrategy(), 3824 AppOpsManager.strOpToOp(message.getOp()))); 3825 } catch (Throwable t) { 3826 // TODO: catch exceptions at a more granular level 3827 Slog.e(TAG, "Could not read runtime appop access message", t); 3828 return StatsManager.PULL_SKIP; 3829 } finally { 3830 Binder.restoreCallingIdentity(token); 3831 } 3832 return StatsManager.PULL_SUCCESS; 3833 } 3834 3835 static void unpackStreamedData(int atomTag, List<StatsEvent> pulledData, 3836 List<ParcelFileDescriptor> statsFiles) throws IOException { 3837 InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(statsFiles.get(0)); 3838 int[] len = new int[1]; 3839 byte[] stats = readFully(stream, len); 3840 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, Arrays.copyOf(stats, len[0]))); 3841 } 3842 3843 static byte[] readFully(InputStream stream, int[] outLen) throws IOException { 3844 int pos = 0; 3845 final int initialAvail = stream.available(); 3846 byte[] data = new byte[initialAvail > 0 ? (initialAvail + 1) : 16384]; 3847 while (true) { 3848 int amt = stream.read(data, pos, data.length - pos); 3849 if (DEBUG) { 3850 Slog.i(TAG, "Read " + amt + " bytes at " + pos + " of avail " + data.length); 3851 } 3852 if (amt < 0) { 3853 if (DEBUG) { 3854 Slog.i(TAG, "**** FINISHED READING: pos=" + pos + " len=" + data.length); 3855 } 3856 outLen[0] = pos; 3857 return data; 3858 } 3859 pos += amt; 3860 if (pos >= data.length) { 3861 byte[] newData = new byte[pos + 16384]; 3862 if (DEBUG) { 3863 Slog.i(TAG, "Copying " + pos + " bytes to new array len " + newData.length); 3864 } 3865 System.arraycopy(data, 0, newData, 0, pos); 3866 data = newData; 3867 } 3868 } 3869 } 3870 3871 private void registerNotificationRemoteViews() { 3872 int tagId = FrameworkStatsLog.NOTIFICATION_REMOTE_VIEWS; 3873 mStatsManager.setPullAtomCallback( 3874 tagId, 3875 null, // use default PullAtomMetadata values 3876 DIRECT_EXECUTOR, 3877 mStatsCallbackImpl 3878 ); 3879 } 3880 3881 int pullNotificationRemoteViewsLocked(int atomTag, List<StatsEvent> pulledData) { 3882 INotificationManager notificationManagerService = getINotificationManagerService(); 3883 if (notificationManagerService == null) { 3884 return StatsManager.PULL_SKIP; 3885 } 3886 final long callingToken = Binder.clearCallingIdentity(); 3887 try { 3888 // determine last pull tine. Copy file trick from pullProcStats? 3889 long wallClockNanos = SystemClock.currentTimeMicro() * 1000L; 3890 long lastNotificationStatsNs = wallClockNanos - 3891 TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS); 3892 3893 List<ParcelFileDescriptor> statsFiles = new ArrayList<>(); 3894 notificationManagerService.pullStats(lastNotificationStatsNs, 3895 NotificationManagerService.REPORT_REMOTE_VIEWS, true, statsFiles); 3896 if (statsFiles.size() != 1) { 3897 return StatsManager.PULL_SKIP; 3898 } 3899 unpackStreamedData(atomTag, pulledData, statsFiles); 3900 } catch (IOException e) { 3901 Slog.e(TAG, "Getting notistats failed: ", e); 3902 return StatsManager.PULL_SKIP; 3903 } catch (RemoteException e) { 3904 Slog.e(TAG, "Getting notistats failed: ", e); 3905 return StatsManager.PULL_SKIP; 3906 } catch (SecurityException e) { 3907 Slog.e(TAG, "Getting notistats failed: ", e); 3908 return StatsManager.PULL_SKIP; 3909 } finally { 3910 Binder.restoreCallingIdentity(callingToken); 3911 } 3912 return StatsManager.PULL_SUCCESS; 3913 } 3914 3915 private void registerDangerousPermissionStateSampled() { 3916 int tagId = FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED; 3917 mStatsManager.setPullAtomCallback( 3918 tagId, 3919 null, // use default PullAtomMetadata values 3920 DIRECT_EXECUTOR, 3921 mStatsCallbackImpl 3922 ); 3923 } 3924 3925 private void registerBatteryLevel() { 3926 int tagId = FrameworkStatsLog.BATTERY_LEVEL; 3927 mStatsManager.setPullAtomCallback( 3928 tagId, 3929 null, // use default PullAtomMetadata values 3930 DIRECT_EXECUTOR, 3931 mStatsCallbackImpl 3932 ); 3933 } 3934 3935 private void registerRemainingBatteryCapacity() { 3936 int tagId = FrameworkStatsLog.REMAINING_BATTERY_CAPACITY; 3937 mStatsManager.setPullAtomCallback( 3938 tagId, 3939 null, // use default PullAtomMetadata values 3940 DIRECT_EXECUTOR, 3941 mStatsCallbackImpl 3942 ); 3943 } 3944 3945 private void registerFullBatteryCapacity() { 3946 int tagId = FrameworkStatsLog.FULL_BATTERY_CAPACITY; 3947 mStatsManager.setPullAtomCallback( 3948 tagId, 3949 null, // use default PullAtomMetadata values 3950 DIRECT_EXECUTOR, 3951 mStatsCallbackImpl 3952 ); 3953 } 3954 3955 private void registerBatteryVoltage() { 3956 int tagId = FrameworkStatsLog.BATTERY_VOLTAGE; 3957 mStatsManager.setPullAtomCallback( 3958 tagId, 3959 null, // use default PullAtomMetadata values 3960 DIRECT_EXECUTOR, 3961 mStatsCallbackImpl 3962 ); 3963 } 3964 3965 private void registerBatteryCycleCount() { 3966 int tagId = FrameworkStatsLog.BATTERY_CYCLE_COUNT; 3967 mStatsManager.setPullAtomCallback( 3968 tagId, 3969 null, // use default PullAtomMetadata values 3970 DIRECT_EXECUTOR, 3971 mStatsCallbackImpl 3972 ); 3973 } 3974 3975 int pullHealthHalLocked(int atomTag, List<StatsEvent> pulledData) { 3976 IHealth healthService = mHealthService.getLastService(); 3977 if (healthService == null) { 3978 return StatsManager.PULL_SKIP; 3979 } 3980 try { 3981 healthService.getHealthInfo((result, value) -> { 3982 int pulledValue; 3983 switch(atomTag) { 3984 case FrameworkStatsLog.BATTERY_LEVEL: 3985 pulledValue = value.legacy.batteryLevel; 3986 break; 3987 case FrameworkStatsLog.REMAINING_BATTERY_CAPACITY: 3988 pulledValue = value.legacy.batteryChargeCounter; 3989 break; 3990 case FrameworkStatsLog.FULL_BATTERY_CAPACITY: 3991 pulledValue = value.legacy.batteryFullCharge; 3992 break; 3993 case FrameworkStatsLog.BATTERY_VOLTAGE: 3994 pulledValue = value.legacy.batteryVoltage; 3995 break; 3996 case FrameworkStatsLog.BATTERY_CYCLE_COUNT: 3997 pulledValue = value.legacy.batteryCycleCount; 3998 break; 3999 default: 4000 throw new IllegalStateException("Invalid atomTag in healthHal puller: " 4001 + atomTag); 4002 } 4003 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, pulledValue)); 4004 }); 4005 } catch (RemoteException | IllegalStateException e) { 4006 return StatsManager.PULL_SKIP; 4007 } 4008 return StatsManager.PULL_SUCCESS; 4009 } 4010 4011 private void registerSettingsStats() { 4012 int tagId = FrameworkStatsLog.SETTING_SNAPSHOT; 4013 mStatsManager.setPullAtomCallback( 4014 tagId, 4015 null, // use default PullAtomMetadata values 4016 DIRECT_EXECUTOR, 4017 mStatsCallbackImpl 4018 ); 4019 } 4020 4021 int pullSettingsStatsLocked(int atomTag, List<StatsEvent> pulledData) { 4022 UserManager userManager = mContext.getSystemService(UserManager.class); 4023 if (userManager == null) { 4024 return StatsManager.PULL_SKIP; 4025 } 4026 4027 final long token = Binder.clearCallingIdentity(); 4028 try { 4029 for (UserInfo user : userManager.getUsers()) { 4030 final int userId = user.getUserHandle().getIdentifier(); 4031 4032 if (userId == UserHandle.USER_SYSTEM) { 4033 pulledData.addAll(SettingsStatsUtil.logGlobalSettings(mContext, atomTag, 4034 UserHandle.USER_SYSTEM)); 4035 } 4036 pulledData.addAll(SettingsStatsUtil.logSystemSettings(mContext, atomTag, userId)); 4037 pulledData.addAll(SettingsStatsUtil.logSecureSettings(mContext, atomTag, userId)); 4038 } 4039 } catch (Exception e) { 4040 Slog.e(TAG, "failed to pullSettingsStats", e); 4041 return StatsManager.PULL_SKIP; 4042 } finally { 4043 Binder.restoreCallingIdentity(token); 4044 } 4045 return StatsManager.PULL_SUCCESS; 4046 } 4047 4048 private void registerInstalledIncrementalPackages() { 4049 int tagId = FrameworkStatsLog.INSTALLED_INCREMENTAL_PACKAGE; 4050 mStatsManager.setPullAtomCallback( 4051 tagId, 4052 null, // use default PullAtomMetadata values 4053 DIRECT_EXECUTOR, 4054 mStatsCallbackImpl 4055 ); 4056 } 4057 4058 int pullInstalledIncrementalPackagesLocked(int atomTag, List<StatsEvent> pulledData) { 4059 final PackageManager pm = mContext.getPackageManager(); 4060 if (!pm.hasSystemFeature(PackageManager.FEATURE_INCREMENTAL_DELIVERY)) { 4061 // Incremental is not enabled on this device. The result list will be empty. 4062 return StatsManager.PULL_SUCCESS; 4063 } 4064 List<PackageInfo> installedPackages = pm.getInstalledPackages(0); 4065 for (PackageInfo pi : installedPackages) { 4066 if (IncrementalManager.isIncrementalPath(pi.applicationInfo.getBaseCodePath())) { 4067 pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, pi.applicationInfo.uid)); 4068 } 4069 } 4070 return StatsManager.PULL_SUCCESS; 4071 } 4072 4073 private void registerKeystoreStorageStats() { 4074 mStatsManager.setPullAtomCallback( 4075 FrameworkStatsLog.KEYSTORE2_STORAGE_STATS, 4076 null, // use default PullAtomMetadata values, 4077 DIRECT_EXECUTOR, 4078 mStatsCallbackImpl); 4079 } 4080 4081 private void registerRkpPoolStats() { 4082 mStatsManager.setPullAtomCallback( 4083 FrameworkStatsLog.RKP_POOL_STATS, 4084 null, // use default PullAtomMetadata values, 4085 DIRECT_EXECUTOR, 4086 mStatsCallbackImpl); 4087 } 4088 4089 private void registerKeystoreKeyCreationWithGeneralInfo() { 4090 mStatsManager.setPullAtomCallback( 4091 FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_GENERAL_INFO, 4092 null, // use default PullAtomMetadata values, 4093 DIRECT_EXECUTOR, 4094 mStatsCallbackImpl); 4095 } 4096 4097 private void registerKeystoreKeyCreationWithAuthInfo() { 4098 mStatsManager.setPullAtomCallback( 4099 FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_AUTH_INFO, 4100 null, // use default PullAtomMetadata values, 4101 DIRECT_EXECUTOR, 4102 mStatsCallbackImpl); 4103 } 4104 4105 private void registerKeystoreKeyCreationWithPurposeModesInfo() { 4106 mStatsManager.setPullAtomCallback( 4107 FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO, 4108 null, // use default PullAtomMetadata values, 4109 DIRECT_EXECUTOR, 4110 mStatsCallbackImpl); 4111 } 4112 4113 private void registerKeystoreAtomWithOverflow() { 4114 mStatsManager.setPullAtomCallback( 4115 FrameworkStatsLog.KEYSTORE2_ATOM_WITH_OVERFLOW, 4116 null, // use default PullAtomMetadata values, 4117 DIRECT_EXECUTOR, 4118 mStatsCallbackImpl); 4119 } 4120 4121 private void registerKeystoreKeyOperationWithPurposeAndModesInfo() { 4122 mStatsManager.setPullAtomCallback( 4123 FrameworkStatsLog.KEYSTORE2_KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO, 4124 null, // use default PullAtomMetadata values, 4125 DIRECT_EXECUTOR, 4126 mStatsCallbackImpl); 4127 } 4128 4129 private void registerKeystoreKeyOperationWithGeneralInfo() { 4130 mStatsManager.setPullAtomCallback( 4131 FrameworkStatsLog.KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO, 4132 null, // use default PullAtomMetadata values, 4133 DIRECT_EXECUTOR, 4134 mStatsCallbackImpl); 4135 } 4136 4137 private void registerRkpErrorStats() { 4138 mStatsManager.setPullAtomCallback( 4139 FrameworkStatsLog.RKP_ERROR_STATS, 4140 null, // use default PullAtomMetadata values, 4141 DIRECT_EXECUTOR, 4142 mStatsCallbackImpl); 4143 } 4144 4145 private void registerKeystoreCrashStats() { 4146 mStatsManager.setPullAtomCallback( 4147 FrameworkStatsLog.KEYSTORE2_CRASH_STATS, 4148 null, // use default PullAtomMetadata values, 4149 DIRECT_EXECUTOR, 4150 mStatsCallbackImpl); 4151 } 4152 4153 int parseKeystoreStorageStats(KeystoreAtom[] atoms, List<StatsEvent> pulledData) { 4154 for (KeystoreAtom atomWrapper : atoms) { 4155 if (atomWrapper.payload.getTag() != KeystoreAtomPayload.storageStats) { 4156 return StatsManager.PULL_SKIP; 4157 } 4158 StorageStats atom = atomWrapper.payload.getStorageStats(); 4159 pulledData.add(FrameworkStatsLog.buildStatsEvent( 4160 FrameworkStatsLog.KEYSTORE2_STORAGE_STATS, atom.storage_type, 4161 atom.size, atom.unused_size)); 4162 } 4163 return StatsManager.PULL_SUCCESS; 4164 } 4165 4166 int parseRkpPoolStats(KeystoreAtom[] atoms, List<StatsEvent> pulledData) { 4167 for (KeystoreAtom atomWrapper : atoms) { 4168 if (atomWrapper.payload.getTag() != KeystoreAtomPayload.rkpPoolStats) { 4169 return StatsManager.PULL_SKIP; 4170 } 4171 RkpPoolStats atom = atomWrapper.payload.getRkpPoolStats(); 4172 pulledData.add(FrameworkStatsLog.buildStatsEvent( 4173 FrameworkStatsLog.RKP_POOL_STATS, atom.security_level, atom.expiring, 4174 atom.unassigned, atom.attested, atom.total)); 4175 } 4176 return StatsManager.PULL_SUCCESS; 4177 } 4178 4179 int parseKeystoreKeyCreationWithGeneralInfo(KeystoreAtom[] atoms, List<StatsEvent> pulledData) { 4180 for (KeystoreAtom atomWrapper : atoms) { 4181 if (atomWrapper.payload.getTag() 4182 != KeystoreAtomPayload.keyCreationWithGeneralInfo) { 4183 return StatsManager.PULL_SKIP; 4184 } 4185 KeyCreationWithGeneralInfo atom = atomWrapper.payload.getKeyCreationWithGeneralInfo(); 4186 pulledData.add(FrameworkStatsLog.buildStatsEvent( 4187 FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_GENERAL_INFO, atom.algorithm, 4188 atom.key_size, atom.ec_curve, atom.key_origin, atom.error_code, 4189 atom.attestation_requested, atomWrapper.count)); 4190 } 4191 return StatsManager.PULL_SUCCESS; 4192 } 4193 4194 int parseKeystoreKeyCreationWithAuthInfo(KeystoreAtom[] atoms, List<StatsEvent> pulledData) { 4195 for (KeystoreAtom atomWrapper : atoms) { 4196 if (atomWrapper.payload.getTag() != KeystoreAtomPayload.keyCreationWithAuthInfo) { 4197 return StatsManager.PULL_SKIP; 4198 } 4199 KeyCreationWithAuthInfo atom = atomWrapper.payload.getKeyCreationWithAuthInfo(); 4200 pulledData.add(FrameworkStatsLog.buildStatsEvent( 4201 FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_AUTH_INFO, atom.user_auth_type, 4202 atom.log10_auth_key_timeout_seconds, atom.security_level, atomWrapper.count)); 4203 } 4204 return StatsManager.PULL_SUCCESS; 4205 } 4206 4207 4208 int parseKeystoreKeyCreationWithPurposeModesInfo(KeystoreAtom[] atoms, 4209 List<StatsEvent> pulledData) { 4210 for (KeystoreAtom atomWrapper : atoms) { 4211 if (atomWrapper.payload.getTag() 4212 != KeystoreAtomPayload.keyCreationWithPurposeAndModesInfo) { 4213 return StatsManager.PULL_SKIP; 4214 } 4215 KeyCreationWithPurposeAndModesInfo atom = 4216 atomWrapper.payload.getKeyCreationWithPurposeAndModesInfo(); 4217 pulledData.add(FrameworkStatsLog.buildStatsEvent( 4218 FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO, 4219 atom.algorithm, atom.purpose_bitmap, 4220 atom.padding_mode_bitmap, atom.digest_bitmap, atom.block_mode_bitmap, 4221 atomWrapper.count)); 4222 } 4223 return StatsManager.PULL_SUCCESS; 4224 } 4225 4226 int parseKeystoreAtomWithOverflow(KeystoreAtom[] atoms, List<StatsEvent> pulledData) { 4227 for (KeystoreAtom atomWrapper : atoms) { 4228 if (atomWrapper.payload.getTag() 4229 != KeystoreAtomPayload.keystore2AtomWithOverflow) { 4230 return StatsManager.PULL_SKIP; 4231 } 4232 Keystore2AtomWithOverflow atom = atomWrapper.payload.getKeystore2AtomWithOverflow(); 4233 pulledData.add(FrameworkStatsLog.buildStatsEvent( 4234 FrameworkStatsLog.KEYSTORE2_ATOM_WITH_OVERFLOW, atom.atom_id, 4235 atomWrapper.count)); 4236 } 4237 return StatsManager.PULL_SUCCESS; 4238 } 4239 4240 int parseKeystoreKeyOperationWithPurposeModesInfo(KeystoreAtom[] atoms, 4241 List<StatsEvent> pulledData) { 4242 for (KeystoreAtom atomWrapper : atoms) { 4243 if (atomWrapper.payload.getTag() 4244 != KeystoreAtomPayload.keyOperationWithPurposeAndModesInfo) { 4245 return StatsManager.PULL_SKIP; 4246 } 4247 KeyOperationWithPurposeAndModesInfo atom = 4248 atomWrapper.payload.getKeyOperationWithPurposeAndModesInfo(); 4249 pulledData.add(FrameworkStatsLog.buildStatsEvent( 4250 FrameworkStatsLog.KEYSTORE2_KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO, 4251 atom.purpose, atom.padding_mode_bitmap, atom.digest_bitmap, 4252 atom.block_mode_bitmap, atomWrapper.count)); 4253 } 4254 return StatsManager.PULL_SUCCESS; 4255 } 4256 4257 int parseKeystoreKeyOperationWithGeneralInfo(KeystoreAtom[] atoms, 4258 List<StatsEvent> pulledData) { 4259 for (KeystoreAtom atomWrapper : atoms) { 4260 if (atomWrapper.payload.getTag() 4261 != KeystoreAtomPayload.keyOperationWithGeneralInfo) { 4262 return StatsManager.PULL_SKIP; 4263 } 4264 KeyOperationWithGeneralInfo atom = atomWrapper.payload.getKeyOperationWithGeneralInfo(); 4265 pulledData.add(FrameworkStatsLog.buildStatsEvent( 4266 FrameworkStatsLog.KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO, atom.outcome, 4267 atom.error_code, atom.key_upgraded, atom.security_level, atomWrapper.count)); 4268 } 4269 return StatsManager.PULL_SUCCESS; 4270 } 4271 4272 int parseRkpErrorStats(KeystoreAtom[] atoms, 4273 List<StatsEvent> pulledData) { 4274 for (KeystoreAtom atomWrapper : atoms) { 4275 if (atomWrapper.payload.getTag() != KeystoreAtomPayload.rkpErrorStats) { 4276 return StatsManager.PULL_SKIP; 4277 } 4278 RkpErrorStats atom = atomWrapper.payload.getRkpErrorStats(); 4279 pulledData.add(FrameworkStatsLog.buildStatsEvent( 4280 FrameworkStatsLog.RKP_ERROR_STATS, atom.rkpError, atomWrapper.count)); 4281 } 4282 return StatsManager.PULL_SUCCESS; 4283 } 4284 4285 int parseKeystoreCrashStats(KeystoreAtom[] atoms, 4286 List<StatsEvent> pulledData) { 4287 for (KeystoreAtom atomWrapper : atoms) { 4288 if (atomWrapper.payload.getTag() != KeystoreAtomPayload.crashStats) { 4289 return StatsManager.PULL_SKIP; 4290 } 4291 CrashStats atom = atomWrapper.payload.getCrashStats(); 4292 pulledData.add(FrameworkStatsLog.buildStatsEvent( 4293 FrameworkStatsLog.KEYSTORE2_CRASH_STATS, atom.count_of_crash_events)); 4294 } 4295 return StatsManager.PULL_SUCCESS; 4296 } 4297 4298 int pullKeystoreAtoms(int atomTag, List<StatsEvent> pulledData) { 4299 IKeystoreMetrics keystoreMetricsService = getIKeystoreMetricsService(); 4300 if (keystoreMetricsService == null) { 4301 Slog.w(TAG, "Keystore service is null"); 4302 return StatsManager.PULL_SKIP; 4303 } 4304 final long callingToken = Binder.clearCallingIdentity(); 4305 try { 4306 KeystoreAtom[] atoms = keystoreMetricsService.pullMetrics(atomTag); 4307 switch (atomTag) { 4308 case FrameworkStatsLog.KEYSTORE2_STORAGE_STATS: 4309 return parseKeystoreStorageStats(atoms, pulledData); 4310 case FrameworkStatsLog.RKP_POOL_STATS: 4311 return parseRkpPoolStats(atoms, pulledData); 4312 case FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_GENERAL_INFO: 4313 return parseKeystoreKeyCreationWithGeneralInfo(atoms, pulledData); 4314 case FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_AUTH_INFO: 4315 return parseKeystoreKeyCreationWithAuthInfo(atoms, pulledData); 4316 case FrameworkStatsLog.KEYSTORE2_KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO: 4317 return parseKeystoreKeyCreationWithPurposeModesInfo(atoms, pulledData); 4318 case FrameworkStatsLog.KEYSTORE2_ATOM_WITH_OVERFLOW: 4319 return parseKeystoreAtomWithOverflow(atoms, pulledData); 4320 case FrameworkStatsLog.KEYSTORE2_KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO: 4321 return parseKeystoreKeyOperationWithPurposeModesInfo(atoms, pulledData); 4322 case FrameworkStatsLog.KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO: 4323 return parseKeystoreKeyOperationWithGeneralInfo(atoms, pulledData); 4324 case FrameworkStatsLog.RKP_ERROR_STATS: 4325 return parseRkpErrorStats(atoms, pulledData); 4326 case FrameworkStatsLog.KEYSTORE2_CRASH_STATS: 4327 return parseKeystoreCrashStats(atoms, pulledData); 4328 default: 4329 Slog.w(TAG, "Unsupported keystore atom: " + atomTag); 4330 return StatsManager.PULL_SKIP; 4331 } 4332 } catch (RemoteException e) { 4333 // Should not happen. 4334 Slog.e(TAG, "Disconnected from keystore service. Cannot pull.", e); 4335 return StatsManager.PULL_SKIP; 4336 } catch (ServiceSpecificException e) { 4337 Slog.e(TAG, "pulling keystore metrics failed", e); 4338 return StatsManager.PULL_SKIP; 4339 } finally { 4340 Binder.restoreCallingIdentity(callingToken); 4341 } 4342 } 4343 4344 // Thermal event received from vendor thermal management subsystem 4345 private static final class ThermalEventListener extends IThermalEventListener.Stub { 4346 @Override 4347 public void notifyThrottling(Temperature temp) { 4348 FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_THROTTLING_SEVERITY_STATE_CHANGED, 4349 temp.getType(), temp.getName(), (int) (temp.getValue() * 10), temp.getStatus()); 4350 } 4351 } 4352 4353 private static final class ConnectivityStatsCallback extends 4354 ConnectivityManager.NetworkCallback { 4355 @Override 4356 public void onAvailable(Network network) { 4357 FrameworkStatsLog.write(FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED, 4358 network.getNetId(), 4359 FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED__STATE__CONNECTED); 4360 } 4361 4362 @Override 4363 public void onLost(Network network) { 4364 FrameworkStatsLog.write(FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED, 4365 network.getNetId(), 4366 FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED__STATE__DISCONNECTED); 4367 } 4368 } 4369 4370 private final class StatsSubscriptionsListener 4371 extends SubscriptionManager.OnSubscriptionsChangedListener { 4372 @NonNull 4373 private final SubscriptionManager mSm; 4374 4375 StatsSubscriptionsListener(@NonNull SubscriptionManager sm) { 4376 mSm = sm; 4377 } 4378 4379 @Override 4380 public void onSubscriptionsChanged() { 4381 final List<SubscriptionInfo> currentSubs = mSm.getCompleteActiveSubscriptionInfoList(); 4382 for (final SubscriptionInfo sub : currentSubs) { 4383 final SubInfo match = CollectionUtils.find(mHistoricalSubs, 4384 (SubInfo it) -> it.subId == sub.getSubscriptionId()); 4385 // SubInfo exists, ignore. 4386 if (match != null) continue; 4387 4388 // Ignore if no valid mcc, mnc, imsi, carrierId. 4389 final int subId = sub.getSubscriptionId(); 4390 final String mcc = sub.getMccString(); 4391 final String mnc = sub.getMncString(); 4392 final String subscriberId = mTelephony.getSubscriberId(subId); 4393 if (TextUtils.isEmpty(subscriberId) || TextUtils.isEmpty(mcc) 4394 || TextUtils.isEmpty(mnc) || sub.getCarrierId() == UNKNOWN_CARRIER_ID) { 4395 Slog.e(TAG, "subInfo of subId " + subId + " is invalid, ignored."); 4396 continue; 4397 } 4398 4399 final SubInfo subInfo = new SubInfo(subId, sub.getCarrierId(), mcc, mnc, 4400 subscriberId, sub.isOpportunistic()); 4401 Slog.i(TAG, "subId " + subId + " added into historical sub list"); 4402 4403 synchronized (mDataBytesTransferLock) { 4404 mHistoricalSubs.add(subInfo); 4405 // Since getting snapshot when pulling will also include data before boot, 4406 // query stats as baseline to prevent double count is needed. 4407 mNetworkStatsBaselines.addAll(getDataUsageBytesTransferSnapshotForSub(subInfo)); 4408 } 4409 } 4410 } 4411 } 4412 4413 } 4414