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