1 /* 2 * Copyright (C) 2017 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 package com.android.server.stats; 17 18 import static android.app.AppOpsManager.OP_FLAGS_ALL_TRUSTED; 19 import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; 20 import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS; 21 import static android.os.Process.getPidsForCommands; 22 import static android.os.Process.getUidForPid; 23 import static android.os.storage.VolumeInfo.TYPE_PRIVATE; 24 import static android.os.storage.VolumeInfo.TYPE_PUBLIC; 25 26 import static com.android.internal.util.Preconditions.checkNotNull; 27 import static com.android.server.am.MemoryStatUtil.readCmdlineFromProcfs; 28 import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem; 29 import static com.android.server.am.MemoryStatUtil.readMemoryStatFromProcfs; 30 import static com.android.server.am.MemoryStatUtil.readProcessSystemIonHeapSizesFromDebugfs; 31 import static com.android.server.am.MemoryStatUtil.readRssHighWaterMarkFromProcfs; 32 import static com.android.server.am.MemoryStatUtil.readSystemIonHeapSizeFromDebugfs; 33 34 import android.annotation.NonNull; 35 import android.annotation.Nullable; 36 import android.app.ActivityManagerInternal; 37 import android.app.AlarmManager; 38 import android.app.AlarmManager.OnAlarmListener; 39 import android.app.AppOpsManager; 40 import android.app.AppOpsManager.HistoricalOps; 41 import android.app.AppOpsManager.HistoricalOpsRequest; 42 import android.app.AppOpsManager.HistoricalPackageOps; 43 import android.app.AppOpsManager.HistoricalUidOps; 44 import android.app.ProcessMemoryState; 45 import android.app.StatsManager; 46 import android.bluetooth.BluetoothActivityEnergyInfo; 47 import android.bluetooth.BluetoothAdapter; 48 import android.bluetooth.UidTraffic; 49 import android.content.BroadcastReceiver; 50 import android.content.Context; 51 import android.content.Intent; 52 import android.content.IntentFilter; 53 import android.content.IntentSender; 54 import android.content.pm.ApplicationInfo; 55 import android.content.pm.PackageInfo; 56 import android.content.pm.PackageManager; 57 import android.content.pm.PermissionInfo; 58 import android.content.pm.UserInfo; 59 import android.hardware.biometrics.BiometricsProtoEnums; 60 import android.hardware.face.FaceManager; 61 import android.hardware.fingerprint.FingerprintManager; 62 import android.net.ConnectivityManager; 63 import android.net.INetworkStatsService; 64 import android.net.Network; 65 import android.net.NetworkRequest; 66 import android.net.NetworkStats; 67 import android.net.wifi.IWifiManager; 68 import android.net.wifi.WifiActivityEnergyInfo; 69 import android.os.BatteryStats; 70 import android.os.BatteryStatsInternal; 71 import android.os.Binder; 72 import android.os.Build; 73 import android.os.Bundle; 74 import android.os.CoolingDevice; 75 import android.os.Environment; 76 import android.os.FileUtils; 77 import android.os.Handler; 78 import android.os.HandlerThread; 79 import android.os.IBinder; 80 import android.os.IStatsCompanionService; 81 import android.os.IStatsManager; 82 import android.os.IStoraged; 83 import android.os.IThermalEventListener; 84 import android.os.IThermalService; 85 import android.os.Looper; 86 import android.os.ParcelFileDescriptor; 87 import android.os.Parcelable; 88 import android.os.Process; 89 import android.os.RemoteException; 90 import android.os.ServiceManager; 91 import android.os.StatFs; 92 import android.os.StatsDimensionsValue; 93 import android.os.StatsLogEventWrapper; 94 import android.os.SynchronousResultReceiver; 95 import android.os.SystemClock; 96 import android.os.SystemProperties; 97 import android.os.Temperature; 98 import android.os.UserHandle; 99 import android.os.UserManager; 100 import android.os.storage.DiskInfo; 101 import android.os.storage.StorageManager; 102 import android.os.storage.VolumeInfo; 103 import android.provider.Settings; 104 import android.stats.storage.StorageEnums; 105 import android.telephony.ModemActivityInfo; 106 import android.telephony.TelephonyManager; 107 import android.util.ArrayMap; 108 import android.util.ArraySet; 109 import android.util.Log; 110 import android.util.Slog; 111 import android.util.StatsLog; 112 import android.util.proto.ProtoOutputStream; 113 import android.util.proto.ProtoStream; 114 115 import com.android.internal.annotations.GuardedBy; 116 import com.android.internal.app.procstats.IProcessStats; 117 import com.android.internal.app.procstats.ProcessStats; 118 import com.android.internal.os.BackgroundThread; 119 import com.android.internal.os.BatterySipper; 120 import com.android.internal.os.BatteryStatsHelper; 121 import com.android.internal.os.BinderCallsStats.ExportedCallStat; 122 import com.android.internal.os.KernelCpuSpeedReader; 123 import com.android.internal.os.KernelCpuThreadReader; 124 import com.android.internal.os.KernelCpuThreadReaderDiff; 125 import com.android.internal.os.KernelCpuThreadReaderSettingsObserver; 126 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader; 127 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader; 128 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader; 129 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader; 130 import com.android.internal.os.KernelWakelockReader; 131 import com.android.internal.os.KernelWakelockStats; 132 import com.android.internal.os.LooperStats; 133 import com.android.internal.os.PowerProfile; 134 import com.android.internal.os.ProcessCpuTracker; 135 import com.android.internal.os.StoragedUidIoStatsReader; 136 import com.android.internal.util.DumpUtils; 137 import com.android.server.BinderCallsStatsService; 138 import com.android.server.LocalServices; 139 import com.android.server.SystemService; 140 import com.android.server.SystemServiceManager; 141 import com.android.server.am.MemoryStatUtil.IonAllocations; 142 import com.android.server.am.MemoryStatUtil.MemoryStat; 143 import com.android.server.role.RoleManagerInternal; 144 import com.android.server.storage.DiskStatsFileLogger; 145 import com.android.server.storage.DiskStatsLoggingService; 146 147 import libcore.io.IoUtils; 148 149 import org.json.JSONArray; 150 import org.json.JSONException; 151 import org.json.JSONObject; 152 153 import java.io.File; 154 import java.io.FileDescriptor; 155 import java.io.FileOutputStream; 156 import java.io.IOException; 157 import java.io.InputStream; 158 import java.io.PrintWriter; 159 import java.time.Instant; 160 import java.time.temporal.ChronoUnit; 161 import java.util.ArrayList; 162 import java.util.Arrays; 163 import java.util.HashMap; 164 import java.util.HashSet; 165 import java.util.List; 166 import java.util.Map; 167 import java.util.Map.Entry; 168 import java.util.UUID; 169 import java.util.concurrent.CompletableFuture; 170 import java.util.concurrent.TimeUnit; 171 import java.util.concurrent.TimeoutException; 172 173 /** 174 * Helper service for statsd (the native stats management service in cmds/statsd/). 175 * Used for registering and receiving alarms on behalf of statsd. 176 * 177 * @hide 178 */ 179 public class StatsCompanionService extends IStatsCompanionService.Stub { 180 /** 181 * How long to wait on an individual subsystem to return its stats. 182 */ 183 private static final long EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS = 2000; 184 private static final long MILLIS_IN_A_DAY = TimeUnit.DAYS.toMillis(1); 185 186 public static final String RESULT_RECEIVER_CONTROLLER_KEY = "controller_activity"; 187 public static final String CONFIG_DIR = "/data/misc/stats-service"; 188 189 static final String TAG = "StatsCompanionService"; 190 static final boolean DEBUG = false; 191 /** 192 * Hard coded field ids of frameworks/base/cmds/statsd/src/uid_data.proto 193 * to be used in ProtoOutputStream. 194 */ 195 private static final int APPLICATION_INFO_FIELD_ID = 1; 196 private static final int UID_FIELD_ID = 1; 197 private static final int VERSION_FIELD_ID = 2; 198 private static final int VERSION_STRING_FIELD_ID = 3; 199 private static final int PACKAGE_NAME_FIELD_ID = 4; 200 private static final int INSTALLER_FIELD_ID = 5; 201 202 public static final int CODE_DATA_BROADCAST = 1; 203 public static final int CODE_SUBSCRIBER_BROADCAST = 1; 204 public static final int CODE_ACTIVE_CONFIGS_BROADCAST = 1; 205 /** 206 * The last report time is provided with each intent registered to 207 * StatsManager#setFetchReportsOperation. This allows easy de-duping in the receiver if 208 * statsd is requesting the client to retrieve the same statsd data. The last report time 209 * corresponds to the last_report_elapsed_nanos that will provided in the current 210 * ConfigMetricsReport, and this timestamp also corresponds to the 211 * current_report_elapsed_nanos of the most recently obtained ConfigMetricsReport. 212 */ 213 public static final String EXTRA_LAST_REPORT_TIME = "android.app.extra.LAST_REPORT_TIME"; 214 public static final int DEATH_THRESHOLD = 10; 215 /** 216 * Which native processes to snapshot memory for. 217 * 218 * <p>Processes are matched by their cmdline in procfs. Example: cat /proc/pid/cmdline returns 219 * /system/bin/statsd for the stats daemon. 220 */ 221 private static final String[] MEMORY_INTERESTING_NATIVE_PROCESSES = new String[]{ 222 "/system/bin/statsd", // Stats daemon. 223 "/system/bin/surfaceflinger", 224 "/system/bin/apexd", // APEX daemon. 225 "/system/bin/audioserver", 226 "/system/bin/cameraserver", 227 "/system/bin/drmserver", 228 "/system/bin/healthd", 229 "/system/bin/incidentd", 230 "/system/bin/installd", 231 "/system/bin/lmkd", // Low memory killer daemon. 232 "/system/bin/logd", 233 "media.codec", 234 "media.extractor", 235 "media.metrics", 236 "/system/bin/mediadrmserver", 237 "/system/bin/mediaserver", 238 "/system/bin/performanced", 239 "/system/bin/tombstoned", 240 "/system/bin/traced", // Perfetto. 241 "/system/bin/traced_probes", // Perfetto. 242 "webview_zygote", 243 "zygote", 244 "zygote64", 245 }; 246 247 private static final int CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES = 8; 248 249 static final class CompanionHandler extends Handler { CompanionHandler(Looper looper)250 CompanionHandler(Looper looper) { 251 super(looper); 252 } 253 } 254 255 private final Context mContext; 256 private final AlarmManager mAlarmManager; 257 private final INetworkStatsService mNetworkStatsService; 258 @GuardedBy("sStatsdLock") 259 private static IStatsManager sStatsd; 260 private static final Object sStatsdLock = new Object(); 261 262 private final OnAlarmListener mAnomalyAlarmListener = new AnomalyAlarmListener(); 263 private final OnAlarmListener mPullingAlarmListener = new PullingAlarmListener(); 264 private final OnAlarmListener mPeriodicAlarmListener = new PeriodicAlarmListener(); 265 private final BroadcastReceiver mAppUpdateReceiver; 266 private final BroadcastReceiver mUserUpdateReceiver; 267 private final ShutdownEventReceiver mShutdownEventReceiver; 268 private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader(); 269 private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats(); 270 private IWifiManager mWifiManager = null; 271 private TelephonyManager mTelephony = null; 272 @GuardedBy("sStatsdLock") 273 private final HashSet<Long> mDeathTimeMillis = new HashSet<>(); 274 @GuardedBy("sStatsdLock") 275 private final HashMap<Long, String> mDeletedFiles = new HashMap<>(); 276 private final CompanionHandler mHandler; 277 278 // Disables throttler on CPU time readers. 279 private KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader = 280 new KernelCpuUidUserSysTimeReader(false); 281 private KernelCpuSpeedReader[] mKernelCpuSpeedReaders; 282 private KernelCpuUidFreqTimeReader mCpuUidFreqTimeReader = 283 new KernelCpuUidFreqTimeReader(false); 284 private KernelCpuUidActiveTimeReader mCpuUidActiveTimeReader = 285 new KernelCpuUidActiveTimeReader(false); 286 private KernelCpuUidClusterTimeReader mCpuUidClusterTimeReader = 287 new KernelCpuUidClusterTimeReader(false); 288 private StoragedUidIoStatsReader mStoragedUidIoStatsReader = 289 new StoragedUidIoStatsReader(); 290 @Nullable 291 private final KernelCpuThreadReaderDiff mKernelCpuThreadReader; 292 293 private long mDebugElapsedClockPreviousValue = 0; 294 private long mDebugElapsedClockPullCount = 0; 295 private long mDebugFailingElapsedClockPreviousValue = 0; 296 private long mDebugFailingElapsedClockPullCount = 0; 297 private BatteryStatsHelper mBatteryStatsHelper = null; 298 private static final int MAX_BATTERY_STATS_HELPER_FREQUENCY_MS = 1000; 299 private long mBatteryStatsHelperTimestampMs = -MAX_BATTERY_STATS_HELPER_FREQUENCY_MS; 300 301 private static IThermalService sThermalService; 302 private File mBaseDir = 303 new File(SystemServiceManager.ensureSystemDir(), "stats_companion"); 304 @GuardedBy("this") 305 ProcessCpuTracker mProcessCpuTracker = null; 306 StatsCompanionService(Context context)307 public StatsCompanionService(Context context) { 308 super(); 309 mContext = context; 310 mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); 311 mNetworkStatsService = INetworkStatsService.Stub.asInterface( 312 ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); 313 mBaseDir.mkdirs(); 314 mAppUpdateReceiver = new AppUpdateReceiver(); 315 mUserUpdateReceiver = new BroadcastReceiver() { 316 @Override 317 public void onReceive(Context context, Intent intent) { 318 synchronized (sStatsdLock) { 319 sStatsd = fetchStatsdService(); 320 if (sStatsd == null) { 321 Slog.w(TAG, "Could not access statsd for UserUpdateReceiver"); 322 return; 323 } 324 try { 325 // Pull the latest state of UID->app name, version mapping. 326 // Needed since the new user basically has a version of every app. 327 informAllUidsLocked(context); 328 } catch (RemoteException e) { 329 Slog.e(TAG, "Failed to inform statsd latest update of all apps", e); 330 forgetEverythingLocked(); 331 } 332 } 333 } 334 }; 335 mShutdownEventReceiver = new ShutdownEventReceiver(); 336 if (DEBUG) Slog.d(TAG, "Registered receiver for ACTION_PACKAGE_REPLACED and ADDED."); 337 PowerProfile powerProfile = new PowerProfile(context); 338 final int numClusters = powerProfile.getNumCpuClusters(); 339 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters]; 340 int firstCpuOfCluster = 0; 341 for (int i = 0; i < numClusters; i++) { 342 final int numSpeedSteps = powerProfile.getNumSpeedStepsInCpuCluster(i); 343 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster, 344 numSpeedSteps); 345 firstCpuOfCluster += powerProfile.getNumCoresInCpuCluster(i); 346 } 347 348 // Enable push notifications of throttling from vendor thermal 349 // management subsystem via thermalservice. 350 IBinder b = ServiceManager.getService("thermalservice"); 351 352 if (b != null) { 353 sThermalService = IThermalService.Stub.asInterface(b); 354 try { 355 sThermalService.registerThermalEventListener( 356 new ThermalEventListener()); 357 Slog.i(TAG, "register thermal listener successfully"); 358 } catch (RemoteException e) { 359 // Should never happen. 360 Slog.e(TAG, "register thermal listener error"); 361 } 362 } else { 363 Slog.e(TAG, "cannot find thermalservice, no throttling push notifications"); 364 } 365 366 // Default NetworkRequest should cover all transport types. 367 final NetworkRequest request = new NetworkRequest.Builder().build(); 368 final ConnectivityManager connectivityManager = 369 (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); 370 connectivityManager.registerNetworkCallback(request, new ConnectivityStatsCallback()); 371 372 HandlerThread handlerThread = new HandlerThread(TAG); 373 handlerThread.start(); 374 mHandler = new CompanionHandler(handlerThread.getLooper()); 375 376 mKernelCpuThreadReader = 377 KernelCpuThreadReaderSettingsObserver.getSettingsModifiedReader(mContext); 378 } 379 380 @Override sendDataBroadcast(IBinder intentSenderBinder, long lastReportTimeNs)381 public void sendDataBroadcast(IBinder intentSenderBinder, long lastReportTimeNs) { 382 enforceCallingPermission(); 383 IntentSender intentSender = new IntentSender(intentSenderBinder); 384 Intent intent = new Intent(); 385 intent.putExtra(EXTRA_LAST_REPORT_TIME, lastReportTimeNs); 386 try { 387 intentSender.sendIntent(mContext, CODE_DATA_BROADCAST, intent, null, null); 388 } catch (IntentSender.SendIntentException e) { 389 Slog.w(TAG, "Unable to send using IntentSender"); 390 } 391 } 392 393 @Override sendActiveConfigsChangedBroadcast(IBinder intentSenderBinder, long[] configIds)394 public void sendActiveConfigsChangedBroadcast(IBinder intentSenderBinder, long[] configIds) { 395 enforceCallingPermission(); 396 IntentSender intentSender = new IntentSender(intentSenderBinder); 397 Intent intent = new Intent(); 398 intent.putExtra(StatsManager.EXTRA_STATS_ACTIVE_CONFIG_KEYS, configIds); 399 try { 400 intentSender.sendIntent(mContext, CODE_ACTIVE_CONFIGS_BROADCAST, intent, null, null); 401 if (DEBUG) { 402 Slog.d(TAG, "Sent broadcast with config ids " + Arrays.toString(configIds)); 403 } 404 } catch (IntentSender.SendIntentException e) { 405 Slog.w(TAG, "Unable to send active configs changed broadcast using IntentSender"); 406 } 407 } 408 409 @Override sendSubscriberBroadcast(IBinder intentSenderBinder, long configUid, long configKey, long subscriptionId, long subscriptionRuleId, String[] cookies, StatsDimensionsValue dimensionsValue)410 public void sendSubscriberBroadcast(IBinder intentSenderBinder, long configUid, long configKey, 411 long subscriptionId, long subscriptionRuleId, String[] cookies, 412 StatsDimensionsValue dimensionsValue) { 413 enforceCallingPermission(); 414 IntentSender intentSender = new IntentSender(intentSenderBinder); 415 Intent intent = 416 new Intent() 417 .putExtra(StatsManager.EXTRA_STATS_CONFIG_UID, configUid) 418 .putExtra(StatsManager.EXTRA_STATS_CONFIG_KEY, configKey) 419 .putExtra(StatsManager.EXTRA_STATS_SUBSCRIPTION_ID, subscriptionId) 420 .putExtra(StatsManager.EXTRA_STATS_SUBSCRIPTION_RULE_ID, subscriptionRuleId) 421 .putExtra(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE, dimensionsValue); 422 423 ArrayList<String> cookieList = new ArrayList<>(cookies.length); 424 for (String cookie : cookies) { 425 cookieList.add(cookie); 426 } 427 intent.putStringArrayListExtra( 428 StatsManager.EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES, cookieList); 429 430 if (DEBUG) { 431 Slog.d(TAG, 432 String.format("Statsd sendSubscriberBroadcast with params {%d %d %d %d %s %s}", 433 configUid, configKey, subscriptionId, subscriptionRuleId, 434 Arrays.toString(cookies), 435 dimensionsValue)); 436 } 437 try { 438 intentSender.sendIntent(mContext, CODE_SUBSCRIBER_BROADCAST, intent, null, null); 439 } catch (IntentSender.SendIntentException e) { 440 Slog.w(TAG, 441 "Unable to send using IntentSender from uid " + configUid 442 + "; presumably it had been cancelled."); 443 } 444 } 445 toIntArray(List<Integer> list)446 private final static int[] toIntArray(List<Integer> list) { 447 int[] ret = new int[list.size()]; 448 for (int i = 0; i < ret.length; i++) { 449 ret[i] = list.get(i); 450 } 451 return ret; 452 } 453 toLongArray(List<Long> list)454 private final static long[] toLongArray(List<Long> list) { 455 long[] ret = new long[list.size()]; 456 for (int i = 0; i < ret.length; i++) { 457 ret[i] = list.get(i); 458 } 459 return ret; 460 } 461 462 // Assumes that sStatsdLock is held. 463 @GuardedBy("sStatsdLock") informAllUidsLocked(Context context)464 private final void informAllUidsLocked(Context context) throws RemoteException { 465 UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); 466 PackageManager pm = context.getPackageManager(); 467 final List<UserInfo> users = um.getUsers(true); 468 if (DEBUG) { 469 Slog.d(TAG, "Iterating over " + users.size() + " profiles."); 470 } 471 472 ParcelFileDescriptor[] fds; 473 try { 474 fds = ParcelFileDescriptor.createPipe(); 475 } catch (IOException e) { 476 Slog.e(TAG, "Failed to create a pipe to send uid map data.", e); 477 return; 478 } 479 sStatsd.informAllUidData(fds[0]); 480 try { 481 fds[0].close(); 482 } catch (IOException e) { 483 Slog.e(TAG, "Failed to close the read side of the pipe.", e); 484 } 485 final ParcelFileDescriptor writeFd = fds[1]; 486 BackgroundThread.getHandler().post(() -> { 487 FileOutputStream fout = new ParcelFileDescriptor.AutoCloseOutputStream(writeFd); 488 try { 489 ProtoOutputStream output = new ProtoOutputStream(fout); 490 int numRecords = 0; 491 // Add in all the apps for every user/profile. 492 for (UserInfo profile : users) { 493 List<PackageInfo> pi = 494 pm.getInstalledPackagesAsUser(PackageManager.MATCH_KNOWN_PACKAGES, 495 profile.id); 496 for (int j = 0; j < pi.size(); j++) { 497 if (pi.get(j).applicationInfo != null) { 498 String installer; 499 try { 500 installer = pm.getInstallerPackageName(pi.get(j).packageName); 501 } catch (IllegalArgumentException e) { 502 installer = ""; 503 } 504 long applicationInfoToken = 505 output.start(ProtoStream.FIELD_TYPE_MESSAGE 506 | ProtoStream.FIELD_COUNT_REPEATED 507 | APPLICATION_INFO_FIELD_ID); 508 output.write(ProtoStream.FIELD_TYPE_INT32 509 | ProtoStream.FIELD_COUNT_SINGLE | UID_FIELD_ID, 510 pi.get(j).applicationInfo.uid); 511 output.write(ProtoStream.FIELD_TYPE_INT64 512 | ProtoStream.FIELD_COUNT_SINGLE 513 | VERSION_FIELD_ID, pi.get(j).getLongVersionCode()); 514 output.write(ProtoStream.FIELD_TYPE_STRING 515 | ProtoStream.FIELD_COUNT_SINGLE | VERSION_STRING_FIELD_ID, 516 pi.get(j).versionName); 517 output.write(ProtoStream.FIELD_TYPE_STRING 518 | ProtoStream.FIELD_COUNT_SINGLE 519 | PACKAGE_NAME_FIELD_ID, pi.get(j).packageName); 520 output.write(ProtoStream.FIELD_TYPE_STRING 521 | ProtoStream.FIELD_COUNT_SINGLE 522 | INSTALLER_FIELD_ID, 523 installer == null ? "" : installer); 524 numRecords++; 525 output.end(applicationInfoToken); 526 } 527 } 528 } 529 output.flush(); 530 if (DEBUG) { 531 Slog.d(TAG, "Sent data for " + numRecords + " apps"); 532 } 533 } finally { 534 IoUtils.closeQuietly(fout); 535 } 536 }); 537 } 538 539 private final static class AppUpdateReceiver extends BroadcastReceiver { 540 @Override onReceive(Context context, Intent intent)541 public void onReceive(Context context, Intent intent) { 542 /** 543 * App updates actually consist of REMOVE, ADD, and then REPLACE broadcasts. To avoid 544 * waste, we ignore the REMOVE and ADD broadcasts that contain the replacing flag. 545 * If we can't find the value for EXTRA_REPLACING, we default to false. 546 */ 547 if (!intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED) 548 && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 549 return; // Keep only replacing or normal add and remove. 550 } 551 if (DEBUG) Slog.d(TAG, "StatsCompanionService noticed an app was updated."); 552 synchronized (sStatsdLock) { 553 if (sStatsd == null) { 554 Slog.w(TAG, "Could not access statsd to inform it of an app update"); 555 return; 556 } 557 try { 558 if (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) { 559 Bundle b = intent.getExtras(); 560 int uid = b.getInt(Intent.EXTRA_UID); 561 boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 562 if (!replacing) { 563 // Don't bother sending an update if we're right about to get another 564 // intent for the new version that's added. 565 PackageManager pm = context.getPackageManager(); 566 String app = intent.getData().getSchemeSpecificPart(); 567 sStatsd.informOnePackageRemoved(app, uid); 568 } 569 } else { 570 PackageManager pm = context.getPackageManager(); 571 Bundle b = intent.getExtras(); 572 int uid = b.getInt(Intent.EXTRA_UID); 573 String app = intent.getData().getSchemeSpecificPart(); 574 PackageInfo pi = pm.getPackageInfo(app, PackageManager.MATCH_ANY_USER); 575 String installer; 576 try { 577 installer = pm.getInstallerPackageName(app); 578 } catch (IllegalArgumentException e) { 579 installer = ""; 580 } 581 sStatsd.informOnePackage(app, uid, pi.getLongVersionCode(), pi.versionName, 582 installer == null ? "" : installer); 583 } 584 } catch (Exception e) { 585 Slog.w(TAG, "Failed to inform statsd of an app update", e); 586 } 587 } 588 } 589 } 590 591 public final static class AnomalyAlarmListener implements OnAlarmListener { 592 @Override onAlarm()593 public void onAlarm() { 594 Slog.i(TAG, "StatsCompanionService believes an anomaly has occurred at time " 595 + System.currentTimeMillis() + "ms."); 596 synchronized (sStatsdLock) { 597 if (sStatsd == null) { 598 Slog.w(TAG, "Could not access statsd to inform it of anomaly alarm firing"); 599 return; 600 } 601 try { 602 // Two-way call to statsd to retain AlarmManager wakelock 603 sStatsd.informAnomalyAlarmFired(); 604 } catch (RemoteException e) { 605 Slog.w(TAG, "Failed to inform statsd of anomaly alarm firing", e); 606 } 607 } 608 // AlarmManager releases its own wakelock here. 609 } 610 } 611 612 public final static class PullingAlarmListener implements OnAlarmListener { 613 @Override onAlarm()614 public void onAlarm() { 615 if (DEBUG) { 616 Slog.d(TAG, "Time to poll something."); 617 } 618 synchronized (sStatsdLock) { 619 if (sStatsd == null) { 620 Slog.w(TAG, "Could not access statsd to inform it of pulling alarm firing."); 621 return; 622 } 623 try { 624 // Two-way call to statsd to retain AlarmManager wakelock 625 sStatsd.informPollAlarmFired(); 626 } catch (RemoteException e) { 627 Slog.w(TAG, "Failed to inform statsd of pulling alarm firing.", e); 628 } 629 } 630 } 631 } 632 633 public final static class PeriodicAlarmListener implements OnAlarmListener { 634 @Override onAlarm()635 public void onAlarm() { 636 if (DEBUG) { 637 Slog.d(TAG, "Time to trigger periodic alarm."); 638 } 639 synchronized (sStatsdLock) { 640 if (sStatsd == null) { 641 Slog.w(TAG, "Could not access statsd to inform it of periodic alarm firing."); 642 return; 643 } 644 try { 645 // Two-way call to statsd to retain AlarmManager wakelock 646 sStatsd.informAlarmForSubscriberTriggeringFired(); 647 } catch (RemoteException e) { 648 Slog.w(TAG, "Failed to inform statsd of periodic alarm firing.", e); 649 } 650 } 651 // AlarmManager releases its own wakelock here. 652 } 653 } 654 655 public final static class ShutdownEventReceiver extends BroadcastReceiver { 656 @Override onReceive(Context context, Intent intent)657 public void onReceive(Context context, Intent intent) { 658 /** 659 * Skip immediately if intent is not relevant to device shutdown. 660 */ 661 if (!intent.getAction().equals(Intent.ACTION_REBOOT) 662 && !(intent.getAction().equals(Intent.ACTION_SHUTDOWN) 663 && (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0)) { 664 return; 665 } 666 667 Slog.i(TAG, "StatsCompanionService noticed a shutdown."); 668 synchronized (sStatsdLock) { 669 if (sStatsd == null) { 670 Slog.w(TAG, "Could not access statsd to inform it of a shutdown event."); 671 return; 672 } 673 try { 674 sStatsd.informDeviceShutdown(); 675 } catch (Exception e) { 676 Slog.w(TAG, "Failed to inform statsd of a shutdown event.", e); 677 } 678 } 679 } 680 } 681 682 @Override // Binder call setAnomalyAlarm(long timestampMs)683 public void setAnomalyAlarm(long timestampMs) { 684 enforceCallingPermission(); 685 if (DEBUG) Slog.d(TAG, "Setting anomaly alarm for " + timestampMs); 686 final long callingToken = Binder.clearCallingIdentity(); 687 try { 688 // using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will 689 // only fire when it awakens. 690 // AlarmManager will automatically cancel any previous mAnomalyAlarmListener alarm. 691 mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, timestampMs, TAG + ".anomaly", 692 mAnomalyAlarmListener, mHandler); 693 } finally { 694 Binder.restoreCallingIdentity(callingToken); 695 } 696 } 697 698 @Override // Binder call cancelAnomalyAlarm()699 public void cancelAnomalyAlarm() { 700 enforceCallingPermission(); 701 if (DEBUG) Slog.d(TAG, "Cancelling anomaly alarm"); 702 final long callingToken = Binder.clearCallingIdentity(); 703 try { 704 mAlarmManager.cancel(mAnomalyAlarmListener); 705 } finally { 706 Binder.restoreCallingIdentity(callingToken); 707 } 708 } 709 710 @Override // Binder call setAlarmForSubscriberTriggering(long timestampMs)711 public void setAlarmForSubscriberTriggering(long timestampMs) { 712 enforceCallingPermission(); 713 if (DEBUG) { 714 Slog.d(TAG, 715 "Setting periodic alarm in about " + (timestampMs 716 - SystemClock.elapsedRealtime())); 717 } 718 final long callingToken = Binder.clearCallingIdentity(); 719 try { 720 // using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will 721 // only fire when it awakens. 722 mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, timestampMs, TAG + ".periodic", 723 mPeriodicAlarmListener, mHandler); 724 } finally { 725 Binder.restoreCallingIdentity(callingToken); 726 } 727 } 728 729 @Override // Binder call cancelAlarmForSubscriberTriggering()730 public void cancelAlarmForSubscriberTriggering() { 731 enforceCallingPermission(); 732 if (DEBUG) { 733 Slog.d(TAG, "Cancelling periodic alarm"); 734 } 735 final long callingToken = Binder.clearCallingIdentity(); 736 try { 737 mAlarmManager.cancel(mPeriodicAlarmListener); 738 } finally { 739 Binder.restoreCallingIdentity(callingToken); 740 } 741 } 742 743 @Override // Binder call setPullingAlarm(long nextPullTimeMs)744 public void setPullingAlarm(long nextPullTimeMs) { 745 enforceCallingPermission(); 746 if (DEBUG) { 747 Slog.d(TAG, "Setting pulling alarm in about " 748 + (nextPullTimeMs - SystemClock.elapsedRealtime())); 749 } 750 final long callingToken = Binder.clearCallingIdentity(); 751 try { 752 // using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will 753 // only fire when it awakens. 754 mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, nextPullTimeMs, TAG + ".pull", 755 mPullingAlarmListener, mHandler); 756 } finally { 757 Binder.restoreCallingIdentity(callingToken); 758 } 759 } 760 761 @Override // Binder call cancelPullingAlarm()762 public void cancelPullingAlarm() { 763 enforceCallingPermission(); 764 if (DEBUG) { 765 Slog.d(TAG, "Cancelling pulling alarm"); 766 } 767 final long callingToken = Binder.clearCallingIdentity(); 768 try { 769 mAlarmManager.cancel(mPullingAlarmListener); 770 } finally { 771 Binder.restoreCallingIdentity(callingToken); 772 } 773 } 774 addNetworkStats( int tag, List<StatsLogEventWrapper> ret, NetworkStats stats, boolean withFGBG)775 private void addNetworkStats( 776 int tag, List<StatsLogEventWrapper> ret, NetworkStats stats, boolean withFGBG) { 777 int size = stats.size(); 778 long elapsedNanos = SystemClock.elapsedRealtimeNanos(); 779 long wallClockNanos = SystemClock.currentTimeMicro() * 1000L; 780 NetworkStats.Entry entry = new NetworkStats.Entry(); // For recycling 781 for (int j = 0; j < size; j++) { 782 stats.getValues(j, entry); 783 StatsLogEventWrapper e = new StatsLogEventWrapper(tag, elapsedNanos, wallClockNanos); 784 e.writeInt(entry.uid); 785 if (withFGBG) { 786 e.writeInt(entry.set); 787 } 788 e.writeLong(entry.rxBytes); 789 e.writeLong(entry.rxPackets); 790 e.writeLong(entry.txBytes); 791 e.writeLong(entry.txPackets); 792 ret.add(e); 793 } 794 } 795 796 /** 797 * Allows rollups per UID but keeping the set (foreground/background) slicing. 798 * Adapted from groupedByUid in frameworks/base/core/java/android/net/NetworkStats.java 799 */ rollupNetworkStatsByFGBG(NetworkStats stats)800 private NetworkStats rollupNetworkStatsByFGBG(NetworkStats stats) { 801 final NetworkStats ret = new NetworkStats(stats.getElapsedRealtime(), 1); 802 803 final NetworkStats.Entry entry = new NetworkStats.Entry(); 804 entry.iface = NetworkStats.IFACE_ALL; 805 entry.tag = NetworkStats.TAG_NONE; 806 entry.metered = NetworkStats.METERED_ALL; 807 entry.roaming = NetworkStats.ROAMING_ALL; 808 809 int size = stats.size(); 810 NetworkStats.Entry recycle = new NetworkStats.Entry(); // Used for retrieving values 811 for (int i = 0; i < size; i++) { 812 stats.getValues(i, recycle); 813 814 // Skip specific tags, since already counted in TAG_NONE 815 if (recycle.tag != NetworkStats.TAG_NONE) continue; 816 817 entry.set = recycle.set; // Allows slicing by background/foreground 818 entry.uid = recycle.uid; 819 entry.rxBytes = recycle.rxBytes; 820 entry.rxPackets = recycle.rxPackets; 821 entry.txBytes = recycle.txBytes; 822 entry.txPackets = recycle.txPackets; 823 // Operations purposefully omitted since we don't use them for statsd. 824 ret.combineValues(entry); 825 } 826 return ret; 827 } 828 829 /** 830 * Helper method to extract the Parcelable controller info from a 831 * SynchronousResultReceiver. 832 */ awaitControllerInfo( @ullable SynchronousResultReceiver receiver)833 private static <T extends Parcelable> T awaitControllerInfo( 834 @Nullable SynchronousResultReceiver receiver) { 835 if (receiver == null) { 836 return null; 837 } 838 839 try { 840 final SynchronousResultReceiver.Result result = 841 receiver.awaitResult(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS); 842 if (result.bundle != null) { 843 // This is the final destination for the Bundle. 844 result.bundle.setDefusable(true); 845 846 final T data = result.bundle.getParcelable( 847 RESULT_RECEIVER_CONTROLLER_KEY); 848 if (data != null) { 849 return data; 850 } 851 } 852 Slog.e(TAG, "no controller energy info supplied for " + receiver.getName()); 853 } catch (TimeoutException e) { 854 Slog.w(TAG, "timeout reading " + receiver.getName() + " stats"); 855 } 856 return null; 857 } 858 pullKernelWakelock( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)859 private void pullKernelWakelock( 860 int tagId, long elapsedNanos, long wallClockNanos, 861 List<StatsLogEventWrapper> pulledData) { 862 final KernelWakelockStats wakelockStats = 863 mKernelWakelockReader.readKernelWakelockStats(mTmpWakelockStats); 864 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) { 865 String name = ent.getKey(); 866 KernelWakelockStats.Entry kws = ent.getValue(); 867 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 868 e.writeString(name); 869 e.writeInt(kws.mCount); 870 e.writeInt(kws.mVersion); 871 e.writeLong(kws.mTotalTime); 872 pulledData.add(e); 873 } 874 } 875 pullWifiBytesTransfer( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)876 private void pullWifiBytesTransfer( 877 int tagId, long elapsedNanos, long wallClockNanos, 878 List<StatsLogEventWrapper> pulledData) { 879 long token = Binder.clearCallingIdentity(); 880 try { 881 // TODO: Consider caching the following call to get BatteryStatsInternal. 882 BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class); 883 String[] ifaces = bs.getWifiIfaces(); 884 if (ifaces.length == 0) { 885 return; 886 } 887 if (mNetworkStatsService == null) { 888 Slog.e(TAG, "NetworkStats Service is not available!"); 889 return; 890 } 891 // Combine all the metrics per Uid into one record. 892 NetworkStats stats = mNetworkStatsService.getDetailedUidStats(ifaces).groupedByUid(); 893 addNetworkStats(tagId, pulledData, stats, false); 894 } catch (RemoteException e) { 895 Slog.e(TAG, "Pulling netstats for wifi bytes has error", e); 896 } finally { 897 Binder.restoreCallingIdentity(token); 898 } 899 } 900 pullWifiBytesTransferByFgBg( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)901 private void pullWifiBytesTransferByFgBg( 902 int tagId, long elapsedNanos, long wallClockNanos, 903 List<StatsLogEventWrapper> pulledData) { 904 long token = Binder.clearCallingIdentity(); 905 try { 906 BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class); 907 String[] ifaces = bs.getWifiIfaces(); 908 if (ifaces.length == 0) { 909 return; 910 } 911 if (mNetworkStatsService == null) { 912 Slog.e(TAG, "NetworkStats Service is not available!"); 913 return; 914 } 915 NetworkStats stats = rollupNetworkStatsByFGBG( 916 mNetworkStatsService.getDetailedUidStats(ifaces)); 917 addNetworkStats(tagId, pulledData, stats, true); 918 } catch (RemoteException e) { 919 Slog.e(TAG, "Pulling netstats for wifi bytes w/ fg/bg has error", e); 920 } finally { 921 Binder.restoreCallingIdentity(token); 922 } 923 } 924 pullMobileBytesTransfer( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)925 private void pullMobileBytesTransfer( 926 int tagId, long elapsedNanos, long wallClockNanos, 927 List<StatsLogEventWrapper> pulledData) { 928 long token = Binder.clearCallingIdentity(); 929 try { 930 BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class); 931 String[] ifaces = bs.getMobileIfaces(); 932 if (ifaces.length == 0) { 933 return; 934 } 935 if (mNetworkStatsService == null) { 936 Slog.e(TAG, "NetworkStats Service is not available!"); 937 return; 938 } 939 // Combine all the metrics per Uid into one record. 940 NetworkStats stats = mNetworkStatsService.getDetailedUidStats(ifaces).groupedByUid(); 941 addNetworkStats(tagId, pulledData, stats, false); 942 } catch (RemoteException e) { 943 Slog.e(TAG, "Pulling netstats for mobile bytes has error", e); 944 } finally { 945 Binder.restoreCallingIdentity(token); 946 } 947 } 948 pullBluetoothBytesTransfer( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)949 private void pullBluetoothBytesTransfer( 950 int tagId, long elapsedNanos, long wallClockNanos, 951 List<StatsLogEventWrapper> pulledData) { 952 BluetoothActivityEnergyInfo info = fetchBluetoothData(); 953 if (info.getUidTraffic() != null) { 954 for (UidTraffic traffic : info.getUidTraffic()) { 955 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, 956 wallClockNanos); 957 e.writeInt(traffic.getUid()); 958 e.writeLong(traffic.getRxBytes()); 959 e.writeLong(traffic.getTxBytes()); 960 pulledData.add(e); 961 } 962 } 963 } 964 pullMobileBytesTransferByFgBg( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)965 private void pullMobileBytesTransferByFgBg( 966 int tagId, long elapsedNanos, long wallClockNanos, 967 List<StatsLogEventWrapper> pulledData) { 968 long token = Binder.clearCallingIdentity(); 969 try { 970 BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class); 971 String[] ifaces = bs.getMobileIfaces(); 972 if (ifaces.length == 0) { 973 return; 974 } 975 if (mNetworkStatsService == null) { 976 Slog.e(TAG, "NetworkStats Service is not available!"); 977 return; 978 } 979 NetworkStats stats = rollupNetworkStatsByFGBG( 980 mNetworkStatsService.getDetailedUidStats(ifaces)); 981 addNetworkStats(tagId, pulledData, stats, true); 982 } catch (RemoteException e) { 983 Slog.e(TAG, "Pulling netstats for mobile bytes w/ fg/bg has error", e); 984 } finally { 985 Binder.restoreCallingIdentity(token); 986 } 987 } 988 pullCpuTimePerFreq( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)989 private void pullCpuTimePerFreq( 990 int tagId, long elapsedNanos, long wallClockNanos, 991 List<StatsLogEventWrapper> pulledData) { 992 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) { 993 long[] clusterTimeMs = mKernelCpuSpeedReaders[cluster].readAbsolute(); 994 if (clusterTimeMs != null) { 995 for (int speed = clusterTimeMs.length - 1; speed >= 0; --speed) { 996 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, 997 wallClockNanos); 998 e.writeInt(cluster); 999 e.writeInt(speed); 1000 e.writeLong(clusterTimeMs[speed]); 1001 pulledData.add(e); 1002 } 1003 } 1004 } 1005 } 1006 pullKernelUidCpuTime( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1007 private void pullKernelUidCpuTime( 1008 int tagId, long elapsedNanos, long wallClockNanos, 1009 List<StatsLogEventWrapper> pulledData) { 1010 mCpuUidUserSysTimeReader.readAbsolute((uid, timesUs) -> { 1011 long userTimeUs = timesUs[0], systemTimeUs = timesUs[1]; 1012 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1013 e.writeInt(uid); 1014 e.writeLong(userTimeUs); 1015 e.writeLong(systemTimeUs); 1016 pulledData.add(e); 1017 }); 1018 } 1019 pullKernelUidCpuFreqTime( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1020 private void pullKernelUidCpuFreqTime( 1021 int tagId, long elapsedNanos, long wallClockNanos, 1022 List<StatsLogEventWrapper> pulledData) { 1023 mCpuUidFreqTimeReader.readAbsolute((uid, cpuFreqTimeMs) -> { 1024 for (int freqIndex = 0; freqIndex < cpuFreqTimeMs.length; ++freqIndex) { 1025 if (cpuFreqTimeMs[freqIndex] != 0) { 1026 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, 1027 wallClockNanos); 1028 e.writeInt(uid); 1029 e.writeInt(freqIndex); 1030 e.writeLong(cpuFreqTimeMs[freqIndex]); 1031 pulledData.add(e); 1032 } 1033 } 1034 }); 1035 } 1036 pullKernelUidCpuClusterTime( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1037 private void pullKernelUidCpuClusterTime( 1038 int tagId, long elapsedNanos, long wallClockNanos, 1039 List<StatsLogEventWrapper> pulledData) { 1040 mCpuUidClusterTimeReader.readAbsolute((uid, cpuClusterTimesMs) -> { 1041 for (int i = 0; i < cpuClusterTimesMs.length; i++) { 1042 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, 1043 wallClockNanos); 1044 e.writeInt(uid); 1045 e.writeInt(i); 1046 e.writeLong(cpuClusterTimesMs[i]); 1047 pulledData.add(e); 1048 } 1049 }); 1050 } 1051 pullKernelUidCpuActiveTime( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1052 private void pullKernelUidCpuActiveTime( 1053 int tagId, long elapsedNanos, long wallClockNanos, 1054 List<StatsLogEventWrapper> pulledData) { 1055 mCpuUidActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> { 1056 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1057 e.writeInt(uid); 1058 e.writeLong((long) cpuActiveTimesMs); 1059 pulledData.add(e); 1060 }); 1061 } 1062 pullWifiActivityInfo( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1063 private void pullWifiActivityInfo( 1064 int tagId, long elapsedNanos, long wallClockNanos, 1065 List<StatsLogEventWrapper> pulledData) { 1066 long token = Binder.clearCallingIdentity(); 1067 synchronized (this) { 1068 if (mWifiManager == null) { 1069 mWifiManager = 1070 IWifiManager.Stub.asInterface( 1071 ServiceManager.getService(Context.WIFI_SERVICE)); 1072 } 1073 } 1074 if (mWifiManager != null) { 1075 try { 1076 SynchronousResultReceiver wifiReceiver = new SynchronousResultReceiver("wifi"); 1077 mWifiManager.requestActivityInfo(wifiReceiver); 1078 final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver); 1079 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, 1080 wallClockNanos); 1081 e.writeLong(wifiInfo.getTimeStamp()); 1082 e.writeInt(wifiInfo.getStackState()); 1083 e.writeLong(wifiInfo.getControllerTxTimeMillis()); 1084 e.writeLong(wifiInfo.getControllerRxTimeMillis()); 1085 e.writeLong(wifiInfo.getControllerIdleTimeMillis()); 1086 e.writeLong(wifiInfo.getControllerEnergyUsed()); 1087 pulledData.add(e); 1088 } catch (RemoteException e) { 1089 Slog.e(TAG, 1090 "Pulling wifiManager for wifi controller activity energy info has error", 1091 e); 1092 } finally { 1093 Binder.restoreCallingIdentity(token); 1094 } 1095 } 1096 } 1097 pullModemActivityInfo( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1098 private void pullModemActivityInfo( 1099 int tagId, long elapsedNanos, long wallClockNanos, 1100 List<StatsLogEventWrapper> pulledData) { 1101 long token = Binder.clearCallingIdentity(); 1102 synchronized (this) { 1103 if (mTelephony == null) { 1104 mTelephony = TelephonyManager.from(mContext); 1105 } 1106 } 1107 if (mTelephony != null) { 1108 SynchronousResultReceiver modemReceiver = new SynchronousResultReceiver("telephony"); 1109 mTelephony.requestModemActivityInfo(modemReceiver); 1110 final ModemActivityInfo modemInfo = awaitControllerInfo(modemReceiver); 1111 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1112 e.writeLong(modemInfo.getTimestamp()); 1113 e.writeLong(modemInfo.getSleepTimeMillis()); 1114 e.writeLong(modemInfo.getIdleTimeMillis()); 1115 e.writeLong(modemInfo.getTxTimeMillis()[0]); 1116 e.writeLong(modemInfo.getTxTimeMillis()[1]); 1117 e.writeLong(modemInfo.getTxTimeMillis()[2]); 1118 e.writeLong(modemInfo.getTxTimeMillis()[3]); 1119 e.writeLong(modemInfo.getTxTimeMillis()[4]); 1120 e.writeLong(modemInfo.getRxTimeMillis()); 1121 e.writeLong(modemInfo.getEnergyUsed()); 1122 pulledData.add(e); 1123 } 1124 } 1125 pullBluetoothActivityInfo( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1126 private void pullBluetoothActivityInfo( 1127 int tagId, long elapsedNanos, long wallClockNanos, 1128 List<StatsLogEventWrapper> pulledData) { 1129 BluetoothActivityEnergyInfo info = fetchBluetoothData(); 1130 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1131 e.writeLong(info.getTimeStamp()); 1132 e.writeInt(info.getBluetoothStackState()); 1133 e.writeLong(info.getControllerTxTimeMillis()); 1134 e.writeLong(info.getControllerRxTimeMillis()); 1135 e.writeLong(info.getControllerIdleTimeMillis()); 1136 e.writeLong(info.getControllerEnergyUsed()); 1137 pulledData.add(e); 1138 } 1139 fetchBluetoothData()1140 private synchronized BluetoothActivityEnergyInfo fetchBluetoothData() { 1141 final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 1142 if (adapter != null) { 1143 SynchronousResultReceiver bluetoothReceiver = new SynchronousResultReceiver( 1144 "bluetooth"); 1145 adapter.requestControllerActivityEnergyInfo(bluetoothReceiver); 1146 return awaitControllerInfo(bluetoothReceiver); 1147 } else { 1148 Slog.e(TAG, "Failed to get bluetooth adapter!"); 1149 return null; 1150 } 1151 } 1152 pullSystemElapsedRealtime( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1153 private void pullSystemElapsedRealtime( 1154 int tagId, long elapsedNanos, long wallClockNanos, 1155 List<StatsLogEventWrapper> pulledData) { 1156 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1157 e.writeLong(SystemClock.elapsedRealtime()); 1158 pulledData.add(e); 1159 } 1160 pullSystemUpTime(int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1161 private void pullSystemUpTime(int tagId, long elapsedNanos, long wallClockNanos, 1162 List<StatsLogEventWrapper> pulledData) { 1163 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1164 e.writeLong(SystemClock.uptimeMillis()); 1165 pulledData.add(e); 1166 } 1167 pullProcessMemoryState( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1168 private void pullProcessMemoryState( 1169 int tagId, long elapsedNanos, long wallClockNanos, 1170 List<StatsLogEventWrapper> pulledData) { 1171 List<ProcessMemoryState> processMemoryStates = 1172 LocalServices.getService( 1173 ActivityManagerInternal.class).getMemoryStateForProcesses(); 1174 for (ProcessMemoryState processMemoryState : processMemoryStates) { 1175 final MemoryStat memoryStat = readMemoryStatFromFilesystem(processMemoryState.uid, 1176 processMemoryState.pid); 1177 if (memoryStat == null) { 1178 continue; 1179 } 1180 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1181 e.writeInt(processMemoryState.uid); 1182 e.writeString(processMemoryState.processName); 1183 e.writeInt(processMemoryState.oomScore); 1184 e.writeLong(memoryStat.pgfault); 1185 e.writeLong(memoryStat.pgmajfault); 1186 e.writeLong(memoryStat.rssInBytes); 1187 e.writeLong(memoryStat.cacheInBytes); 1188 e.writeLong(memoryStat.swapInBytes); 1189 e.writeLong(0); // unused 1190 e.writeLong(memoryStat.startTimeNanos); 1191 e.writeInt(anonAndSwapInKilobytes(memoryStat)); 1192 pulledData.add(e); 1193 } 1194 } 1195 pullNativeProcessMemoryState( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1196 private void pullNativeProcessMemoryState( 1197 int tagId, long elapsedNanos, long wallClockNanos, 1198 List<StatsLogEventWrapper> pulledData) { 1199 final List<String> processNames = Arrays.asList(MEMORY_INTERESTING_NATIVE_PROCESSES); 1200 int[] pids = getPidsForCommands(MEMORY_INTERESTING_NATIVE_PROCESSES); 1201 for (int i = 0; i < pids.length; i++) { 1202 int pid = pids[i]; 1203 MemoryStat memoryStat = readMemoryStatFromProcfs(pid); 1204 if (memoryStat == null) { 1205 continue; 1206 } 1207 int uid = getUidForPid(pid); 1208 String processName = readCmdlineFromProcfs(pid); 1209 // Sometimes we get here processName that is not included in the whitelist. It comes 1210 // from forking the zygote for an app. We can ignore that sample because this process 1211 // is collected by ProcessMemoryState. 1212 if (!processNames.contains(processName)) { 1213 continue; 1214 } 1215 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1216 e.writeInt(uid); 1217 e.writeString(processName); 1218 e.writeLong(memoryStat.pgfault); 1219 e.writeLong(memoryStat.pgmajfault); 1220 e.writeLong(memoryStat.rssInBytes); 1221 e.writeLong(0); // unused 1222 e.writeLong(memoryStat.startTimeNanos); 1223 e.writeLong(memoryStat.swapInBytes); 1224 e.writeInt(anonAndSwapInKilobytes(memoryStat)); 1225 pulledData.add(e); 1226 } 1227 } 1228 anonAndSwapInKilobytes(MemoryStat memoryStat)1229 private static int anonAndSwapInKilobytes(MemoryStat memoryStat) { 1230 return (int) ((memoryStat.anonRssInBytes + memoryStat.swapInBytes) / 1024); 1231 } 1232 pullProcessMemoryHighWaterMark( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1233 private void pullProcessMemoryHighWaterMark( 1234 int tagId, long elapsedNanos, long wallClockNanos, 1235 List<StatsLogEventWrapper> pulledData) { 1236 List<ProcessMemoryState> managedProcessList = 1237 LocalServices.getService( 1238 ActivityManagerInternal.class).getMemoryStateForProcesses(); 1239 for (ProcessMemoryState managedProcess : managedProcessList) { 1240 final long rssHighWaterMarkInBytes = 1241 readRssHighWaterMarkFromProcfs(managedProcess.pid); 1242 if (rssHighWaterMarkInBytes == 0) { 1243 continue; 1244 } 1245 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1246 e.writeInt(managedProcess.uid); 1247 e.writeString(managedProcess.processName); 1248 e.writeLong(rssHighWaterMarkInBytes); 1249 pulledData.add(e); 1250 } 1251 int[] pids = getPidsForCommands(MEMORY_INTERESTING_NATIVE_PROCESSES); 1252 for (int i = 0; i < pids.length; i++) { 1253 final int pid = pids[i]; 1254 final int uid = getUidForPid(pid); 1255 final String processName = readCmdlineFromProcfs(pid); 1256 final long rssHighWaterMarkInBytes = readRssHighWaterMarkFromProcfs(pid); 1257 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1258 e.writeInt(uid); 1259 e.writeString(processName); 1260 e.writeLong(rssHighWaterMarkInBytes); 1261 pulledData.add(e); 1262 } 1263 // Invoke rss_hwm_reset binary to reset RSS HWM counters for all processes. 1264 SystemProperties.set("sys.rss_hwm_reset.on", "1"); 1265 } 1266 pullSystemIonHeapSize( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1267 private void pullSystemIonHeapSize( 1268 int tagId, long elapsedNanos, long wallClockNanos, 1269 List<StatsLogEventWrapper> pulledData) { 1270 final long systemIonHeapSizeInBytes = readSystemIonHeapSizeFromDebugfs(); 1271 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1272 e.writeLong(systemIonHeapSizeInBytes); 1273 pulledData.add(e); 1274 } 1275 pullProcessSystemIonHeapSize( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1276 private void pullProcessSystemIonHeapSize( 1277 int tagId, long elapsedNanos, long wallClockNanos, 1278 List<StatsLogEventWrapper> pulledData) { 1279 List<IonAllocations> result = readProcessSystemIonHeapSizesFromDebugfs(); 1280 for (IonAllocations allocations : result) { 1281 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1282 e.writeInt(getUidForPid(allocations.pid)); 1283 e.writeString(readCmdlineFromProcfs(allocations.pid)); 1284 e.writeInt((int) (allocations.totalSizeInBytes / 1024)); 1285 e.writeInt(allocations.count); 1286 e.writeInt((int) (allocations.maxSizeInBytes / 1024)); 1287 pulledData.add(e); 1288 } 1289 } 1290 pullBinderCallsStats( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1291 private void pullBinderCallsStats( 1292 int tagId, long elapsedNanos, long wallClockNanos, 1293 List<StatsLogEventWrapper> pulledData) { 1294 BinderCallsStatsService.Internal binderStats = 1295 LocalServices.getService(BinderCallsStatsService.Internal.class); 1296 if (binderStats == null) { 1297 throw new IllegalStateException("binderStats is null"); 1298 } 1299 1300 List<ExportedCallStat> callStats = binderStats.getExportedCallStats(); 1301 binderStats.reset(); 1302 for (ExportedCallStat callStat : callStats) { 1303 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1304 e.writeInt(callStat.workSourceUid); 1305 e.writeString(callStat.className); 1306 e.writeString(callStat.methodName); 1307 e.writeLong(callStat.callCount); 1308 e.writeLong(callStat.exceptionCount); 1309 e.writeLong(callStat.latencyMicros); 1310 e.writeLong(callStat.maxLatencyMicros); 1311 e.writeLong(callStat.cpuTimeMicros); 1312 e.writeLong(callStat.maxCpuTimeMicros); 1313 e.writeLong(callStat.maxReplySizeBytes); 1314 e.writeLong(callStat.maxRequestSizeBytes); 1315 e.writeLong(callStat.recordedCallCount); 1316 e.writeInt(callStat.screenInteractive ? 1 : 0); 1317 e.writeInt(callStat.callingUid); 1318 pulledData.add(e); 1319 } 1320 } 1321 pullBinderCallsStatsExceptions( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1322 private void pullBinderCallsStatsExceptions( 1323 int tagId, long elapsedNanos, long wallClockNanos, 1324 List<StatsLogEventWrapper> pulledData) { 1325 BinderCallsStatsService.Internal binderStats = 1326 LocalServices.getService(BinderCallsStatsService.Internal.class); 1327 if (binderStats == null) { 1328 throw new IllegalStateException("binderStats is null"); 1329 } 1330 1331 ArrayMap<String, Integer> exceptionStats = binderStats.getExportedExceptionStats(); 1332 // TODO: decouple binder calls exceptions with the rest of the binder calls data so that we 1333 // can reset the exception stats. 1334 for (Entry<String, Integer> entry : exceptionStats.entrySet()) { 1335 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1336 e.writeString(entry.getKey()); 1337 e.writeInt(entry.getValue()); 1338 pulledData.add(e); 1339 } 1340 } 1341 pullLooperStats(int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1342 private void pullLooperStats(int tagId, long elapsedNanos, long wallClockNanos, 1343 List<StatsLogEventWrapper> pulledData) { 1344 LooperStats looperStats = LocalServices.getService(LooperStats.class); 1345 if (looperStats == null) { 1346 throw new IllegalStateException("looperStats null"); 1347 } 1348 1349 List<LooperStats.ExportedEntry> entries = looperStats.getEntries(); 1350 looperStats.reset(); 1351 for (LooperStats.ExportedEntry entry : entries) { 1352 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1353 e.writeInt(entry.workSourceUid); 1354 e.writeString(entry.handlerClassName); 1355 e.writeString(entry.threadName); 1356 e.writeString(entry.messageName); 1357 e.writeLong(entry.messageCount); 1358 e.writeLong(entry.exceptionCount); 1359 e.writeLong(entry.recordedMessageCount); 1360 e.writeLong(entry.totalLatencyMicros); 1361 e.writeLong(entry.cpuUsageMicros); 1362 e.writeBoolean(entry.isInteractive); 1363 e.writeLong(entry.maxCpuUsageMicros); 1364 e.writeLong(entry.maxLatencyMicros); 1365 e.writeLong(entry.recordedDelayMessageCount); 1366 e.writeLong(entry.delayMillis); 1367 e.writeLong(entry.maxDelayMillis); 1368 pulledData.add(e); 1369 } 1370 } 1371 pullDiskStats(int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1372 private void pullDiskStats(int tagId, long elapsedNanos, long wallClockNanos, 1373 List<StatsLogEventWrapper> pulledData) { 1374 // Run a quick-and-dirty performance test: write 512 bytes 1375 byte[] junk = new byte[512]; 1376 for (int i = 0; i < junk.length; i++) junk[i] = (byte) i; // Write nonzero bytes 1377 1378 File tmp = new File(Environment.getDataDirectory(), "system/statsdperftest.tmp"); 1379 FileOutputStream fos = null; 1380 IOException error = null; 1381 1382 long before = SystemClock.elapsedRealtime(); 1383 try { 1384 fos = new FileOutputStream(tmp); 1385 fos.write(junk); 1386 } catch (IOException e) { 1387 error = e; 1388 } finally { 1389 try { 1390 if (fos != null) fos.close(); 1391 } catch (IOException e) { 1392 // Do nothing. 1393 } 1394 } 1395 1396 long latency = SystemClock.elapsedRealtime() - before; 1397 if (tmp.exists()) tmp.delete(); 1398 1399 if (error != null) { 1400 Slog.e(TAG, "Error performing diskstats latency test"); 1401 latency = -1; 1402 } 1403 // File based encryption. 1404 boolean fileBased = StorageManager.isFileEncryptedNativeOnly(); 1405 1406 //Recent disk write speed. Binder call to storaged. 1407 int writeSpeed = -1; 1408 try { 1409 IBinder binder = ServiceManager.getService("storaged"); 1410 if (binder == null) { 1411 Slog.e(TAG, "storaged not found"); 1412 } 1413 IStoraged storaged = IStoraged.Stub.asInterface(binder); 1414 writeSpeed = storaged.getRecentPerf(); 1415 } catch (RemoteException e) { 1416 Slog.e(TAG, "storaged not found"); 1417 } 1418 1419 // Add info pulledData. 1420 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1421 e.writeLong(latency); 1422 e.writeBoolean(fileBased); 1423 e.writeInt(writeSpeed); 1424 pulledData.add(e); 1425 } 1426 pullDirectoryUsage(int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1427 private void pullDirectoryUsage(int tagId, long elapsedNanos, long wallClockNanos, 1428 List<StatsLogEventWrapper> pulledData) { 1429 StatFs statFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath()); 1430 StatFs statFsSystem = new StatFs(Environment.getRootDirectory().getAbsolutePath()); 1431 StatFs statFsCache = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath()); 1432 1433 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1434 e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__DATA); 1435 e.writeLong(statFsData.getAvailableBytes()); 1436 e.writeLong(statFsData.getTotalBytes()); 1437 pulledData.add(e); 1438 1439 e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1440 e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__CACHE); 1441 e.writeLong(statFsCache.getAvailableBytes()); 1442 e.writeLong(statFsCache.getTotalBytes()); 1443 pulledData.add(e); 1444 1445 e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1446 e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__SYSTEM); 1447 e.writeLong(statFsSystem.getAvailableBytes()); 1448 e.writeLong(statFsSystem.getTotalBytes()); 1449 pulledData.add(e); 1450 } 1451 pullAppSize(int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1452 private void pullAppSize(int tagId, long elapsedNanos, long wallClockNanos, 1453 List<StatsLogEventWrapper> pulledData) { 1454 try { 1455 String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH); 1456 JSONObject json = new JSONObject(jsonStr); 1457 long cache_time = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L); 1458 JSONArray pkg_names = json.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY); 1459 JSONArray app_sizes = json.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY); 1460 JSONArray app_data_sizes = json.getJSONArray(DiskStatsFileLogger.APP_DATA_KEY); 1461 JSONArray app_cache_sizes = json.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY); 1462 // Sanity check: Ensure all 4 lists have the same length. 1463 int length = pkg_names.length(); 1464 if (app_sizes.length() != length || app_data_sizes.length() != length 1465 || app_cache_sizes.length() != length) { 1466 Slog.e(TAG, "formatting error in diskstats cache file!"); 1467 return; 1468 } 1469 for (int i = 0; i < length; i++) { 1470 StatsLogEventWrapper e = 1471 new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1472 e.writeString(pkg_names.getString(i)); 1473 e.writeLong(app_sizes.optLong(i, -1L)); 1474 e.writeLong(app_data_sizes.optLong(i, -1L)); 1475 e.writeLong(app_cache_sizes.optLong(i, -1L)); 1476 e.writeLong(cache_time); 1477 pulledData.add(e); 1478 } 1479 } catch (IOException | JSONException e) { 1480 Slog.e(TAG, "exception reading diskstats cache file", e); 1481 } 1482 } 1483 pullCategorySize(int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1484 private void pullCategorySize(int tagId, long elapsedNanos, long wallClockNanos, 1485 List<StatsLogEventWrapper> pulledData) { 1486 try { 1487 String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH); 1488 JSONObject json = new JSONObject(jsonStr); 1489 long cacheTime = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L); 1490 1491 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1492 e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_SIZE); 1493 e.writeLong(json.optLong(DiskStatsFileLogger.APP_SIZE_AGG_KEY, -1L)); 1494 e.writeLong(cacheTime); 1495 pulledData.add(e); 1496 1497 e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1498 e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_DATA_SIZE); 1499 e.writeLong(json.optLong(DiskStatsFileLogger.APP_DATA_SIZE_AGG_KEY, -1L)); 1500 e.writeLong(cacheTime); 1501 pulledData.add(e); 1502 1503 e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1504 e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_CACHE_SIZE); 1505 e.writeLong(json.optLong(DiskStatsFileLogger.APP_CACHE_AGG_KEY, -1L)); 1506 e.writeLong(cacheTime); 1507 pulledData.add(e); 1508 1509 e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1510 e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__PHOTOS); 1511 e.writeLong(json.optLong(DiskStatsFileLogger.PHOTOS_KEY, -1L)); 1512 e.writeLong(cacheTime); 1513 pulledData.add(e); 1514 1515 e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1516 e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__VIDEOS); 1517 e.writeLong(json.optLong(DiskStatsFileLogger.VIDEOS_KEY, -1L)); 1518 e.writeLong(cacheTime); 1519 pulledData.add(e); 1520 1521 e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1522 e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__AUDIO); 1523 e.writeLong(json.optLong(DiskStatsFileLogger.AUDIO_KEY, -1L)); 1524 e.writeLong(cacheTime); 1525 pulledData.add(e); 1526 1527 e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1528 e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__DOWNLOADS); 1529 e.writeLong(json.optLong(DiskStatsFileLogger.DOWNLOADS_KEY, -1L)); 1530 e.writeLong(cacheTime); 1531 pulledData.add(e); 1532 1533 e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1534 e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__SYSTEM); 1535 e.writeLong(json.optLong(DiskStatsFileLogger.SYSTEM_KEY, -1L)); 1536 e.writeLong(cacheTime); 1537 pulledData.add(e); 1538 1539 e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1540 e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__OTHER); 1541 e.writeLong(json.optLong(DiskStatsFileLogger.MISC_KEY, -1L)); 1542 e.writeLong(cacheTime); 1543 pulledData.add(e); 1544 } catch (IOException | JSONException e) { 1545 Slog.e(TAG, "exception reading diskstats cache file", e); 1546 } 1547 } 1548 pullNumBiometricsEnrolled(int modality, int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1549 private void pullNumBiometricsEnrolled(int modality, int tagId, long elapsedNanos, 1550 long wallClockNanos, List<StatsLogEventWrapper> pulledData) { 1551 final PackageManager pm = mContext.getPackageManager(); 1552 FingerprintManager fingerprintManager = null; 1553 FaceManager faceManager = null; 1554 1555 if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) { 1556 fingerprintManager = mContext.getSystemService( 1557 FingerprintManager.class); 1558 } 1559 if (pm.hasSystemFeature(PackageManager.FEATURE_FACE)) { 1560 faceManager = mContext.getSystemService(FaceManager.class); 1561 } 1562 1563 if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT && fingerprintManager == null) { 1564 return; 1565 } 1566 if (modality == BiometricsProtoEnums.MODALITY_FACE && faceManager == null) { 1567 return; 1568 } 1569 UserManager userManager = mContext.getSystemService(UserManager.class); 1570 if (userManager == null) { 1571 return; 1572 } 1573 1574 final long token = Binder.clearCallingIdentity(); 1575 for (UserInfo user : userManager.getUsers()) { 1576 final int userId = user.getUserHandle().getIdentifier(); 1577 int numEnrolled = 0; 1578 if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT) { 1579 numEnrolled = fingerprintManager.getEnrolledFingerprints(userId).size(); 1580 } else if (modality == BiometricsProtoEnums.MODALITY_FACE) { 1581 numEnrolled = faceManager.getEnrolledFaces(userId).size(); 1582 } else { 1583 return; 1584 } 1585 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1586 e.writeInt(userId); 1587 e.writeInt(numEnrolled); 1588 pulledData.add(e); 1589 } 1590 Binder.restoreCallingIdentity(token); 1591 } 1592 1593 // read high watermark for section readProcStatsHighWaterMark(int section)1594 private long readProcStatsHighWaterMark(int section) { 1595 try { 1596 File[] files = mBaseDir.listFiles((d, name) -> { 1597 return name.toLowerCase().startsWith(String.valueOf(section) + '_'); 1598 }); 1599 if (files == null || files.length == 0) { 1600 return 0; 1601 } 1602 if (files.length > 1) { 1603 Log.e(TAG, "Only 1 file expected for high water mark. Found " + files.length); 1604 } 1605 return Long.valueOf(files[0].getName().split("_")[1]); 1606 } catch (SecurityException e) { 1607 Log.e(TAG, "Failed to get procstats high watermark file.", e); 1608 } catch (NumberFormatException e) { 1609 Log.e(TAG, "Failed to parse file name.", e); 1610 } 1611 return 0; 1612 } 1613 1614 private IProcessStats mProcessStats = 1615 IProcessStats.Stub.asInterface(ServiceManager.getService(ProcessStats.SERVICE_NAME)); 1616 pullProcessStats(int section, int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1617 private void pullProcessStats(int section, int tagId, long elapsedNanos, long wallClockNanos, 1618 List<StatsLogEventWrapper> pulledData) { 1619 synchronized (this) { 1620 try { 1621 long lastHighWaterMark = readProcStatsHighWaterMark(section); 1622 List<ParcelFileDescriptor> statsFiles = new ArrayList<>(); 1623 long highWaterMark = mProcessStats.getCommittedStats( 1624 lastHighWaterMark, section, true, statsFiles); 1625 if (statsFiles.size() != 1) { 1626 return; 1627 } 1628 InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream( 1629 statsFiles.get(0)); 1630 int[] len = new int[1]; 1631 byte[] stats = readFully(stream, len); 1632 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, 1633 wallClockNanos); 1634 e.writeStorage(Arrays.copyOf(stats, len[0])); 1635 pulledData.add(e); 1636 new File(mBaseDir.getAbsolutePath() + "/" + section + "_" 1637 + lastHighWaterMark).delete(); 1638 new File( 1639 mBaseDir.getAbsolutePath() + "/" + section + "_" 1640 + highWaterMark).createNewFile(); 1641 } catch (IOException e) { 1642 Log.e(TAG, "Getting procstats failed: ", e); 1643 } catch (RemoteException e) { 1644 Log.e(TAG, "Getting procstats failed: ", e); 1645 } catch (SecurityException e) { 1646 Log.e(TAG, "Getting procstats failed: ", e); 1647 } 1648 } 1649 } 1650 readFully(InputStream stream, int[] outLen)1651 static byte[] readFully(InputStream stream, int[] outLen) throws IOException { 1652 int pos = 0; 1653 final int initialAvail = stream.available(); 1654 byte[] data = new byte[initialAvail > 0 ? (initialAvail + 1) : 16384]; 1655 while (true) { 1656 int amt = stream.read(data, pos, data.length - pos); 1657 if (DEBUG) { 1658 Slog.i(TAG, "Read " + amt + " bytes at " + pos + " of avail " + data.length); 1659 } 1660 if (amt < 0) { 1661 if (DEBUG) { 1662 Slog.i(TAG, "**** FINISHED READING: pos=" + pos + " len=" + data.length); 1663 } 1664 outLen[0] = pos; 1665 return data; 1666 } 1667 pos += amt; 1668 if (pos >= data.length) { 1669 byte[] newData = new byte[pos + 16384]; 1670 if (DEBUG) { 1671 Slog.i(TAG, "Copying " + pos + " bytes to new array len " + newData.length); 1672 } 1673 System.arraycopy(data, 0, newData, 0, pos); 1674 data = newData; 1675 } 1676 } 1677 } 1678 pullPowerProfile( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1679 private void pullPowerProfile( 1680 int tagId, long elapsedNanos, long wallClockNanos, 1681 List<StatsLogEventWrapper> pulledData) { 1682 PowerProfile powerProfile = new PowerProfile(mContext); 1683 checkNotNull(powerProfile); 1684 1685 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, 1686 wallClockNanos); 1687 ProtoOutputStream proto = new ProtoOutputStream(); 1688 powerProfile.writeToProto(proto); 1689 proto.flush(); 1690 e.writeStorage(proto.getBytes()); 1691 pulledData.add(e); 1692 } 1693 pullBuildInformation(int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1694 private void pullBuildInformation(int tagId, 1695 long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData) { 1696 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1697 e.writeString(Build.FINGERPRINT); 1698 e.writeString(Build.BRAND); 1699 e.writeString(Build.PRODUCT); 1700 e.writeString(Build.DEVICE); 1701 e.writeString(Build.VERSION.RELEASE); 1702 e.writeString(Build.ID); 1703 e.writeString(Build.VERSION.INCREMENTAL); 1704 e.writeString(Build.TYPE); 1705 e.writeString(Build.TAGS); 1706 pulledData.add(e); 1707 } 1708 getBatteryStatsHelper()1709 private BatteryStatsHelper getBatteryStatsHelper() { 1710 if (mBatteryStatsHelper == null) { 1711 final long callingToken = Binder.clearCallingIdentity(); 1712 try { 1713 // clearCallingIdentity required for BatteryStatsHelper.checkWifiOnly(). 1714 mBatteryStatsHelper = new BatteryStatsHelper(mContext, false); 1715 } finally { 1716 Binder.restoreCallingIdentity(callingToken); 1717 } 1718 mBatteryStatsHelper.create((Bundle) null); 1719 } 1720 long currentTime = SystemClock.elapsedRealtime(); 1721 if (currentTime - mBatteryStatsHelperTimestampMs >= MAX_BATTERY_STATS_HELPER_FREQUENCY_MS) { 1722 // Load BatteryStats and do all the calculations. 1723 mBatteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, UserHandle.USER_ALL); 1724 // Calculations are done so we don't need to save the raw BatteryStats data in RAM. 1725 mBatteryStatsHelper.clearStats(); 1726 mBatteryStatsHelperTimestampMs = currentTime; 1727 } 1728 return mBatteryStatsHelper; 1729 } 1730 milliAmpHrsToNanoAmpSecs(double mAh)1731 private long milliAmpHrsToNanoAmpSecs(double mAh) { 1732 final long MILLI_AMP_HR_TO_NANO_AMP_SECS = 1_000_000L * 3600L; 1733 return (long) (mAh * MILLI_AMP_HR_TO_NANO_AMP_SECS + 0.5); 1734 } 1735 pullDeviceCalculatedPowerUse(int tagId, long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData)1736 private void pullDeviceCalculatedPowerUse(int tagId, 1737 long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData) { 1738 BatteryStatsHelper bsHelper = getBatteryStatsHelper(); 1739 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1740 e.writeLong(milliAmpHrsToNanoAmpSecs(bsHelper.getComputedPower())); 1741 pulledData.add(e); 1742 } 1743 pullDeviceCalculatedPowerBlameUid(int tagId, long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData)1744 private void pullDeviceCalculatedPowerBlameUid(int tagId, 1745 long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData) { 1746 final List<BatterySipper> sippers = getBatteryStatsHelper().getUsageList(); 1747 if (sippers == null) { 1748 return; 1749 } 1750 for (BatterySipper bs : sippers) { 1751 if (bs.drainType != bs.drainType.APP) { 1752 continue; 1753 } 1754 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1755 e.writeInt(bs.uidObj.getUid()); 1756 e.writeLong(milliAmpHrsToNanoAmpSecs(bs.totalPowerMah)); 1757 pulledData.add(e); 1758 } 1759 } 1760 pullDeviceCalculatedPowerBlameOther(int tagId, long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData)1761 private void pullDeviceCalculatedPowerBlameOther(int tagId, 1762 long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData) { 1763 final List<BatterySipper> sippers = getBatteryStatsHelper().getUsageList(); 1764 if (sippers == null) { 1765 return; 1766 } 1767 for (BatterySipper bs : sippers) { 1768 if (bs.drainType == bs.drainType.APP) { 1769 continue; // This is a separate atom; see pullDeviceCalculatedPowerBlameUid(). 1770 } 1771 if (bs.drainType == bs.drainType.USER) { 1772 continue; // This is not supported. We purposefully calculate over USER_ALL. 1773 } 1774 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1775 e.writeInt(bs.drainType.ordinal()); 1776 e.writeLong(milliAmpHrsToNanoAmpSecs(bs.totalPowerMah)); 1777 pulledData.add(e); 1778 } 1779 } 1780 pullDiskIo(int tagId, long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData)1781 private void pullDiskIo(int tagId, long elapsedNanos, final long wallClockNanos, 1782 List<StatsLogEventWrapper> pulledData) { 1783 mStoragedUidIoStatsReader.readAbsolute((uid, fgCharsRead, fgCharsWrite, fgBytesRead, 1784 fgBytesWrite, bgCharsRead, bgCharsWrite, bgBytesRead, bgBytesWrite, 1785 fgFsync, bgFsync) -> { 1786 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, 1787 wallClockNanos); 1788 e.writeInt(uid); 1789 e.writeLong(fgCharsRead); 1790 e.writeLong(fgCharsWrite); 1791 e.writeLong(fgBytesRead); 1792 e.writeLong(fgBytesWrite); 1793 e.writeLong(bgCharsRead); 1794 e.writeLong(bgCharsWrite); 1795 e.writeLong(bgBytesRead); 1796 e.writeLong(bgBytesWrite); 1797 e.writeLong(fgFsync); 1798 e.writeLong(bgFsync); 1799 pulledData.add(e); 1800 }); 1801 } 1802 pullProcessCpuTime(int tagId, long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData)1803 private void pullProcessCpuTime(int tagId, long elapsedNanos, final long wallClockNanos, 1804 List<StatsLogEventWrapper> pulledData) { 1805 synchronized (this) { 1806 if (mProcessCpuTracker == null) { 1807 mProcessCpuTracker = new ProcessCpuTracker(false); 1808 mProcessCpuTracker.init(); 1809 } 1810 mProcessCpuTracker.update(); 1811 for (int i = 0; i < mProcessCpuTracker.countStats(); i++) { 1812 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1813 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, 1814 wallClockNanos); 1815 e.writeInt(st.uid); 1816 e.writeString(st.name); 1817 e.writeLong(st.base_utime); 1818 e.writeLong(st.base_stime); 1819 pulledData.add(e); 1820 } 1821 } 1822 } 1823 pullCpuTimePerThreadFreq(int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1824 private void pullCpuTimePerThreadFreq(int tagId, long elapsedNanos, long wallClockNanos, 1825 List<StatsLogEventWrapper> pulledData) { 1826 if (this.mKernelCpuThreadReader == null) { 1827 throw new IllegalStateException("mKernelCpuThreadReader is null"); 1828 } 1829 ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages = 1830 this.mKernelCpuThreadReader.getProcessCpuUsageDiffed(); 1831 if (processCpuUsages == null) { 1832 throw new IllegalStateException("processCpuUsages is null"); 1833 } 1834 int[] cpuFrequencies = mKernelCpuThreadReader.getCpuFrequenciesKhz(); 1835 if (cpuFrequencies.length > CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES) { 1836 String message = "Expected maximum " + CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES 1837 + " frequencies, but got " + cpuFrequencies.length; 1838 Slog.w(TAG, message); 1839 throw new IllegalStateException(message); 1840 } 1841 for (int i = 0; i < processCpuUsages.size(); i++) { 1842 KernelCpuThreadReader.ProcessCpuUsage processCpuUsage = processCpuUsages.get(i); 1843 ArrayList<KernelCpuThreadReader.ThreadCpuUsage> threadCpuUsages = 1844 processCpuUsage.threadCpuUsages; 1845 for (int j = 0; j < threadCpuUsages.size(); j++) { 1846 KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage = threadCpuUsages.get(j); 1847 if (threadCpuUsage.usageTimesMillis.length != cpuFrequencies.length) { 1848 String message = "Unexpected number of usage times," 1849 + " expected " + cpuFrequencies.length 1850 + " but got " + threadCpuUsage.usageTimesMillis.length; 1851 Slog.w(TAG, message); 1852 throw new IllegalStateException(message); 1853 } 1854 1855 StatsLogEventWrapper e = 1856 new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1857 e.writeInt(processCpuUsage.uid); 1858 e.writeInt(processCpuUsage.processId); 1859 e.writeInt(threadCpuUsage.threadId); 1860 e.writeString(processCpuUsage.processName); 1861 e.writeString(threadCpuUsage.threadName); 1862 for (int k = 0; k < CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES; k++) { 1863 if (k < cpuFrequencies.length) { 1864 e.writeInt(cpuFrequencies[k]); 1865 e.writeInt(threadCpuUsage.usageTimesMillis[k]); 1866 } else { 1867 // If we have no more frequencies to write, we still must write empty data. 1868 // We know that this data is empty (and not just zero) because all 1869 // frequencies are expected to be greater than zero 1870 e.writeInt(0); 1871 e.writeInt(0); 1872 } 1873 } 1874 pulledData.add(e); 1875 } 1876 } 1877 } 1878 pullTemperature(int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1879 private void pullTemperature(int tagId, long elapsedNanos, long wallClockNanos, 1880 List<StatsLogEventWrapper> pulledData) { 1881 long callingToken = Binder.clearCallingIdentity(); 1882 try { 1883 List<Temperature> temperatures = sThermalService.getCurrentTemperatures(); 1884 for (Temperature temp : temperatures) { 1885 StatsLogEventWrapper e = 1886 new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1887 e.writeInt(temp.getType()); 1888 e.writeString(temp.getName()); 1889 e.writeInt((int) (temp.getValue() * 10)); 1890 e.writeInt(temp.getStatus()); 1891 pulledData.add(e); 1892 } 1893 } catch (RemoteException e) { 1894 // Should not happen. 1895 Slog.e(TAG, "Disconnected from thermal service. Cannot pull temperatures."); 1896 } finally { 1897 Binder.restoreCallingIdentity(callingToken); 1898 } 1899 } 1900 pullCoolingDevices(int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)1901 private void pullCoolingDevices(int tagId, long elapsedNanos, long wallClockNanos, 1902 List<StatsLogEventWrapper> pulledData) { 1903 long callingToken = Binder.clearCallingIdentity(); 1904 try { 1905 List<CoolingDevice> devices = sThermalService.getCurrentCoolingDevices(); 1906 for (CoolingDevice device : devices) { 1907 StatsLogEventWrapper e = 1908 new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1909 e.writeInt(device.getType()); 1910 e.writeString(device.getName()); 1911 e.writeInt((int) (device.getValue())); 1912 pulledData.add(e); 1913 } 1914 } catch (RemoteException e) { 1915 // Should not happen. 1916 Slog.e(TAG, "Disconnected from thermal service. Cannot pull temperatures."); 1917 } finally { 1918 Binder.restoreCallingIdentity(callingToken); 1919 } 1920 } 1921 pullDebugElapsedClock(int tagId, long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData)1922 private void pullDebugElapsedClock(int tagId, 1923 long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData) { 1924 final long elapsedMillis = SystemClock.elapsedRealtime(); 1925 final long clockDiffMillis = mDebugElapsedClockPreviousValue == 0 1926 ? 0 : elapsedMillis - mDebugElapsedClockPreviousValue; 1927 1928 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1929 e.writeLong(mDebugElapsedClockPullCount); 1930 e.writeLong(elapsedMillis); 1931 // Log it twice to be able to test multi-value aggregation from ValueMetric. 1932 e.writeLong(elapsedMillis); 1933 e.writeLong(clockDiffMillis); 1934 e.writeInt(1 /* always set */); 1935 pulledData.add(e); 1936 1937 if (mDebugElapsedClockPullCount % 2 == 1) { 1938 StatsLogEventWrapper e2 = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1939 e2.writeLong(mDebugElapsedClockPullCount); 1940 e2.writeLong(elapsedMillis); 1941 // Log it twice to be able to test multi-value aggregation from ValueMetric. 1942 e2.writeLong(elapsedMillis); 1943 e2.writeLong(clockDiffMillis); 1944 e2.writeInt(2 /* set on odd pulls */); 1945 pulledData.add(e2); 1946 } 1947 1948 mDebugElapsedClockPullCount++; 1949 mDebugElapsedClockPreviousValue = elapsedMillis; 1950 } 1951 pullDebugFailingElapsedClock(int tagId, long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData)1952 private void pullDebugFailingElapsedClock(int tagId, 1953 long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData) { 1954 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 1955 final long elapsedMillis = SystemClock.elapsedRealtime(); 1956 // Fails every 5 buckets. 1957 if (mDebugFailingElapsedClockPullCount++ % 5 == 0) { 1958 mDebugFailingElapsedClockPreviousValue = elapsedMillis; 1959 throw new RuntimeException("Failing debug elapsed clock"); 1960 } 1961 1962 e.writeLong(mDebugFailingElapsedClockPullCount); 1963 e.writeLong(elapsedMillis); 1964 // Log it twice to be able to test multi-value aggregation from ValueMetric. 1965 e.writeLong(elapsedMillis); 1966 e.writeLong(mDebugFailingElapsedClockPreviousValue == 0 1967 ? 0 : elapsedMillis - mDebugFailingElapsedClockPreviousValue); 1968 mDebugFailingElapsedClockPreviousValue = elapsedMillis; 1969 pulledData.add(e); 1970 } 1971 pullDangerousPermissionState(long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData)1972 private void pullDangerousPermissionState(long elapsedNanos, final long wallClockNanos, 1973 List<StatsLogEventWrapper> pulledData) { 1974 long token = Binder.clearCallingIdentity(); 1975 try { 1976 PackageManager pm = mContext.getPackageManager(); 1977 1978 List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers(); 1979 1980 int numUsers = users.size(); 1981 for (int userNum = 0; userNum < numUsers; userNum++) { 1982 UserHandle user = users.get(userNum).getUserHandle(); 1983 1984 List<PackageInfo> pkgs = pm.getInstalledPackagesAsUser( 1985 PackageManager.GET_PERMISSIONS, user.getIdentifier()); 1986 1987 int numPkgs = pkgs.size(); 1988 for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) { 1989 PackageInfo pkg = pkgs.get(pkgNum); 1990 1991 if (pkg.requestedPermissions == null) { 1992 continue; 1993 } 1994 1995 int numPerms = pkg.requestedPermissions.length; 1996 for (int permNum = 0; permNum < numPerms; permNum++) { 1997 String permName = pkg.requestedPermissions[permNum]; 1998 1999 PermissionInfo permissionInfo; 2000 int permissionFlags = 0; 2001 try { 2002 permissionInfo = pm.getPermissionInfo(permName, 0); 2003 permissionFlags = 2004 pm.getPermissionFlags(permName, pkg.packageName, user); 2005 2006 } catch (PackageManager.NameNotFoundException ignored) { 2007 continue; 2008 } 2009 2010 if (permissionInfo.getProtection() != PROTECTION_DANGEROUS) { 2011 continue; 2012 } 2013 2014 StatsLogEventWrapper e = new StatsLogEventWrapper( 2015 StatsLog.DANGEROUS_PERMISSION_STATE, elapsedNanos, wallClockNanos); 2016 2017 e.writeString(permName); 2018 e.writeInt(pkg.applicationInfo.uid); 2019 e.writeString(pkg.packageName); 2020 e.writeBoolean((pkg.requestedPermissionsFlags[permNum] 2021 & REQUESTED_PERMISSION_GRANTED) != 0); 2022 e.writeInt(permissionFlags); 2023 2024 pulledData.add(e); 2025 } 2026 } 2027 } 2028 } catch (Throwable t) { 2029 Log.e(TAG, "Could not read permissions", t); 2030 } finally { 2031 Binder.restoreCallingIdentity(token); 2032 } 2033 } 2034 pullAppOps(long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData)2035 private void pullAppOps(long elapsedNanos, final long wallClockNanos, 2036 List<StatsLogEventWrapper> pulledData) { 2037 long token = Binder.clearCallingIdentity(); 2038 try { 2039 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class); 2040 2041 CompletableFuture<HistoricalOps> ops = new CompletableFuture<>(); 2042 HistoricalOpsRequest histOpsRequest = 2043 new HistoricalOpsRequest.Builder( 2044 Instant.now().minus(1, ChronoUnit.HOURS).toEpochMilli(), 2045 Long.MAX_VALUE).build(); 2046 appOps.getHistoricalOps(histOpsRequest, mContext.getMainExecutor(), ops::complete); 2047 2048 HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS, 2049 TimeUnit.MILLISECONDS); 2050 2051 StatsLogEventWrapper e = new StatsLogEventWrapper(StatsLog.APP_OPS, elapsedNanos, 2052 wallClockNanos); 2053 2054 for (int uidIdx = 0; uidIdx < histOps.getUidCount(); uidIdx++) { 2055 final HistoricalUidOps uidOps = histOps.getUidOpsAt(uidIdx); 2056 final int uid = uidOps.getUid(); 2057 for (int pkgIdx = 0; pkgIdx < uidOps.getPackageCount(); pkgIdx++) { 2058 final HistoricalPackageOps packageOps = uidOps.getPackageOpsAt(pkgIdx); 2059 for (int opIdx = 0; opIdx < packageOps.getOpCount(); opIdx++) { 2060 final AppOpsManager.HistoricalOp op = packageOps.getOpAt(opIdx); 2061 e.writeInt(uid); 2062 e.writeString(packageOps.getPackageName()); 2063 e.writeInt(op.getOpCode()); 2064 e.writeLong(op.getForegroundAccessCount(OP_FLAGS_ALL_TRUSTED)); 2065 e.writeLong(op.getBackgroundAccessCount(OP_FLAGS_ALL_TRUSTED)); 2066 e.writeLong(op.getForegroundRejectCount(OP_FLAGS_ALL_TRUSTED)); 2067 e.writeLong(op.getBackgroundRejectCount(OP_FLAGS_ALL_TRUSTED)); 2068 e.writeLong(op.getForegroundAccessDuration(OP_FLAGS_ALL_TRUSTED)); 2069 e.writeLong(op.getBackgroundAccessDuration(OP_FLAGS_ALL_TRUSTED)); 2070 pulledData.add(e); 2071 } 2072 } 2073 } 2074 } catch (Throwable t) { 2075 Log.e(TAG, "Could not read appops", t); 2076 } finally { 2077 Binder.restoreCallingIdentity(token); 2078 } 2079 } 2080 2081 2082 /** 2083 * Add a RoleHolder atom for each package that holds a role. 2084 * 2085 * @param elapsedNanos the time since boot 2086 * @param wallClockNanos the time on the clock 2087 * @param pulledData the data sink to write to 2088 */ pullRoleHolders(long elapsedNanos, final long wallClockNanos, @NonNull List<StatsLogEventWrapper> pulledData)2089 private void pullRoleHolders(long elapsedNanos, final long wallClockNanos, 2090 @NonNull List<StatsLogEventWrapper> pulledData) { 2091 long callingToken = Binder.clearCallingIdentity(); 2092 try { 2093 PackageManager pm = mContext.getPackageManager(); 2094 RoleManagerInternal rmi = LocalServices.getService(RoleManagerInternal.class); 2095 2096 List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers(); 2097 2098 int numUsers = users.size(); 2099 for (int userNum = 0; userNum < numUsers; userNum++) { 2100 int userId = users.get(userNum).getUserHandle().getIdentifier(); 2101 2102 ArrayMap<String, ArraySet<String>> roles = rmi.getRolesAndHolders( 2103 userId); 2104 2105 int numRoles = roles.size(); 2106 for (int roleNum = 0; roleNum < numRoles; roleNum++) { 2107 String roleName = roles.keyAt(roleNum); 2108 ArraySet<String> holders = roles.valueAt(roleNum); 2109 2110 int numHolders = holders.size(); 2111 for (int holderNum = 0; holderNum < numHolders; holderNum++) { 2112 String holderName = holders.valueAt(holderNum); 2113 2114 PackageInfo pkg; 2115 try { 2116 pkg = pm.getPackageInfoAsUser(holderName, 0, userId); 2117 } catch (PackageManager.NameNotFoundException e) { 2118 Log.w(TAG, "Role holder " + holderName + " not found"); 2119 return; 2120 } 2121 2122 StatsLogEventWrapper e = new StatsLogEventWrapper(StatsLog.ROLE_HOLDER, 2123 elapsedNanos, wallClockNanos); 2124 e.writeInt(pkg.applicationInfo.uid); 2125 e.writeString(holderName); 2126 e.writeString(roleName); 2127 pulledData.add(e); 2128 } 2129 } 2130 } 2131 } finally { 2132 Binder.restoreCallingIdentity(callingToken); 2133 } 2134 } 2135 pullTimeZoneDataInfo(int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)2136 private void pullTimeZoneDataInfo(int tagId, 2137 long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData) { 2138 String tzDbVersion = "Unknown"; 2139 try { 2140 tzDbVersion = android.icu.util.TimeZone.getTZDataVersion(); 2141 } catch (Exception e) { 2142 Log.e(TAG, "Getting tzdb version failed: ", e); 2143 } 2144 2145 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 2146 e.writeString(tzDbVersion); 2147 pulledData.add(e); 2148 } 2149 pullExternalStorageInfo(int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)2150 private void pullExternalStorageInfo(int tagId, long elapsedNanos, long wallClockNanos, 2151 List<StatsLogEventWrapper> pulledData) { 2152 StorageManager storageManager = mContext.getSystemService(StorageManager.class); 2153 if (storageManager != null) { 2154 List<VolumeInfo> volumes = storageManager.getVolumes(); 2155 for (VolumeInfo vol : volumes) { 2156 final String envState = VolumeInfo.getEnvironmentForState(vol.getState()); 2157 final DiskInfo diskInfo = vol.getDisk(); 2158 if (diskInfo != null) { 2159 if (envState.equals(Environment.MEDIA_MOUNTED)) { 2160 // Get the type of the volume, if it is adoptable or portable. 2161 int volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__OTHER; 2162 if (vol.getType() == TYPE_PUBLIC) { 2163 volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PUBLIC; 2164 } else if (vol.getType() == TYPE_PRIVATE) { 2165 volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PRIVATE; 2166 } 2167 // Get the type of external storage inserted in the device (sd cards, 2168 // usb, etc) 2169 int externalStorageType; 2170 if (diskInfo.isSd()) { 2171 externalStorageType = StorageEnums.SD_CARD; 2172 } else if (diskInfo.isUsb()) { 2173 externalStorageType = StorageEnums.USB; 2174 } else { 2175 externalStorageType = StorageEnums.OTHER; 2176 } 2177 StatsLogEventWrapper e = 2178 new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 2179 e.writeInt(externalStorageType); 2180 e.writeInt(volumeType); 2181 e.writeLong(diskInfo.size); 2182 pulledData.add(e); 2183 } 2184 } 2185 } 2186 } 2187 } 2188 pullAppsOnExternalStorageInfo(int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)2189 private void pullAppsOnExternalStorageInfo(int tagId, long elapsedNanos, long wallClockNanos, 2190 List<StatsLogEventWrapper> pulledData) { 2191 PackageManager pm = mContext.getPackageManager(); 2192 StorageManager storage = mContext.getSystemService(StorageManager.class); 2193 List<ApplicationInfo> apps = pm.getInstalledApplications(/* flags = */ 0); 2194 for (ApplicationInfo appInfo : apps) { 2195 UUID storageUuid = appInfo.storageUuid; 2196 if (storageUuid != null) { 2197 VolumeInfo volumeInfo = storage.findVolumeByUuid(appInfo.storageUuid.toString()); 2198 if (volumeInfo != null) { 2199 DiskInfo diskInfo = volumeInfo.getDisk(); 2200 if (diskInfo != null) { 2201 int externalStorageType = -1; 2202 if (diskInfo.isSd()) { 2203 externalStorageType = StorageEnums.SD_CARD; 2204 } else if (diskInfo.isUsb()) { 2205 externalStorageType = StorageEnums.USB; 2206 } else if (appInfo.isExternal()) { 2207 externalStorageType = StorageEnums.OTHER; 2208 } 2209 // App is installed on external storage. 2210 if (externalStorageType != -1) { 2211 StatsLogEventWrapper e = 2212 new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 2213 e.writeInt(externalStorageType); 2214 e.writeString(appInfo.packageName); 2215 pulledData.add(e); 2216 } 2217 } 2218 } 2219 } 2220 } 2221 } 2222 pullFaceSettings(int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData)2223 private void pullFaceSettings(int tagId, long elapsedNanos, long wallClockNanos, 2224 List<StatsLogEventWrapper> pulledData) { 2225 long callingToken = Binder.clearCallingIdentity(); 2226 try { 2227 List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers(); 2228 int numUsers = users.size(); 2229 for (int userNum = 0; userNum < numUsers; userNum++) { 2230 int userId = users.get(userNum).getUserHandle().getIdentifier(); 2231 2232 StatsLogEventWrapper e = 2233 new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); 2234 e.writeBoolean(Settings.Secure.getIntForUser(mContext.getContentResolver(), 2235 Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED, 1, 2236 userId) != 0); 2237 e.writeBoolean(Settings.Secure.getIntForUser(mContext.getContentResolver(), 2238 Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, 2239 0, userId) != 0); 2240 e.writeBoolean(Settings.Secure.getIntForUser(mContext.getContentResolver(), 2241 Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED, 1, 2242 userId) != 0); 2243 e.writeBoolean(Settings.Secure.getIntForUser(mContext.getContentResolver(), 2244 Settings.Secure.FACE_UNLOCK_APP_ENABLED, 1, 2245 userId) != 0); 2246 e.writeBoolean(Settings.Secure.getIntForUser(mContext.getContentResolver(), 2247 Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, 0, 2248 userId) != 0); 2249 e.writeBoolean(Settings.Secure.getIntForUser(mContext.getContentResolver(), 2250 Settings.Secure.FACE_UNLOCK_DIVERSITY_REQUIRED, 1, 2251 userId) != 0); 2252 2253 pulledData.add(e); 2254 } 2255 } finally { 2256 Binder.restoreCallingIdentity(callingToken); 2257 } 2258 } 2259 2260 /** 2261 * Pulls various data. 2262 */ 2263 @Override // Binder call pullData(int tagId)2264 public StatsLogEventWrapper[] pullData(int tagId) { 2265 enforceCallingPermission(); 2266 if (DEBUG) { 2267 Slog.d(TAG, "Pulling " + tagId); 2268 } 2269 List<StatsLogEventWrapper> ret = new ArrayList<>(); 2270 long elapsedNanos = SystemClock.elapsedRealtimeNanos(); 2271 long wallClockNanos = SystemClock.currentTimeMicro() * 1000L; 2272 switch (tagId) { 2273 case StatsLog.WIFI_BYTES_TRANSFER: { 2274 pullWifiBytesTransfer(tagId, elapsedNanos, wallClockNanos, ret); 2275 break; 2276 } 2277 case StatsLog.MOBILE_BYTES_TRANSFER: { 2278 pullMobileBytesTransfer(tagId, elapsedNanos, wallClockNanos, ret); 2279 break; 2280 } 2281 case StatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG: { 2282 pullWifiBytesTransferByFgBg(tagId, elapsedNanos, wallClockNanos, ret); 2283 break; 2284 } 2285 case StatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG: { 2286 pullMobileBytesTransferByFgBg(tagId, elapsedNanos, wallClockNanos, ret); 2287 break; 2288 } 2289 case StatsLog.BLUETOOTH_BYTES_TRANSFER: { 2290 pullBluetoothBytesTransfer(tagId, elapsedNanos, wallClockNanos, ret); 2291 break; 2292 } 2293 case StatsLog.KERNEL_WAKELOCK: { 2294 pullKernelWakelock(tagId, elapsedNanos, wallClockNanos, ret); 2295 break; 2296 } 2297 case StatsLog.CPU_TIME_PER_FREQ: { 2298 pullCpuTimePerFreq(tagId, elapsedNanos, wallClockNanos, ret); 2299 break; 2300 } 2301 case StatsLog.CPU_TIME_PER_UID: { 2302 pullKernelUidCpuTime(tagId, elapsedNanos, wallClockNanos, ret); 2303 break; 2304 } 2305 case StatsLog.CPU_TIME_PER_UID_FREQ: { 2306 pullKernelUidCpuFreqTime(tagId, elapsedNanos, wallClockNanos, ret); 2307 break; 2308 } 2309 case StatsLog.CPU_CLUSTER_TIME: { 2310 pullKernelUidCpuClusterTime(tagId, elapsedNanos, wallClockNanos, ret); 2311 break; 2312 } 2313 case StatsLog.CPU_ACTIVE_TIME: { 2314 pullKernelUidCpuActiveTime(tagId, elapsedNanos, wallClockNanos, ret); 2315 break; 2316 } 2317 case StatsLog.WIFI_ACTIVITY_INFO: { 2318 pullWifiActivityInfo(tagId, elapsedNanos, wallClockNanos, ret); 2319 break; 2320 } 2321 case StatsLog.MODEM_ACTIVITY_INFO: { 2322 pullModemActivityInfo(tagId, elapsedNanos, wallClockNanos, ret); 2323 break; 2324 } 2325 case StatsLog.BLUETOOTH_ACTIVITY_INFO: { 2326 pullBluetoothActivityInfo(tagId, elapsedNanos, wallClockNanos, ret); 2327 break; 2328 } 2329 case StatsLog.SYSTEM_UPTIME: { 2330 pullSystemUpTime(tagId, elapsedNanos, wallClockNanos, ret); 2331 break; 2332 } 2333 case StatsLog.SYSTEM_ELAPSED_REALTIME: { 2334 pullSystemElapsedRealtime(tagId, elapsedNanos, wallClockNanos, ret); 2335 break; 2336 } 2337 case StatsLog.PROCESS_MEMORY_STATE: { 2338 pullProcessMemoryState(tagId, elapsedNanos, wallClockNanos, ret); 2339 break; 2340 } 2341 case StatsLog.NATIVE_PROCESS_MEMORY_STATE: { 2342 pullNativeProcessMemoryState(tagId, elapsedNanos, wallClockNanos, ret); 2343 break; 2344 } 2345 case StatsLog.PROCESS_MEMORY_HIGH_WATER_MARK: { 2346 pullProcessMemoryHighWaterMark(tagId, elapsedNanos, wallClockNanos, ret); 2347 break; 2348 } 2349 case StatsLog.SYSTEM_ION_HEAP_SIZE: { 2350 pullSystemIonHeapSize(tagId, elapsedNanos, wallClockNanos, ret); 2351 break; 2352 } 2353 case StatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE: { 2354 pullProcessSystemIonHeapSize(tagId, elapsedNanos, wallClockNanos, ret); 2355 break; 2356 } 2357 case StatsLog.BINDER_CALLS: { 2358 pullBinderCallsStats(tagId, elapsedNanos, wallClockNanos, ret); 2359 break; 2360 } 2361 case StatsLog.BINDER_CALLS_EXCEPTIONS: { 2362 pullBinderCallsStatsExceptions(tagId, elapsedNanos, wallClockNanos, ret); 2363 break; 2364 } 2365 case StatsLog.LOOPER_STATS: { 2366 pullLooperStats(tagId, elapsedNanos, wallClockNanos, ret); 2367 break; 2368 } 2369 case StatsLog.DISK_STATS: { 2370 pullDiskStats(tagId, elapsedNanos, wallClockNanos, ret); 2371 break; 2372 } 2373 case StatsLog.DIRECTORY_USAGE: { 2374 pullDirectoryUsage(tagId, elapsedNanos, wallClockNanos, ret); 2375 break; 2376 } 2377 case StatsLog.APP_SIZE: { 2378 pullAppSize(tagId, elapsedNanos, wallClockNanos, ret); 2379 break; 2380 } 2381 case StatsLog.CATEGORY_SIZE: { 2382 pullCategorySize(tagId, elapsedNanos, wallClockNanos, ret); 2383 break; 2384 } 2385 case StatsLog.NUM_FINGERPRINTS_ENROLLED: { 2386 pullNumBiometricsEnrolled(BiometricsProtoEnums.MODALITY_FINGERPRINT, tagId, 2387 elapsedNanos, wallClockNanos, ret); 2388 break; 2389 } 2390 case StatsLog.NUM_FACES_ENROLLED: { 2391 pullNumBiometricsEnrolled(BiometricsProtoEnums.MODALITY_FACE, tagId, elapsedNanos, 2392 wallClockNanos, ret); 2393 break; 2394 } 2395 case StatsLog.PROC_STATS: { 2396 pullProcessStats(ProcessStats.REPORT_ALL, tagId, elapsedNanos, wallClockNanos, ret); 2397 break; 2398 } 2399 case StatsLog.PROC_STATS_PKG_PROC: { 2400 pullProcessStats(ProcessStats.REPORT_PKG_PROC_STATS, tagId, elapsedNanos, 2401 wallClockNanos, ret); 2402 break; 2403 } 2404 case StatsLog.DISK_IO: { 2405 pullDiskIo(tagId, elapsedNanos, wallClockNanos, ret); 2406 break; 2407 } 2408 case StatsLog.POWER_PROFILE: { 2409 pullPowerProfile(tagId, elapsedNanos, wallClockNanos, ret); 2410 break; 2411 } 2412 case StatsLog.BUILD_INFORMATION: { 2413 pullBuildInformation(tagId, elapsedNanos, wallClockNanos, ret); 2414 break; 2415 } 2416 case StatsLog.PROCESS_CPU_TIME: { 2417 pullProcessCpuTime(tagId, elapsedNanos, wallClockNanos, ret); 2418 break; 2419 } 2420 case StatsLog.CPU_TIME_PER_THREAD_FREQ: { 2421 pullCpuTimePerThreadFreq(tagId, elapsedNanos, wallClockNanos, ret); 2422 break; 2423 } 2424 case StatsLog.DEVICE_CALCULATED_POWER_USE: { 2425 pullDeviceCalculatedPowerUse(tagId, elapsedNanos, wallClockNanos, ret); 2426 break; 2427 } 2428 case StatsLog.DEVICE_CALCULATED_POWER_BLAME_UID: { 2429 pullDeviceCalculatedPowerBlameUid(tagId, elapsedNanos, wallClockNanos, ret); 2430 break; 2431 } 2432 case StatsLog.DEVICE_CALCULATED_POWER_BLAME_OTHER: { 2433 pullDeviceCalculatedPowerBlameOther(tagId, elapsedNanos, wallClockNanos, ret); 2434 break; 2435 } 2436 case StatsLog.TEMPERATURE: { 2437 pullTemperature(tagId, elapsedNanos, wallClockNanos, ret); 2438 break; 2439 } 2440 case StatsLog.COOLING_DEVICE: { 2441 pullCoolingDevices(tagId, elapsedNanos, wallClockNanos, ret); 2442 break; 2443 } 2444 case StatsLog.DEBUG_ELAPSED_CLOCK: { 2445 pullDebugElapsedClock(tagId, elapsedNanos, wallClockNanos, ret); 2446 break; 2447 } 2448 case StatsLog.DEBUG_FAILING_ELAPSED_CLOCK: { 2449 pullDebugFailingElapsedClock(tagId, elapsedNanos, wallClockNanos, ret); 2450 break; 2451 } 2452 case StatsLog.ROLE_HOLDER: { 2453 pullRoleHolders(elapsedNanos, wallClockNanos, ret); 2454 break; 2455 } 2456 case StatsLog.DANGEROUS_PERMISSION_STATE: { 2457 pullDangerousPermissionState(elapsedNanos, wallClockNanos, ret); 2458 break; 2459 } 2460 case StatsLog.TIME_ZONE_DATA_INFO: { 2461 pullTimeZoneDataInfo(tagId, elapsedNanos, wallClockNanos, ret); 2462 break; 2463 } 2464 case StatsLog.EXTERNAL_STORAGE_INFO: { 2465 pullExternalStorageInfo(tagId, elapsedNanos, wallClockNanos, ret); 2466 break; 2467 } 2468 case StatsLog.APPS_ON_EXTERNAL_STORAGE_INFO: { 2469 pullAppsOnExternalStorageInfo(tagId, elapsedNanos, wallClockNanos, ret); 2470 break; 2471 } 2472 case StatsLog.FACE_SETTINGS: { 2473 pullFaceSettings(tagId, elapsedNanos, wallClockNanos, ret); 2474 break; 2475 } 2476 case StatsLog.APP_OPS: { 2477 pullAppOps(elapsedNanos, wallClockNanos, ret); 2478 break; 2479 } 2480 default: 2481 Slog.w(TAG, "No such tagId data as " + tagId); 2482 return null; 2483 } 2484 return ret.toArray(new StatsLogEventWrapper[ret.size()]); 2485 } 2486 2487 @Override // Binder call statsdReady()2488 public void statsdReady() { 2489 enforceCallingPermission(); 2490 if (DEBUG) { 2491 Slog.d(TAG, "learned that statsdReady"); 2492 } 2493 sayHiToStatsd(); // tell statsd that we're ready too and link to it 2494 mContext.sendBroadcastAsUser(new Intent(StatsManager.ACTION_STATSD_STARTED) 2495 .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND), 2496 UserHandle.SYSTEM, android.Manifest.permission.DUMP); 2497 } 2498 2499 @Override triggerUidSnapshot()2500 public void triggerUidSnapshot() { 2501 enforceCallingPermission(); 2502 synchronized (sStatsdLock) { 2503 final long token = Binder.clearCallingIdentity(); 2504 try { 2505 informAllUidsLocked(mContext); 2506 } catch (RemoteException e) { 2507 Slog.e(TAG, "Failed to trigger uid snapshot.", e); 2508 } finally { 2509 restoreCallingIdentity(token); 2510 } 2511 } 2512 } 2513 enforceCallingPermission()2514 private void enforceCallingPermission() { 2515 if (Binder.getCallingPid() == Process.myPid()) { 2516 return; 2517 } 2518 mContext.enforceCallingPermission(android.Manifest.permission.STATSCOMPANION, null); 2519 } 2520 2521 // Lifecycle and related code 2522 2523 /** 2524 * Fetches the statsd IBinder service 2525 */ fetchStatsdService()2526 private static IStatsManager fetchStatsdService() { 2527 return IStatsManager.Stub.asInterface(ServiceManager.getService("stats")); 2528 } 2529 2530 public static final class Lifecycle extends SystemService { 2531 private StatsCompanionService mStatsCompanionService; 2532 Lifecycle(Context context)2533 public Lifecycle(Context context) { 2534 super(context); 2535 } 2536 2537 @Override onStart()2538 public void onStart() { 2539 mStatsCompanionService = new StatsCompanionService(getContext()); 2540 try { 2541 publishBinderService(Context.STATS_COMPANION_SERVICE, 2542 mStatsCompanionService); 2543 if (DEBUG) Slog.d(TAG, "Published " + Context.STATS_COMPANION_SERVICE); 2544 } catch (Exception e) { 2545 Slog.e(TAG, "Failed to publishBinderService", e); 2546 } 2547 } 2548 2549 @Override onBootPhase(int phase)2550 public void onBootPhase(int phase) { 2551 super.onBootPhase(phase); 2552 if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { 2553 mStatsCompanionService.systemReady(); 2554 } 2555 } 2556 } 2557 2558 /** 2559 * Now that the android system is ready, StatsCompanion is ready too, so inform statsd. 2560 */ systemReady()2561 private void systemReady() { 2562 if (DEBUG) Slog.d(TAG, "Learned that systemReady"); 2563 sayHiToStatsd(); 2564 } 2565 2566 /** 2567 * Tells statsd that statscompanion is ready. If the binder call returns, link to 2568 * statsd. 2569 */ sayHiToStatsd()2570 private void sayHiToStatsd() { 2571 synchronized (sStatsdLock) { 2572 if (sStatsd != null) { 2573 Slog.e(TAG, "Trying to fetch statsd, but it was already fetched", 2574 new IllegalStateException( 2575 "sStatsd is not null when being fetched")); 2576 return; 2577 } 2578 sStatsd = fetchStatsdService(); 2579 if (sStatsd == null) { 2580 Slog.i(TAG, 2581 "Could not yet find statsd to tell it that StatsCompanion is " 2582 + "alive."); 2583 return; 2584 } 2585 if (DEBUG) Slog.d(TAG, "Saying hi to statsd"); 2586 try { 2587 sStatsd.statsCompanionReady(); 2588 // If the statsCompanionReady two-way binder call returns, link to statsd. 2589 try { 2590 sStatsd.asBinder().linkToDeath(new StatsdDeathRecipient(), 0); 2591 } catch (RemoteException e) { 2592 Slog.e(TAG, "linkToDeath(StatsdDeathRecipient) failed", e); 2593 forgetEverythingLocked(); 2594 } 2595 // Setup broadcast receiver for updates. 2596 IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REPLACED); 2597 filter.addAction(Intent.ACTION_PACKAGE_ADDED); 2598 filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 2599 filter.addDataScheme("package"); 2600 mContext.registerReceiverAsUser(mAppUpdateReceiver, UserHandle.ALL, filter, 2601 null, 2602 null); 2603 2604 // Setup receiver for user initialize (which happens once for a new user) 2605 // and 2606 // if a user is removed. 2607 filter = new IntentFilter(Intent.ACTION_USER_INITIALIZE); 2608 filter.addAction(Intent.ACTION_USER_REMOVED); 2609 mContext.registerReceiverAsUser(mUserUpdateReceiver, UserHandle.ALL, 2610 filter, null, null); 2611 2612 // Setup receiver for device reboots or shutdowns. 2613 filter = new IntentFilter(Intent.ACTION_REBOOT); 2614 filter.addAction(Intent.ACTION_SHUTDOWN); 2615 mContext.registerReceiverAsUser( 2616 mShutdownEventReceiver, UserHandle.ALL, filter, null, null); 2617 final long token = Binder.clearCallingIdentity(); 2618 try { 2619 // Pull the latest state of UID->app name, version mapping when 2620 // statsd starts. 2621 informAllUidsLocked(mContext); 2622 } finally { 2623 restoreCallingIdentity(token); 2624 } 2625 Slog.i(TAG, "Told statsd that StatsCompanionService is alive."); 2626 } catch (RemoteException e) { 2627 Slog.e(TAG, "Failed to inform statsd that statscompanion is ready", e); 2628 forgetEverythingLocked(); 2629 } 2630 } 2631 } 2632 2633 private class StatsdDeathRecipient implements IBinder.DeathRecipient { 2634 @Override binderDied()2635 public void binderDied() { 2636 Slog.i(TAG, "Statsd is dead - erase all my knowledge."); 2637 synchronized (sStatsdLock) { 2638 long now = SystemClock.elapsedRealtime(); 2639 for (Long timeMillis : mDeathTimeMillis) { 2640 long ageMillis = now - timeMillis; 2641 if (ageMillis > MILLIS_IN_A_DAY) { 2642 mDeathTimeMillis.remove(timeMillis); 2643 } 2644 } 2645 for (Long timeMillis : mDeletedFiles.keySet()) { 2646 long ageMillis = now - timeMillis; 2647 if (ageMillis > MILLIS_IN_A_DAY * 7) { 2648 mDeletedFiles.remove(timeMillis); 2649 } 2650 } 2651 mDeathTimeMillis.add(now); 2652 if (mDeathTimeMillis.size() >= DEATH_THRESHOLD) { 2653 mDeathTimeMillis.clear(); 2654 File[] configs = FileUtils.listFilesOrEmpty(new File(CONFIG_DIR)); 2655 if (configs.length > 0) { 2656 String fileName = configs[0].getName(); 2657 if (configs[0].delete()) { 2658 mDeletedFiles.put(now, fileName); 2659 } 2660 } 2661 } 2662 forgetEverythingLocked(); 2663 } 2664 } 2665 } 2666 2667 @GuardedBy("StatsCompanionService.sStatsdLock") forgetEverythingLocked()2668 private void forgetEverythingLocked() { 2669 sStatsd = null; 2670 mContext.unregisterReceiver(mAppUpdateReceiver); 2671 mContext.unregisterReceiver(mUserUpdateReceiver); 2672 mContext.unregisterReceiver(mShutdownEventReceiver); 2673 cancelAnomalyAlarm(); 2674 cancelPullingAlarm(); 2675 2676 BinderCallsStatsService.Internal binderStats = 2677 LocalServices.getService(BinderCallsStatsService.Internal.class); 2678 if (binderStats != null) { 2679 binderStats.reset(); 2680 } 2681 2682 LooperStats looperStats = LocalServices.getService(LooperStats.class); 2683 if (looperStats != null) { 2684 looperStats.reset(); 2685 } 2686 } 2687 2688 @Override dump(FileDescriptor fd, PrintWriter writer, String[] args)2689 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 2690 if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return; 2691 2692 synchronized (sStatsdLock) { 2693 writer.println( 2694 "Number of configuration files deleted: " + mDeletedFiles.size()); 2695 if (mDeletedFiles.size() > 0) { 2696 writer.println(" timestamp, deleted file name"); 2697 } 2698 long lastBootMillis = 2699 SystemClock.currentThreadTimeMillis() - SystemClock.elapsedRealtime(); 2700 for (Long elapsedMillis : mDeletedFiles.keySet()) { 2701 long deletionMillis = lastBootMillis + elapsedMillis; 2702 writer.println( 2703 " " + deletionMillis + ", " + mDeletedFiles.get(elapsedMillis)); 2704 } 2705 } 2706 } 2707 2708 // Thermal event received from vendor thermal management subsystem 2709 private static final class ThermalEventListener extends IThermalEventListener.Stub { 2710 @Override notifyThrottling(Temperature temp)2711 public void notifyThrottling(Temperature temp) { 2712 StatsLog.write(StatsLog.THERMAL_THROTTLING_SEVERITY_STATE_CHANGED, temp.getType(), 2713 temp.getName(), (int) (temp.getValue() * 10), temp.getStatus()); 2714 } 2715 } 2716 2717 private static final class ConnectivityStatsCallback extends 2718 ConnectivityManager.NetworkCallback { 2719 @Override onAvailable(Network network)2720 public void onAvailable(Network network) { 2721 StatsLog.write(StatsLog.CONNECTIVITY_STATE_CHANGED, network.netId, 2722 StatsLog.CONNECTIVITY_STATE_CHANGED__STATE__CONNECTED); 2723 } 2724 2725 @Override onLost(Network network)2726 public void onLost(Network network) { 2727 StatsLog.write(StatsLog.CONNECTIVITY_STATE_CHANGED, network.netId, 2728 StatsLog.CONNECTIVITY_STATE_CHANGED__STATE__DISCONNECTED); 2729 } 2730 } 2731 } 2732