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