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