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