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