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