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