blob: 7f7d668ea8acb1153c863717e32ae0a1af8b68ad [file] [log] [blame]
Tej Singh953ad862020-01-03 12:47:07 -08001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Tej Singh250e7aa2020-01-16 13:16:21 -080017package com.android.server.stats.pull;
Tej Singh953ad862020-01-03 12:47:07 -080018
Stanislav Zholnin050abc32020-02-17 14:14:52 +000019import static android.app.AppOpsManager.OP_FLAG_SELF;
Stanislav Zholnind20eacc2020-03-02 18:44:45 +000020import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXY;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080021import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
22import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS;
Rafal Slawikbdd5a502020-01-14 14:14:29 +000023import static android.os.Debug.getIonHeapsSizeKb;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080024import static android.os.Process.getUidForPid;
25import static android.os.storage.VolumeInfo.TYPE_PRIVATE;
26import static android.os.storage.VolumeInfo.TYPE_PUBLIC;
Stanislav Zholnin59199132020-03-06 14:19:25 +000027import static android.util.MathUtils.abs;
28import static android.util.MathUtils.constrain;
Tej Singh953ad862020-01-03 12:47:07 -080029
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080030import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
Tej Singh250e7aa2020-01-16 13:16:21 -080031import static com.android.server.stats.pull.IonMemoryUtil.readProcessSystemIonHeapSizesFromDebugfs;
32import static com.android.server.stats.pull.IonMemoryUtil.readSystemIonHeapSizeFromDebugfs;
Ioannis Ilkos754eb072020-01-27 16:42:24 +000033import static com.android.server.stats.pull.ProcfsMemoryUtil.getProcessCmdlines;
Tej Singh250e7aa2020-01-16 13:16:21 -080034import static com.android.server.stats.pull.ProcfsMemoryUtil.readCmdlineFromProcfs;
35import static com.android.server.stats.pull.ProcfsMemoryUtil.readMemorySnapshotFromProcfs;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080036
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080037import android.annotation.Nullable;
38import android.app.ActivityManagerInternal;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080039import android.app.AppOpsManager;
40import android.app.AppOpsManager.HistoricalOps;
41import android.app.AppOpsManager.HistoricalOpsRequest;
42import android.app.AppOpsManager.HistoricalPackageOps;
43import android.app.AppOpsManager.HistoricalUidOps;
44import android.app.INotificationManager;
45import android.app.ProcessMemoryState;
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +000046import android.app.RuntimeAppOpAccessMessage;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080047import android.app.StatsManager;
48import android.app.StatsManager.PullAtomMetadata;
49import android.bluetooth.BluetoothActivityEnergyInfo;
50import android.bluetooth.BluetoothAdapter;
51import android.bluetooth.UidTraffic;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080052import android.content.Context;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080053import android.content.pm.ApplicationInfo;
54import android.content.pm.PackageInfo;
55import android.content.pm.PackageManager;
56import android.content.pm.PermissionInfo;
57import android.content.pm.UserInfo;
58import android.hardware.biometrics.BiometricsProtoEnums;
59import android.hardware.face.FaceManager;
60import android.hardware.fingerprint.FingerprintManager;
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -080061import android.hardware.health.V2_0.IHealth;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080062import android.net.ConnectivityManager;
63import android.net.INetworkStatsService;
64import android.net.Network;
65import android.net.NetworkRequest;
66import android.net.NetworkStats;
67import android.net.wifi.WifiManager;
68import android.os.BatteryStats;
69import android.os.BatteryStatsInternal;
70import android.os.Binder;
71import android.os.Build;
72import android.os.Bundle;
73import android.os.CoolingDevice;
74import android.os.Environment;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080075import android.os.IStoraged;
76import android.os.IThermalEventListener;
77import android.os.IThermalService;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080078import android.os.ParcelFileDescriptor;
79import android.os.Parcelable;
80import android.os.RemoteException;
81import android.os.ServiceManager;
82import android.os.StatFs;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080083import android.os.SynchronousResultReceiver;
84import android.os.SystemClock;
85import android.os.SystemProperties;
86import android.os.Temperature;
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +000087import android.os.Trace;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080088import android.os.UserHandle;
89import android.os.UserManager;
90import android.os.connectivity.WifiActivityEnergyInfo;
91import android.os.storage.DiskInfo;
92import android.os.storage.StorageManager;
93import android.os.storage.VolumeInfo;
94import android.provider.Settings;
95import android.stats.storage.StorageEnums;
96import android.telephony.ModemActivityInfo;
97import android.telephony.TelephonyManager;
98import android.util.ArrayMap;
99import android.util.ArraySet;
100import android.util.Log;
101import android.util.Slog;
Ioannis Ilkos754eb072020-01-27 16:42:24 +0000102import android.util.SparseArray;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800103import android.util.StatsEvent;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800104import android.util.proto.ProtoOutputStream;
105
106import com.android.internal.annotations.GuardedBy;
107import com.android.internal.app.procstats.IProcessStats;
108import com.android.internal.app.procstats.ProcessStats;
Tej Singh953ad862020-01-03 12:47:07 -0800109import com.android.internal.os.BackgroundThread;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800110import com.android.internal.os.BatterySipper;
111import com.android.internal.os.BatteryStatsHelper;
112import com.android.internal.os.BinderCallsStats.ExportedCallStat;
113import com.android.internal.os.KernelCpuSpeedReader;
114import com.android.internal.os.KernelCpuThreadReader;
115import com.android.internal.os.KernelCpuThreadReaderDiff;
116import com.android.internal.os.KernelCpuThreadReaderSettingsObserver;
117import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader;
118import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader;
119import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader;
120import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader;
121import com.android.internal.os.KernelWakelockReader;
122import com.android.internal.os.KernelWakelockStats;
123import com.android.internal.os.LooperStats;
124import com.android.internal.os.PowerProfile;
125import com.android.internal.os.ProcessCpuTracker;
126import com.android.internal.os.StoragedUidIoStatsReader;
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -0800127import com.android.internal.util.FrameworkStatsLog;
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -0800128import com.android.server.BatteryService;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800129import com.android.server.BinderCallsStatsService;
130import com.android.server.LocalServices;
Tej Singh953ad862020-01-03 12:47:07 -0800131import com.android.server.SystemService;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800132import com.android.server.SystemServiceManager;
133import com.android.server.am.MemoryStatUtil.MemoryStat;
134import com.android.server.notification.NotificationManagerService;
135import com.android.server.role.RoleManagerInternal;
Tej Singh250e7aa2020-01-16 13:16:21 -0800136import com.android.server.stats.pull.IonMemoryUtil.IonAllocations;
137import com.android.server.stats.pull.ProcfsMemoryUtil.MemorySnapshot;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800138import com.android.server.storage.DiskStatsFileLogger;
139import com.android.server.storage.DiskStatsLoggingService;
140
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800141import libcore.io.IoUtils;
142
143import org.json.JSONArray;
144import org.json.JSONException;
145import org.json.JSONObject;
146
147import java.io.File;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800148import java.io.FileOutputStream;
149import java.io.IOException;
150import java.io.InputStream;
Stanislav Zholnin59199132020-03-06 14:19:25 +0000151import java.time.Instant;
152import java.time.temporal.ChronoUnit;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800153import java.util.ArrayList;
154import java.util.Arrays;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800155import java.util.HashSet;
156import java.util.List;
157import java.util.Map;
Ruchir Rastogibd2c4ba2020-01-15 14:48:36 -0800158import java.util.MissingResourceException;
Stanislav Zholnin59199132020-03-06 14:19:25 +0000159import java.util.Random;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800160import java.util.Set;
161import java.util.UUID;
162import java.util.concurrent.CompletableFuture;
163import java.util.concurrent.Executor;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800164import java.util.concurrent.ThreadLocalRandom;
165import java.util.concurrent.TimeUnit;
166import java.util.concurrent.TimeoutException;
Tej Singh953ad862020-01-03 12:47:07 -0800167
168/**
169 * SystemService containing PullAtomCallbacks that are registered with statsd.
170 *
171 * @hide
172 */
173public class StatsPullAtomService extends SystemService {
174 private static final String TAG = "StatsPullAtomService";
175 private static final boolean DEBUG = true;
176
Stanislav Zholnin59199132020-03-06 14:19:25 +0000177 // Random seed stable for StatsPullAtomService life cycle - can be used for stable sampling
178 private static final int RANDOM_SEED = new Random().nextInt();
179
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800180 /**
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800181 * Lowest available uid for apps.
182 *
183 * <p>Used to quickly discard memory snapshots of the zygote forks from native process
184 * measurements.
185 */
186 private static final int MIN_APP_UID = 10_000;
187
Jeffrey Huangfa917892020-01-10 16:58:03 -0800188 private static final String RESULT_RECEIVER_CONTROLLER_KEY = "controller_activity";
189 /**
190 * How long to wait on an individual subsystem to return its stats.
191 */
192 private static final long EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS = 2000;
Tej Singh72a70a82020-02-26 23:46:29 -0800193 private static final long MILLIS_PER_SEC = 1000;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800194 private static final long MILLI_AMP_HR_TO_NANO_AMP_SECS = 1_000_000L * 3600L;
195
196 private static final int MAX_BATTERY_STATS_HELPER_FREQUENCY_MS = 1000;
197 private static final int CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES = 8;
Stanislav Zholnind20eacc2020-03-02 18:44:45 +0000198 private static final int OP_FLAGS_PULLED = OP_FLAG_SELF | OP_FLAG_TRUSTED_PROXY;
Stanislav Zholnindbcf85e2020-02-24 18:17:55 +0000199 private static final String COMMON_PERMISSION_PREFIX = "android.permission.";
Jeffrey Huangfa917892020-01-10 16:58:03 -0800200
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800201 private final Object mNetworkStatsLock = new Object();
202 @GuardedBy("mNetworkStatsLock")
203 private INetworkStatsService mNetworkStatsService;
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800204
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800205 private final Object mThermalLock = new Object();
206 @GuardedBy("mThermalLock")
207 private IThermalService mThermalService;
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800208
Jeffrey Huang95765f02020-01-16 11:33:58 -0800209 private final Object mStoragedLock = new Object();
210 @GuardedBy("mStoragedLock")
211 private IStoraged mStorageService;
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800212
Jeffrey Huang730bf962020-01-16 15:59:52 -0800213 private final Object mNotificationStatsLock = new Object();
214 @GuardedBy("mNotificationStatsLock")
215 private INotificationManager mNotificationManagerService;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800216
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800217 private final Object mProcessStatsLock = new Object();
218 @GuardedBy("mProcessStatsLock")
219 private IProcessStats mProcessStatsService;
220
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800221 private final Object mCpuTrackerLock = new Object();
222 @GuardedBy("mCpuTrackerLock")
223 private ProcessCpuTracker mProcessCpuTracker;
224
225 private final Object mDebugElapsedClockLock = new Object();
226 @GuardedBy("mDebugElapsedClockLock")
227 private long mDebugElapsedClockPreviousValue = 0;
228 @GuardedBy("mDebugElapsedClockLock")
229 private long mDebugElapsedClockPullCount = 0;
230
231 private final Object mDebugFailingElapsedClockLock = new Object();
232 @GuardedBy("mDebugFailingElapsedClockLock")
233 private long mDebugFailingElapsedClockPreviousValue = 0;
234 @GuardedBy("mDebugFailingElapsedClockLock")
235 private long mDebugFailingElapsedClockPullCount = 0;
236
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800237 private final Context mContext;
238 private StatsManager mStatsManager;
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -0800239 private StorageManager mStorageManager;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800240 private WifiManager mWifiManager;
241 private TelephonyManager mTelephony;
242
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800243 private KernelWakelockReader mKernelWakelockReader;
244 private KernelWakelockStats mTmpWakelockStats;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800245
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800246 private StoragedUidIoStatsReader mStoragedUidIoStatsReader;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800247
248 private KernelCpuSpeedReader[] mKernelCpuSpeedReaders;
249 // Disables throttler on CPU time readers.
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800250 private KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader;
251 private KernelCpuUidFreqTimeReader mCpuUidFreqTimeReader;
252 private KernelCpuUidActiveTimeReader mCpuUidActiveTimeReader;
253 private KernelCpuUidClusterTimeReader mCpuUidClusterTimeReader;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800254
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800255 private File mBaseDir;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800256
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -0800257 private BatteryService.HealthServiceWrapper mHealthService;
258
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800259 @Nullable
260 private KernelCpuThreadReaderDiff mKernelCpuThreadReader;
261
262 private BatteryStatsHelper mBatteryStatsHelper = null;
263 private long mBatteryStatsHelperTimestampMs = -MAX_BATTERY_STATS_HELPER_FREQUENCY_MS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800264
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800265 private StatsPullAtomCallbackImpl mStatsCallbackImpl;
266
Stanislav Zholnin59199132020-03-06 14:19:25 +0000267 private int mAppOpsSamplingRate = 0;
268
Tej Singh953ad862020-01-03 12:47:07 -0800269 public StatsPullAtomService(Context context) {
270 super(context);
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800271 mContext = context;
Tej Singh953ad862020-01-03 12:47:07 -0800272 }
273
Jeffrey Huang4c527162020-01-30 17:53:13 -0800274 private native void nativeInit();
275
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800276 /**
277 * Use of this StatsPullAtomCallbackImpl means we avoid one class per tagId, which we would
278 * get if we used lambdas.
279 *
280 * The pull methods are intentionally left to be package private to avoid the creation
281 * of synthetic methods to save unnecessary bytecode.
282 */
283 private class StatsPullAtomCallbackImpl implements StatsManager.StatsPullAtomCallback {
284 @Override
285 public int onPullAtom(int atomTag, List<StatsEvent> data) {
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000286 if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
287 Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StatsPull-" + atomTag);
288 }
289 try {
290 switch (atomTag) {
291 case FrameworkStatsLog.WIFI_BYTES_TRANSFER:
292 return pullWifiBytesTransfer(atomTag, data);
293 case FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG:
294 return pullWifiBytesTransferBackground(atomTag, data);
295 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER:
296 return pullMobileBytesTransfer(atomTag, data);
297 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG:
298 return pullMobileBytesTransferBackground(atomTag, data);
299 case FrameworkStatsLog.BLUETOOTH_BYTES_TRANSFER:
300 return pullBluetoothBytesTransfer(atomTag, data);
301 case FrameworkStatsLog.KERNEL_WAKELOCK:
302 return pullKernelWakelock(atomTag, data);
303 case FrameworkStatsLog.CPU_TIME_PER_FREQ:
304 return pullCpuTimePerFreq(atomTag, data);
305 case FrameworkStatsLog.CPU_TIME_PER_UID:
306 return pullCpuTimePerUid(atomTag, data);
307 case FrameworkStatsLog.CPU_TIME_PER_UID_FREQ:
308 return pullCpuTimeperUidFreq(atomTag, data);
309 case FrameworkStatsLog.CPU_ACTIVE_TIME:
310 return pullCpuActiveTime(atomTag, data);
311 case FrameworkStatsLog.CPU_CLUSTER_TIME:
312 return pullCpuClusterTime(atomTag, data);
313 case FrameworkStatsLog.WIFI_ACTIVITY_INFO:
314 return pullWifiActivityInfo(atomTag, data);
315 case FrameworkStatsLog.MODEM_ACTIVITY_INFO:
316 return pullModemActivityInfo(atomTag, data);
317 case FrameworkStatsLog.BLUETOOTH_ACTIVITY_INFO:
318 return pullBluetoothActivityInfo(atomTag, data);
319 case FrameworkStatsLog.SYSTEM_ELAPSED_REALTIME:
320 return pullSystemElapsedRealtime(atomTag, data);
321 case FrameworkStatsLog.SYSTEM_UPTIME:
322 return pullSystemUptime(atomTag, data);
323 case FrameworkStatsLog.PROCESS_MEMORY_STATE:
324 return pullProcessMemoryState(atomTag, data);
325 case FrameworkStatsLog.PROCESS_MEMORY_HIGH_WATER_MARK:
326 return pullProcessMemoryHighWaterMark(atomTag, data);
327 case FrameworkStatsLog.PROCESS_MEMORY_SNAPSHOT:
328 return pullProcessMemorySnapshot(atomTag, data);
329 case FrameworkStatsLog.SYSTEM_ION_HEAP_SIZE:
330 return pullSystemIonHeapSize(atomTag, data);
331 case FrameworkStatsLog.ION_HEAP_SIZE:
332 return pullIonHeapSize(atomTag, data);
333 case FrameworkStatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE:
334 return pullProcessSystemIonHeapSize(atomTag, data);
335 case FrameworkStatsLog.TEMPERATURE:
336 return pullTemperature(atomTag, data);
337 case FrameworkStatsLog.COOLING_DEVICE:
338 return pullCooldownDevice(atomTag, data);
339 case FrameworkStatsLog.BINDER_CALLS:
340 return pullBinderCallsStats(atomTag, data);
341 case FrameworkStatsLog.BINDER_CALLS_EXCEPTIONS:
342 return pullBinderCallsStatsExceptions(atomTag, data);
343 case FrameworkStatsLog.LOOPER_STATS:
344 return pullLooperStats(atomTag, data);
345 case FrameworkStatsLog.DISK_STATS:
346 return pullDiskStats(atomTag, data);
347 case FrameworkStatsLog.DIRECTORY_USAGE:
348 return pullDirectoryUsage(atomTag, data);
349 case FrameworkStatsLog.APP_SIZE:
350 return pullAppSize(atomTag, data);
351 case FrameworkStatsLog.CATEGORY_SIZE:
352 return pullCategorySize(atomTag, data);
353 case FrameworkStatsLog.NUM_FINGERPRINTS_ENROLLED:
354 return pullNumBiometricsEnrolled(
355 BiometricsProtoEnums.MODALITY_FINGERPRINT, atomTag, data);
356 case FrameworkStatsLog.NUM_FACES_ENROLLED:
357 return pullNumBiometricsEnrolled(
358 BiometricsProtoEnums.MODALITY_FACE, atomTag, data);
359 case FrameworkStatsLog.PROC_STATS:
360 return pullProcStats(ProcessStats.REPORT_ALL, atomTag, data);
361 case FrameworkStatsLog.PROC_STATS_PKG_PROC:
362 return pullProcStats(ProcessStats.REPORT_PKG_PROC_STATS, atomTag, data);
363 case FrameworkStatsLog.DISK_IO:
364 return pullDiskIO(atomTag, data);
365 case FrameworkStatsLog.POWER_PROFILE:
366 return pullPowerProfile(atomTag, data);
367 case FrameworkStatsLog.PROCESS_CPU_TIME:
368 return pullProcessCpuTime(atomTag, data);
369 case FrameworkStatsLog.CPU_TIME_PER_THREAD_FREQ:
370 return pullCpuTimePerThreadFreq(atomTag, data);
371 case FrameworkStatsLog.DEVICE_CALCULATED_POWER_USE:
372 return pullDeviceCalculatedPowerUse(atomTag, data);
373 case FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_UID:
374 return pullDeviceCalculatedPowerBlameUid(atomTag, data);
375 case FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_OTHER:
376 return pullDeviceCalculatedPowerBlameOther(atomTag, data);
377 case FrameworkStatsLog.DEBUG_ELAPSED_CLOCK:
378 return pullDebugElapsedClock(atomTag, data);
379 case FrameworkStatsLog.DEBUG_FAILING_ELAPSED_CLOCK:
380 return pullDebugFailingElapsedClock(atomTag, data);
381 case FrameworkStatsLog.BUILD_INFORMATION:
382 return pullBuildInformation(atomTag, data);
383 case FrameworkStatsLog.ROLE_HOLDER:
384 return pullRoleHolder(atomTag, data);
385 case FrameworkStatsLog.DANGEROUS_PERMISSION_STATE:
386 return pullDangerousPermissionState(atomTag, data);
387 case FrameworkStatsLog.TIME_ZONE_DATA_INFO:
388 return pullTimeZoneDataInfo(atomTag, data);
389 case FrameworkStatsLog.EXTERNAL_STORAGE_INFO:
390 return pullExternalStorageInfo(atomTag, data);
391 case FrameworkStatsLog.APPS_ON_EXTERNAL_STORAGE_INFO:
392 return pullAppsOnExternalStorageInfo(atomTag, data);
393 case FrameworkStatsLog.FACE_SETTINGS:
394 return pullFaceSettings(atomTag, data);
395 case FrameworkStatsLog.APP_OPS:
396 return pullAppOps(atomTag, data);
397 case FrameworkStatsLog.RUNTIME_APP_OP_ACCESS:
398 return pullRuntimeAppOpAccessMessage(atomTag, data);
399 case FrameworkStatsLog.NOTIFICATION_REMOTE_VIEWS:
400 return pullNotificationRemoteViews(atomTag, data);
401 case FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED:
402 return pullDangerousPermissionState(atomTag, data);
403 case FrameworkStatsLog.BATTERY_LEVEL:
404 case FrameworkStatsLog.REMAINING_BATTERY_CAPACITY:
405 case FrameworkStatsLog.FULL_BATTERY_CAPACITY:
406 case FrameworkStatsLog.BATTERY_VOLTAGE:
407 case FrameworkStatsLog.BATTERY_CYCLE_COUNT:
408 return pullHealthHal(atomTag, data);
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -0800409 case FrameworkStatsLog.ATTRIBUTED_APP_OPS:
410 return pullAttributedAppOps(atomTag, data);
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000411 default:
412 throw new UnsupportedOperationException("Unknown tagId=" + atomTag);
413 }
414 } finally {
415 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800416 }
417 }
418 }
419
Tej Singh953ad862020-01-03 12:47:07 -0800420 @Override
421 public void onStart() {
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800422 // no op
423 }
424
425 @Override
426 public void onBootPhase(int phase) {
427 super.onBootPhase(phase);
428 if (phase == PHASE_SYSTEM_SERVICES_READY) {
429 BackgroundThread.getHandler().post(() -> {
Jeffrey Huang4c527162020-01-30 17:53:13 -0800430 nativeInit();
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800431 initializePullersState();
432 registerAllPullers();
433 registerEventListeners();
434 });
435 }
436 }
437
438 void initializePullersState() {
439 // Get Context Managers
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800440 mStatsManager = (StatsManager) mContext.getSystemService(Context.STATS_MANAGER);
Jeffrey Huang4df57402020-01-14 11:57:22 -0800441 mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
Jeffrey Huang1f818892020-01-14 12:05:05 -0800442 mTelephony = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -0800443 mStorageManager = (StorageManager) mContext.getSystemService(StorageManager.class);
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -0800444
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800445 // Initialize DiskIO
446 mStoragedUidIoStatsReader = new StoragedUidIoStatsReader();
Jeffrey Huangbf130832020-01-22 15:48:26 -0800447
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800448 // Initialize PROC_STATS
Jeffrey Huangb2cdb1a52020-02-24 15:26:13 -0800449 mBaseDir = new File(SystemServiceManager.ensureSystemDir(), "stats_pull");
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800450
451 // Disables throttler on CPU time readers.
452 mCpuUidUserSysTimeReader = new KernelCpuUidUserSysTimeReader(false);
453 mCpuUidFreqTimeReader = new KernelCpuUidFreqTimeReader(false);
454 mCpuUidActiveTimeReader = new KernelCpuUidActiveTimeReader(false);
455 mCpuUidClusterTimeReader = new KernelCpuUidClusterTimeReader(false);
456
457 // Initialize state for KERNEL_WAKELOCK
458 mKernelWakelockReader = new KernelWakelockReader();
459 mTmpWakelockStats = new KernelWakelockStats();
Jeffrey Huangbf130832020-01-22 15:48:26 -0800460
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800461 // Initialize state for CPU_TIME_PER_FREQ atom
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -0800462 PowerProfile powerProfile = new PowerProfile(mContext);
463 final int numClusters = powerProfile.getNumCpuClusters();
464 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters];
465 int firstCpuOfCluster = 0;
466 for (int i = 0; i < numClusters; i++) {
467 final int numSpeedSteps = powerProfile.getNumSpeedStepsInCpuCluster(i);
468 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster,
469 numSpeedSteps);
470 firstCpuOfCluster += powerProfile.getNumCoresInCpuCluster(i);
471 }
Jeffrey Huangbf4eef82020-01-16 15:38:58 -0800472
473 // Used for CPU_TIME_PER_THREAD_FREQ
474 mKernelCpuThreadReader =
475 KernelCpuThreadReaderSettingsObserver.getSettingsModifiedReader(mContext);
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800476
477 // Used by PROC_STATS and PROC_STATS_PKG_PROC atoms
478 mBaseDir.mkdirs();
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -0800479
480 // Initialize HealthService
481 mHealthService = new BatteryService.HealthServiceWrapper();
482 try {
483 mHealthService.init();
484 } catch (RemoteException e) {
485 Slog.e(TAG, "failed to initialize healthHalWrapper");
486 }
Tej Singh953ad862020-01-03 12:47:07 -0800487 }
488
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800489 void registerEventListeners() {
490 final ConnectivityManager connectivityManager =
491 (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
492 // Default NetworkRequest should cover all transport types.
493 final NetworkRequest request = new NetworkRequest.Builder().build();
494 connectivityManager.registerNetworkCallback(request, new ConnectivityStatsCallback());
495
496 // Enable push notifications of throttling from vendor thermal
497 // management subsystem via thermalservice.
498 IThermalService thermalService = getIThermalService();
499 if (thermalService != null) {
500 try {
501 thermalService.registerThermalEventListener(new ThermalEventListener());
502 Slog.i(TAG, "register thermal listener successfully");
503 } catch (RemoteException e) {
504 Slog.i(TAG, "failed to register thermal listener");
505 }
Tej Singh953ad862020-01-03 12:47:07 -0800506 }
507 }
508
509 void registerAllPullers() {
510 if (DEBUG) {
511 Slog.d(TAG, "Registering all pullers with statsd");
512 }
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800513 mStatsCallbackImpl = new StatsPullAtomCallbackImpl();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800514 registerWifiBytesTransfer();
515 registerWifiBytesTransferBackground();
516 registerMobileBytesTransfer();
517 registerMobileBytesTransferBackground();
518 registerBluetoothBytesTransfer();
519 registerKernelWakelock();
520 registerCpuTimePerFreq();
521 registerCpuTimePerUid();
522 registerCpuTimePerUidFreq();
523 registerCpuActiveTime();
524 registerCpuClusterTime();
525 registerWifiActivityInfo();
526 registerModemActivityInfo();
527 registerBluetoothActivityInfo();
528 registerSystemElapsedRealtime();
529 registerSystemUptime();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800530 registerProcessMemoryState();
531 registerProcessMemoryHighWaterMark();
532 registerProcessMemorySnapshot();
533 registerSystemIonHeapSize();
Rafal Slawikbdd5a502020-01-14 14:14:29 +0000534 registerIonHeapSize();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800535 registerProcessSystemIonHeapSize();
536 registerTemperature();
537 registerCoolingDevice();
Jeffrey Huang877adfe2020-01-15 17:16:43 -0800538 registerBinderCallsStats();
539 registerBinderCallsStatsExceptions();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800540 registerLooperStats();
541 registerDiskStats();
542 registerDirectoryUsage();
543 registerAppSize();
544 registerCategorySize();
545 registerNumFingerprintsEnrolled();
546 registerNumFacesEnrolled();
547 registerProcStats();
548 registerProcStatsPkgProc();
549 registerDiskIO();
550 registerPowerProfile();
551 registerProcessCpuTime();
552 registerCpuTimePerThreadFreq();
553 registerDeviceCalculatedPowerUse();
554 registerDeviceCalculatedPowerBlameUid();
555 registerDeviceCalculatedPowerBlameOther();
556 registerDebugElapsedClock();
557 registerDebugFailingElapsedClock();
558 registerBuildInformation();
559 registerRoleHolder();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800560 registerTimeZoneDataInfo();
561 registerExternalStorageInfo();
562 registerAppsOnExternalStorageInfo();
563 registerFaceSettings();
564 registerAppOps();
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -0800565 registerAttributedAppOps();
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +0000566 registerRuntimeAppOpAccessMessage();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800567 registerNotificationRemoteViews();
568 registerDangerousPermissionState();
569 registerDangerousPermissionStateSampled();
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -0800570 registerBatteryLevel();
Jeffrey Huang43f4d262020-01-30 14:03:31 -0800571 registerRemainingBatteryCapacity();
572 registerFullBatteryCapacity();
573 registerBatteryVoltage();
574 registerBatteryCycleCount();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800575 }
576
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800577 private INetworkStatsService getINetworkStatsService() {
578 synchronized (mNetworkStatsLock) {
579 if (mNetworkStatsService == null) {
580 mNetworkStatsService = INetworkStatsService.Stub.asInterface(
581 ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
582 if (mNetworkStatsService != null) {
583 try {
584 mNetworkStatsService.asBinder().linkToDeath(() -> {
585 synchronized (mNetworkStatsLock) {
586 mNetworkStatsService = null;
587 }
588 }, /* flags */ 0);
589 } catch (RemoteException e) {
590 Slog.e(TAG, "linkToDeath with NetworkStatsService failed", e);
591 mNetworkStatsService = null;
592 }
593 }
594
595 }
596 return mNetworkStatsService;
597 }
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800598 }
599
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800600 private IThermalService getIThermalService() {
601 synchronized (mThermalLock) {
602 if (mThermalService == null) {
603 mThermalService = IThermalService.Stub.asInterface(
604 ServiceManager.getService(Context.THERMAL_SERVICE));
605 if (mThermalService != null) {
606 try {
607 mThermalService.asBinder().linkToDeath(() -> {
608 synchronized (mThermalLock) {
609 mThermalService = null;
610 }
611 }, /* flags */ 0);
612 } catch (RemoteException e) {
613 Slog.e(TAG, "linkToDeath with thermalService failed", e);
614 mThermalService = null;
615 }
616 }
617 }
618 return mThermalService;
619 }
620 }
Jeffrey Huang95765f02020-01-16 11:33:58 -0800621
622 private IStoraged getIStoragedService() {
623 synchronized (mStoragedLock) {
624 if (mStorageService == null) {
625 mStorageService = IStoraged.Stub.asInterface(
626 ServiceManager.getService("storaged"));
627 }
628 if (mStorageService != null) {
629 try {
630 mStorageService.asBinder().linkToDeath(() -> {
631 synchronized (mStoragedLock) {
632 mStorageService = null;
633 }
634 }, /* flags */ 0);
635 } catch (RemoteException e) {
636 Slog.e(TAG, "linkToDeath with storagedService failed", e);
637 mStorageService = null;
638 }
639 }
640 }
641 return mStorageService;
642 }
643
Jeffrey Huang730bf962020-01-16 15:59:52 -0800644 private INotificationManager getINotificationManagerService() {
645 synchronized (mNotificationStatsLock) {
646 if (mNotificationManagerService == null) {
647 mNotificationManagerService = INotificationManager.Stub.asInterface(
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800648 ServiceManager.getService(Context.NOTIFICATION_SERVICE));
Jeffrey Huang730bf962020-01-16 15:59:52 -0800649 }
650 if (mNotificationManagerService != null) {
651 try {
652 mNotificationManagerService.asBinder().linkToDeath(() -> {
653 synchronized (mNotificationStatsLock) {
654 mNotificationManagerService = null;
655 }
656 }, /* flags */ 0);
657 } catch (RemoteException e) {
658 Slog.e(TAG, "linkToDeath with notificationManager failed", e);
659 mNotificationManagerService = null;
660 }
661 }
662 }
663 return mNotificationManagerService;
664 }
665
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800666 private IProcessStats getIProcessStatsService() {
667 synchronized (mProcessStatsLock) {
668 if (mProcessStatsService == null) {
669 mProcessStatsService = IProcessStats.Stub.asInterface(
670 ServiceManager.getService(ProcessStats.SERVICE_NAME));
671 }
672 if (mProcessStatsService != null) {
673 try {
674 mProcessStatsService.asBinder().linkToDeath(() -> {
675 synchronized (mProcessStatsLock) {
676 mProcessStatsService = null;
677 }
678 }, /* flags */ 0);
679 } catch (RemoteException e) {
680 Slog.e(TAG, "linkToDeath with ProcessStats failed", e);
681 mProcessStatsService = null;
682 }
683 }
684 }
685 return mProcessStatsService;
686 }
687
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800688 private void registerWifiBytesTransfer() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -0800689 int tagId = FrameworkStatsLog.WIFI_BYTES_TRANSFER;
Tej Singh6b979832020-01-02 15:23:02 -0800690 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800691 .setAdditiveFields(new int[] {2, 3, 4, 5})
692 .build();
Tej Singh72a70a82020-02-26 23:46:29 -0800693 mStatsManager.setPullAtomCallback(
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800694 tagId,
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800695 metadata,
Tej Singh6b979832020-01-02 15:23:02 -0800696 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800697 mStatsCallbackImpl
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800698 );
699 }
700
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800701 int pullWifiBytesTransfer(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800702 INetworkStatsService networkStatsService = getINetworkStatsService();
703 if (networkStatsService == null) {
704 Slog.e(TAG, "NetworkStats Service is not available!");
705 return StatsManager.PULL_SKIP;
706 }
707 long token = Binder.clearCallingIdentity();
708 try {
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800709 // TODO(b/148402814): Consider caching the following call to get BatteryStatsInternal.
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800710 BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class);
711 String[] ifaces = bs.getWifiIfaces();
712 if (ifaces.length == 0) {
713 return StatsManager.PULL_SKIP;
714 }
715 // Combine all the metrics per Uid into one record.
716 NetworkStats stats = networkStatsService.getDetailedUidStats(ifaces).groupedByUid();
717 addNetworkStats(atomTag, pulledData, stats, false);
718 } catch (RemoteException e) {
719 Slog.e(TAG, "Pulling netstats for wifi bytes has error", e);
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800720 return StatsManager.PULL_SKIP;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800721 } finally {
722 Binder.restoreCallingIdentity(token);
723 }
724 return StatsManager.PULL_SUCCESS;
725 }
726
727 private void addNetworkStats(
728 int tag, List<StatsEvent> ret, NetworkStats stats, boolean withFGBG) {
729 int size = stats.size();
730 NetworkStats.Entry entry = new NetworkStats.Entry(); // For recycling
731 for (int j = 0; j < size; j++) {
732 stats.getValues(j, entry);
733 StatsEvent.Builder e = StatsEvent.newBuilder();
734 e.setAtomId(tag);
735 e.writeInt(entry.uid);
736 if (withFGBG) {
737 e.writeInt(entry.set);
738 }
739 e.writeLong(entry.rxBytes);
740 e.writeLong(entry.rxPackets);
741 e.writeLong(entry.txBytes);
742 e.writeLong(entry.txPackets);
743 ret.add(e.build());
744 }
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800745 }
746
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800747 /**
748 * Allows rollups per UID but keeping the set (foreground/background) slicing.
749 * Adapted from groupedByUid in frameworks/base/core/java/android/net/NetworkStats.java
750 */
751 private NetworkStats rollupNetworkStatsByFGBG(NetworkStats stats) {
752 final NetworkStats ret = new NetworkStats(stats.getElapsedRealtime(), 1);
753
754 final NetworkStats.Entry entry = new NetworkStats.Entry();
755 entry.iface = NetworkStats.IFACE_ALL;
756 entry.tag = NetworkStats.TAG_NONE;
757 entry.metered = NetworkStats.METERED_ALL;
758 entry.roaming = NetworkStats.ROAMING_ALL;
759
760 int size = stats.size();
761 NetworkStats.Entry recycle = new NetworkStats.Entry(); // Used for retrieving values
762 for (int i = 0; i < size; i++) {
763 stats.getValues(i, recycle);
764
765 // Skip specific tags, since already counted in TAG_NONE
766 if (recycle.tag != NetworkStats.TAG_NONE) continue;
767
768 entry.set = recycle.set; // Allows slicing by background/foreground
769 entry.uid = recycle.uid;
770 entry.rxBytes = recycle.rxBytes;
771 entry.rxPackets = recycle.rxPackets;
772 entry.txBytes = recycle.txBytes;
773 entry.txPackets = recycle.txPackets;
774 // Operations purposefully omitted since we don't use them for statsd.
775 ret.combineValues(entry);
776 }
777 return ret;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800778 }
779
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800780 private void registerWifiBytesTransferBackground() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -0800781 int tagId = FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG;
Tej Singh6b979832020-01-02 15:23:02 -0800782 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800783 .setAdditiveFields(new int[] {3, 4, 5, 6})
784 .build();
Tej Singh72a70a82020-02-26 23:46:29 -0800785 mStatsManager.setPullAtomCallback(
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800786 tagId,
787 metadata,
Tej Singh6b979832020-01-02 15:23:02 -0800788 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800789 mStatsCallbackImpl
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800790 );
791 }
792
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800793 int pullWifiBytesTransferBackground(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800794 INetworkStatsService networkStatsService = getINetworkStatsService();
795 if (networkStatsService == null) {
796 Slog.e(TAG, "NetworkStats Service is not available!");
797 return StatsManager.PULL_SKIP;
798 }
799 long token = Binder.clearCallingIdentity();
800 try {
801 BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class);
802 String[] ifaces = bs.getWifiIfaces();
803 if (ifaces.length == 0) {
804 return StatsManager.PULL_SKIP;
805 }
806 NetworkStats stats = rollupNetworkStatsByFGBG(
807 networkStatsService.getDetailedUidStats(ifaces));
808 addNetworkStats(atomTag, pulledData, stats, true);
809 } catch (RemoteException e) {
810 Slog.e(TAG, "Pulling netstats for wifi bytes w/ fg/bg has error", e);
811 return StatsManager.PULL_SKIP;
812 } finally {
813 Binder.restoreCallingIdentity(token);
814 }
815 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800816 }
817
818 private void registerMobileBytesTransfer() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -0800819 int tagId = FrameworkStatsLog.MOBILE_BYTES_TRANSFER;
Tej Singh6b979832020-01-02 15:23:02 -0800820 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangc8785422020-01-10 15:54:53 -0800821 .setAdditiveFields(new int[] {2, 3, 4, 5})
822 .build();
Tej Singh72a70a82020-02-26 23:46:29 -0800823 mStatsManager.setPullAtomCallback(
Jeffrey Huangc8785422020-01-10 15:54:53 -0800824 tagId,
825 metadata,
Tej Singh6b979832020-01-02 15:23:02 -0800826 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800827 mStatsCallbackImpl
Jeffrey Huangc8785422020-01-10 15:54:53 -0800828 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800829 }
830
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800831 int pullMobileBytesTransfer(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangc8785422020-01-10 15:54:53 -0800832 INetworkStatsService networkStatsService = getINetworkStatsService();
833 if (networkStatsService == null) {
834 Slog.e(TAG, "NetworkStats Service is not available!");
835 return StatsManager.PULL_SKIP;
836 }
837 long token = Binder.clearCallingIdentity();
838 try {
839 BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class);
840 String[] ifaces = bs.getMobileIfaces();
841 if (ifaces.length == 0) {
842 return StatsManager.PULL_SKIP;
843 }
844 // Combine all the metrics per Uid into one record.
845 NetworkStats stats = networkStatsService.getDetailedUidStats(ifaces).groupedByUid();
846 addNetworkStats(atomTag, pulledData, stats, false);
847 } catch (RemoteException e) {
848 Slog.e(TAG, "Pulling netstats for mobile bytes has error", e);
849 return StatsManager.PULL_SKIP;
850 } finally {
851 Binder.restoreCallingIdentity(token);
852 }
853 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800854 }
855
856 private void registerMobileBytesTransferBackground() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -0800857 int tagId = FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG;
Tej Singh6b979832020-01-02 15:23:02 -0800858 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huang89864442020-01-10 16:35:51 -0800859 .setAdditiveFields(new int[] {3, 4, 5, 6})
860 .build();
Tej Singh72a70a82020-02-26 23:46:29 -0800861 mStatsManager.setPullAtomCallback(
Jeffrey Huang89864442020-01-10 16:35:51 -0800862 tagId,
863 metadata,
Tej Singh6b979832020-01-02 15:23:02 -0800864 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800865 mStatsCallbackImpl
Jeffrey Huang89864442020-01-10 16:35:51 -0800866 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800867 }
868
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800869 int pullMobileBytesTransferBackground(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang89864442020-01-10 16:35:51 -0800870 INetworkStatsService networkStatsService = getINetworkStatsService();
871 if (networkStatsService == null) {
872 Slog.e(TAG, "NetworkStats Service is not available!");
873 return StatsManager.PULL_SKIP;
874 }
875 long token = Binder.clearCallingIdentity();
876 try {
877 BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class);
878 String[] ifaces = bs.getMobileIfaces();
879 if (ifaces.length == 0) {
880 return StatsManager.PULL_SKIP;
881 }
882 NetworkStats stats = rollupNetworkStatsByFGBG(
883 networkStatsService.getDetailedUidStats(ifaces));
884 addNetworkStats(atomTag, pulledData, stats, true);
885 } catch (RemoteException e) {
886 Slog.e(TAG, "Pulling netstats for mobile bytes w/ fg/bg has error", e);
887 return StatsManager.PULL_SKIP;
888 } finally {
889 Binder.restoreCallingIdentity(token);
890 }
891 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800892 }
893
894 private void registerBluetoothBytesTransfer() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -0800895 int tagId = FrameworkStatsLog.BLUETOOTH_BYTES_TRANSFER;
Tej Singh6b979832020-01-02 15:23:02 -0800896 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangfa917892020-01-10 16:58:03 -0800897 .setAdditiveFields(new int[] {2, 3})
898 .build();
Tej Singh72a70a82020-02-26 23:46:29 -0800899 mStatsManager.setPullAtomCallback(
Jeffrey Huangfa917892020-01-10 16:58:03 -0800900 tagId,
901 metadata,
Tej Singh6b979832020-01-02 15:23:02 -0800902 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800903 mStatsCallbackImpl
Jeffrey Huangfa917892020-01-10 16:58:03 -0800904 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800905 }
906
Jeffrey Huangfa917892020-01-10 16:58:03 -0800907 /**
908 * Helper method to extract the Parcelable controller info from a
909 * SynchronousResultReceiver.
910 */
911 private static <T extends Parcelable> T awaitControllerInfo(
912 @Nullable SynchronousResultReceiver receiver) {
913 if (receiver == null) {
914 return null;
915 }
916
917 try {
918 final SynchronousResultReceiver.Result result =
919 receiver.awaitResult(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS);
920 if (result.bundle != null) {
921 // This is the final destination for the Bundle.
922 result.bundle.setDefusable(true);
923
924 final T data = result.bundle.getParcelable(RESULT_RECEIVER_CONTROLLER_KEY);
925 if (data != null) {
926 return data;
927 }
928 }
Jeffrey Huangfa917892020-01-10 16:58:03 -0800929 } catch (TimeoutException e) {
930 Slog.w(TAG, "timeout reading " + receiver.getName() + " stats");
931 }
932 return null;
933 }
934
935 private synchronized BluetoothActivityEnergyInfo fetchBluetoothData() {
936 // TODO: Investigate whether the synchronized keyword is needed.
937 final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
938 if (adapter != null) {
939 SynchronousResultReceiver bluetoothReceiver = new SynchronousResultReceiver(
940 "bluetooth");
941 adapter.requestControllerActivityEnergyInfo(bluetoothReceiver);
942 return awaitControllerInfo(bluetoothReceiver);
943 } else {
944 Slog.e(TAG, "Failed to get bluetooth adapter!");
945 return null;
946 }
947 }
948
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800949 int pullBluetoothBytesTransfer(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangfa917892020-01-10 16:58:03 -0800950 BluetoothActivityEnergyInfo info = fetchBluetoothData();
951 if (info == null || info.getUidTraffic() == null) {
952 return StatsManager.PULL_SKIP;
953 }
954 for (UidTraffic traffic : info.getUidTraffic()) {
955 StatsEvent e = StatsEvent.newBuilder()
956 .setAtomId(atomTag)
957 .writeInt(traffic.getUid())
958 .writeLong(traffic.getRxBytes())
959 .writeLong(traffic.getTxBytes())
960 .build();
961 pulledData.add(e);
962 }
963 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800964 }
965
966 private void registerKernelWakelock() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -0800967 int tagId = FrameworkStatsLog.KERNEL_WAKELOCK;
Tej Singh72a70a82020-02-26 23:46:29 -0800968 mStatsManager.setPullAtomCallback(
Jeffrey Huanga6e5a9b2020-01-13 15:59:16 -0800969 tagId,
970 /* PullAtomMetadata */ null,
Tej Singh6b979832020-01-02 15:23:02 -0800971 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800972 mStatsCallbackImpl
Jeffrey Huanga6e5a9b2020-01-13 15:59:16 -0800973 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800974 }
975
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800976 int pullKernelWakelock(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huanga6e5a9b2020-01-13 15:59:16 -0800977 final KernelWakelockStats wakelockStats =
978 mKernelWakelockReader.readKernelWakelockStats(mTmpWakelockStats);
979 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) {
980 String name = ent.getKey();
981 KernelWakelockStats.Entry kws = ent.getValue();
982 StatsEvent e = StatsEvent.newBuilder()
983 .setAtomId(atomTag)
984 .writeString(name)
985 .writeInt(kws.mCount)
986 .writeInt(kws.mVersion)
987 .writeLong(kws.mTotalTime)
988 .build();
989 pulledData.add(e);
990 }
991 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800992 }
993
994 private void registerCpuTimePerFreq() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -0800995 int tagId = FrameworkStatsLog.CPU_TIME_PER_FREQ;
Tej Singh6b979832020-01-02 15:23:02 -0800996 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -0800997 .setAdditiveFields(new int[] {3})
998 .build();
Tej Singh72a70a82020-02-26 23:46:29 -0800999 mStatsManager.setPullAtomCallback(
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -08001000 tagId,
1001 metadata,
Tej Singh6b979832020-01-02 15:23:02 -08001002 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001003 mStatsCallbackImpl
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -08001004 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001005 }
1006
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001007 int pullCpuTimePerFreq(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -08001008 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) {
1009 long[] clusterTimeMs = mKernelCpuSpeedReaders[cluster].readAbsolute();
1010 if (clusterTimeMs != null) {
1011 for (int speed = clusterTimeMs.length - 1; speed >= 0; --speed) {
1012 StatsEvent e = StatsEvent.newBuilder()
1013 .setAtomId(atomTag)
1014 .writeInt(cluster)
1015 .writeInt(speed)
1016 .writeLong(clusterTimeMs[speed])
1017 .build();
1018 pulledData.add(e);
1019 }
1020 }
1021 }
1022 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001023 }
1024
1025 private void registerCpuTimePerUid() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001026 int tagId = FrameworkStatsLog.CPU_TIME_PER_UID;
Tej Singh6b979832020-01-02 15:23:02 -08001027 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangd5f053e2020-01-13 16:27:53 -08001028 .setAdditiveFields(new int[] {2, 3})
1029 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001030 mStatsManager.setPullAtomCallback(
Jeffrey Huangd5f053e2020-01-13 16:27:53 -08001031 tagId,
1032 metadata,
Tej Singh6b979832020-01-02 15:23:02 -08001033 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001034 mStatsCallbackImpl
Jeffrey Huangd5f053e2020-01-13 16:27:53 -08001035 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001036 }
1037
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001038 int pullCpuTimePerUid(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangd5f053e2020-01-13 16:27:53 -08001039 mCpuUidUserSysTimeReader.readAbsolute((uid, timesUs) -> {
1040 long userTimeUs = timesUs[0], systemTimeUs = timesUs[1];
1041 StatsEvent e = StatsEvent.newBuilder()
1042 .setAtomId(atomTag)
1043 .writeInt(uid)
1044 .writeLong(userTimeUs)
1045 .writeLong(systemTimeUs)
1046 .build();
1047 pulledData.add(e);
1048 });
1049 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001050 }
1051
1052 private void registerCpuTimePerUidFreq() {
Jeffrey Huanga9899302020-01-13 16:34:03 -08001053 // the throttling is 3sec, handled in
1054 // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001055 int tagId = FrameworkStatsLog.CPU_TIME_PER_UID_FREQ;
Tej Singh6b979832020-01-02 15:23:02 -08001056 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huanga9899302020-01-13 16:34:03 -08001057 .setAdditiveFields(new int[] {4})
1058 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001059 mStatsManager.setPullAtomCallback(
Jeffrey Huanga9899302020-01-13 16:34:03 -08001060 tagId,
1061 metadata,
Tej Singh6b979832020-01-02 15:23:02 -08001062 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001063 mStatsCallbackImpl
Jeffrey Huanga9899302020-01-13 16:34:03 -08001064 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001065 }
1066
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001067 int pullCpuTimeperUidFreq(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huanga9899302020-01-13 16:34:03 -08001068 mCpuUidFreqTimeReader.readAbsolute((uid, cpuFreqTimeMs) -> {
1069 for (int freqIndex = 0; freqIndex < cpuFreqTimeMs.length; ++freqIndex) {
1070 if (cpuFreqTimeMs[freqIndex] != 0) {
1071 StatsEvent e = StatsEvent.newBuilder()
1072 .setAtomId(atomTag)
1073 .writeInt(uid)
1074 .writeInt(freqIndex)
1075 .writeLong(cpuFreqTimeMs[freqIndex])
1076 .build();
1077 pulledData.add(e);
1078 }
1079 }
1080 });
1081 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001082 }
1083
1084 private void registerCpuActiveTime() {
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001085 // the throttling is 3sec, handled in
1086 // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001087 int tagId = FrameworkStatsLog.CPU_ACTIVE_TIME;
Tej Singh6b979832020-01-02 15:23:02 -08001088 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001089 .setAdditiveFields(new int[] {2})
1090 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001091 mStatsManager.setPullAtomCallback(
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001092 tagId,
1093 metadata,
Tej Singh6b979832020-01-02 15:23:02 -08001094 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001095 mStatsCallbackImpl
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001096 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001097 }
1098
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001099 int pullCpuActiveTime(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001100 mCpuUidActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> {
1101 StatsEvent e = StatsEvent.newBuilder()
1102 .setAtomId(atomTag)
1103 .writeInt(uid)
1104 .writeLong(cpuActiveTimesMs)
1105 .build();
1106 pulledData.add(e);
1107 });
1108 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001109 }
1110
1111 private void registerCpuClusterTime() {
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001112 // the throttling is 3sec, handled in
1113 // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001114 int tagId = FrameworkStatsLog.CPU_CLUSTER_TIME;
Tej Singh6b979832020-01-02 15:23:02 -08001115 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001116 .setAdditiveFields(new int[] {3})
1117 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001118 mStatsManager.setPullAtomCallback(
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001119 tagId,
1120 metadata,
Tej Singh6b979832020-01-02 15:23:02 -08001121 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001122 mStatsCallbackImpl
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001123 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001124 }
1125
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001126 int pullCpuClusterTime(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001127 mCpuUidClusterTimeReader.readAbsolute((uid, cpuClusterTimesMs) -> {
1128 for (int i = 0; i < cpuClusterTimesMs.length; i++) {
1129 StatsEvent e = StatsEvent.newBuilder()
1130 .setAtomId(atomTag)
1131 .writeInt(uid)
1132 .writeInt(i)
1133 .writeLong(cpuClusterTimesMs[i])
1134 .build();
1135 pulledData.add(e);
1136 }
1137 });
1138 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001139 }
1140
1141 private void registerWifiActivityInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001142 int tagId = FrameworkStatsLog.WIFI_ACTIVITY_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08001143 mStatsManager.setPullAtomCallback(
Jeffrey Huang4df57402020-01-14 11:57:22 -08001144 tagId,
1145 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001146 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001147 mStatsCallbackImpl
Jeffrey Huang4df57402020-01-14 11:57:22 -08001148 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001149 }
1150
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001151 int pullWifiActivityInfo(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang4df57402020-01-14 11:57:22 -08001152 long token = Binder.clearCallingIdentity();
1153 try {
1154 SynchronousResultReceiver wifiReceiver = new SynchronousResultReceiver("wifi");
1155 mWifiManager.getWifiActivityEnergyInfoAsync(
1156 new Executor() {
1157 @Override
1158 public void execute(Runnable runnable) {
1159 // run the listener on the binder thread, if it was run on the main
1160 // thread it would deadlock since we would be waiting on ourselves
1161 runnable.run();
1162 }
1163 },
1164 info -> {
1165 Bundle bundle = new Bundle();
1166 bundle.putParcelable(BatteryStats.RESULT_RECEIVER_CONTROLLER_KEY, info);
1167 wifiReceiver.send(0, bundle);
1168 }
1169 );
1170 final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver);
1171 if (wifiInfo == null) {
1172 return StatsManager.PULL_SKIP;
1173 }
1174 StatsEvent e = StatsEvent.newBuilder()
1175 .setAtomId(atomTag)
1176 .writeLong(wifiInfo.getTimeSinceBootMillis())
1177 .writeInt(wifiInfo.getStackState())
1178 .writeLong(wifiInfo.getControllerTxDurationMillis())
1179 .writeLong(wifiInfo.getControllerRxDurationMillis())
1180 .writeLong(wifiInfo.getControllerIdleDurationMillis())
1181 .writeLong(wifiInfo.getControllerEnergyUsedMicroJoules())
1182 .build();
1183 pulledData.add(e);
1184 } catch (RuntimeException e) {
1185 Slog.e(TAG, "failed to getWifiActivityEnergyInfoAsync", e);
1186 return StatsManager.PULL_SKIP;
1187 } finally {
1188 Binder.restoreCallingIdentity(token);
1189 }
1190 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001191 }
1192
1193 private void registerModemActivityInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001194 int tagId = FrameworkStatsLog.MODEM_ACTIVITY_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08001195 mStatsManager.setPullAtomCallback(
Jeffrey Huang1f818892020-01-14 12:05:05 -08001196 tagId,
1197 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001198 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001199 mStatsCallbackImpl
Jeffrey Huang1f818892020-01-14 12:05:05 -08001200 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001201 }
1202
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001203 int pullModemActivityInfo(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang1f818892020-01-14 12:05:05 -08001204 long token = Binder.clearCallingIdentity();
1205 try {
1206 SynchronousResultReceiver modemReceiver = new SynchronousResultReceiver("telephony");
1207 mTelephony.requestModemActivityInfo(modemReceiver);
1208 final ModemActivityInfo modemInfo = awaitControllerInfo(modemReceiver);
1209 if (modemInfo == null) {
1210 return StatsManager.PULL_SKIP;
1211 }
1212 StatsEvent e = StatsEvent.newBuilder()
1213 .setAtomId(atomTag)
1214 .writeLong(modemInfo.getTimestamp())
1215 .writeLong(modemInfo.getSleepTimeMillis())
1216 .writeLong(modemInfo.getIdleTimeMillis())
1217 .writeLong(modemInfo.getTransmitPowerInfo().get(0).getTimeInMillis())
1218 .writeLong(modemInfo.getTransmitPowerInfo().get(1).getTimeInMillis())
1219 .writeLong(modemInfo.getTransmitPowerInfo().get(2).getTimeInMillis())
1220 .writeLong(modemInfo.getTransmitPowerInfo().get(3).getTimeInMillis())
1221 .writeLong(modemInfo.getTransmitPowerInfo().get(4).getTimeInMillis())
1222 .writeLong(modemInfo.getReceiveTimeMillis())
1223 .build();
1224 pulledData.add(e);
1225 } finally {
1226 Binder.restoreCallingIdentity(token);
1227 }
1228 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001229 }
1230
1231 private void registerBluetoothActivityInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001232 int tagId = FrameworkStatsLog.BLUETOOTH_ACTIVITY_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08001233 mStatsManager.setPullAtomCallback(
Jeffrey Huangaafccb32020-01-13 10:16:58 -08001234 tagId,
1235 /* metadata */ null,
Tej Singh6b979832020-01-02 15:23:02 -08001236 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001237 mStatsCallbackImpl
Jeffrey Huangaafccb32020-01-13 10:16:58 -08001238 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001239 }
1240
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001241 int pullBluetoothActivityInfo(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangaafccb32020-01-13 10:16:58 -08001242 BluetoothActivityEnergyInfo info = fetchBluetoothData();
1243 if (info == null) {
1244 return StatsManager.PULL_SKIP;
1245 }
1246 StatsEvent e = StatsEvent.newBuilder()
1247 .setAtomId(atomTag)
1248 .writeLong(info.getTimeStamp())
1249 .writeInt(info.getBluetoothStackState())
1250 .writeLong(info.getControllerTxTimeMillis())
1251 .writeLong(info.getControllerRxTimeMillis())
1252 .writeLong(info.getControllerIdleTimeMillis())
1253 .writeLong(info.getControllerEnergyUsed())
1254 .build();
1255 pulledData.add(e);
1256 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001257 }
1258
1259 private void registerSystemElapsedRealtime() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001260 int tagId = FrameworkStatsLog.SYSTEM_ELAPSED_REALTIME;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001261 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Tej Singh72a70a82020-02-26 23:46:29 -08001262 .setCoolDownMillis(MILLIS_PER_SEC)
1263 .setTimeoutMillis(MILLIS_PER_SEC / 2)
Jeffrey Huang882f99a2020-01-14 14:33:52 -08001264 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001265 mStatsManager.setPullAtomCallback(
Jeffrey Huang882f99a2020-01-14 14:33:52 -08001266 tagId,
1267 metadata,
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001268 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001269 mStatsCallbackImpl
Jeffrey Huang882f99a2020-01-14 14:33:52 -08001270 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001271 }
1272
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001273 int pullSystemElapsedRealtime(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang882f99a2020-01-14 14:33:52 -08001274 StatsEvent e = StatsEvent.newBuilder()
1275 .setAtomId(atomTag)
1276 .writeLong(SystemClock.elapsedRealtime())
1277 .build();
1278 pulledData.add(e);
1279 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001280 }
1281
1282 private void registerSystemUptime() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001283 int tagId = FrameworkStatsLog.SYSTEM_UPTIME;
Tej Singh72a70a82020-02-26 23:46:29 -08001284 mStatsManager.setPullAtomCallback(
Ruchir Rastogice29fc12020-01-09 17:08:20 -08001285 tagId,
1286 null, // use default PullAtomMetadata values
Tej Singh6b979832020-01-02 15:23:02 -08001287 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001288 mStatsCallbackImpl
Ruchir Rastogice29fc12020-01-09 17:08:20 -08001289 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001290 }
1291
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001292 int pullSystemUptime(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogice29fc12020-01-09 17:08:20 -08001293 StatsEvent e = StatsEvent.newBuilder()
1294 .setAtomId(atomTag)
1295 .writeLong(SystemClock.elapsedRealtime())
1296 .build();
1297 pulledData.add(e);
1298 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001299 }
1300
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001301 private void registerProcessMemoryState() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001302 int tagId = FrameworkStatsLog.PROCESS_MEMORY_STATE;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001303 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001304 .setAdditiveFields(new int[] {4, 5, 6, 7, 8})
1305 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001306 mStatsManager.setPullAtomCallback(
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001307 tagId,
1308 metadata,
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001309 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001310 mStatsCallbackImpl
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001311 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001312 }
1313
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001314 int pullProcessMemoryState(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001315 List<ProcessMemoryState> processMemoryStates =
1316 LocalServices.getService(ActivityManagerInternal.class)
1317 .getMemoryStateForProcesses();
1318 for (ProcessMemoryState processMemoryState : processMemoryStates) {
1319 final MemoryStat memoryStat = readMemoryStatFromFilesystem(processMemoryState.uid,
1320 processMemoryState.pid);
1321 if (memoryStat == null) {
1322 continue;
1323 }
1324 StatsEvent e = StatsEvent.newBuilder()
1325 .setAtomId(atomTag)
1326 .writeInt(processMemoryState.uid)
1327 .writeString(processMemoryState.processName)
1328 .writeInt(processMemoryState.oomScore)
1329 .writeLong(memoryStat.pgfault)
1330 .writeLong(memoryStat.pgmajfault)
1331 .writeLong(memoryStat.rssInBytes)
1332 .writeLong(memoryStat.cacheInBytes)
1333 .writeLong(memoryStat.swapInBytes)
1334 .writeLong(-1) // unused
1335 .writeLong(-1) // unused
1336 .writeInt(-1) // unused
1337 .build();
1338 pulledData.add(e);
1339 }
1340 return StatsManager.PULL_SUCCESS;
1341 }
1342
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001343 private static boolean isAppUid(int uid) {
1344 return uid >= MIN_APP_UID;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001345 }
1346
1347 private void registerProcessMemoryHighWaterMark() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001348 int tagId = FrameworkStatsLog.PROCESS_MEMORY_HIGH_WATER_MARK;
Tej Singh72a70a82020-02-26 23:46:29 -08001349 mStatsManager.setPullAtomCallback(
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001350 tagId,
1351 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001352 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001353 mStatsCallbackImpl
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001354 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001355 }
1356
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001357 int pullProcessMemoryHighWaterMark(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001358 List<ProcessMemoryState> managedProcessList =
1359 LocalServices.getService(ActivityManagerInternal.class)
1360 .getMemoryStateForProcesses();
1361 for (ProcessMemoryState managedProcess : managedProcessList) {
1362 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(managedProcess.pid);
1363 if (snapshot == null) {
1364 continue;
1365 }
1366 StatsEvent e = StatsEvent.newBuilder()
1367 .setAtomId(atomTag)
1368 .writeInt(managedProcess.uid)
1369 .writeString(managedProcess.processName)
1370 // RSS high-water mark in bytes.
1371 .writeLong(snapshot.rssHighWaterMarkInKilobytes * 1024L)
1372 .writeInt(snapshot.rssHighWaterMarkInKilobytes)
1373 .build();
1374 pulledData.add(e);
1375 }
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001376 // Complement the data with native system processes
1377 SparseArray<String> processCmdlines = getProcessCmdlines();
1378 managedProcessList.forEach(managedProcess -> processCmdlines.delete(managedProcess.pid));
1379 int size = processCmdlines.size();
1380 for (int i = 0; i < size; ++i) {
1381 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(processCmdlines.keyAt(i));
1382 if (snapshot == null || isAppUid(snapshot.uid)) {
1383 continue;
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001384 }
1385 StatsEvent e = StatsEvent.newBuilder()
1386 .setAtomId(atomTag)
1387 .writeInt(snapshot.uid)
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001388 .writeString(processCmdlines.valueAt(i))
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001389 // RSS high-water mark in bytes.
1390 .writeLong(snapshot.rssHighWaterMarkInKilobytes * 1024L)
1391 .writeInt(snapshot.rssHighWaterMarkInKilobytes)
1392 .build();
1393 pulledData.add(e);
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001394 }
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001395 // Invoke rss_hwm_reset binary to reset RSS HWM counters for all processes.
1396 SystemProperties.set("sys.rss_hwm_reset.on", "1");
1397 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001398 }
1399
1400 private void registerProcessMemorySnapshot() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001401 int tagId = FrameworkStatsLog.PROCESS_MEMORY_SNAPSHOT;
Tej Singh72a70a82020-02-26 23:46:29 -08001402 mStatsManager.setPullAtomCallback(
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001403 tagId,
1404 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001405 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001406 mStatsCallbackImpl
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001407 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001408 }
1409
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001410 int pullProcessMemorySnapshot(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001411 List<ProcessMemoryState> managedProcessList =
1412 LocalServices.getService(ActivityManagerInternal.class)
1413 .getMemoryStateForProcesses();
1414 for (ProcessMemoryState managedProcess : managedProcessList) {
1415 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(managedProcess.pid);
1416 if (snapshot == null) {
1417 continue;
1418 }
1419 StatsEvent e = StatsEvent.newBuilder()
Ioannis Ilkosda5d8812020-01-27 16:04:10 +00001420 .setAtomId(atomTag)
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001421 .writeInt(managedProcess.uid)
1422 .writeString(managedProcess.processName)
1423 .writeInt(managedProcess.pid)
1424 .writeInt(managedProcess.oomScore)
1425 .writeInt(snapshot.rssInKilobytes)
1426 .writeInt(snapshot.anonRssInKilobytes)
1427 .writeInt(snapshot.swapInKilobytes)
1428 .writeInt(snapshot.anonRssInKilobytes + snapshot.swapInKilobytes)
1429 .build();
1430 pulledData.add(e);
1431 }
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001432 // Complement the data with native system processes. Given these measurements can be taken
1433 // in response to LMKs happening, we want to first collect the managed app stats (to
1434 // maximize the probability that a heavyweight process will be sampled before it dies).
1435 SparseArray<String> processCmdlines = getProcessCmdlines();
1436 managedProcessList.forEach(managedProcess -> processCmdlines.delete(managedProcess.pid));
1437 int size = processCmdlines.size();
1438 for (int i = 0; i < size; ++i) {
1439 int pid = processCmdlines.keyAt(i);
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001440 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(pid);
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001441 if (snapshot == null || isAppUid(snapshot.uid)) {
1442 continue;
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001443 }
1444 StatsEvent e = StatsEvent.newBuilder()
1445 .setAtomId(atomTag)
1446 .writeInt(snapshot.uid)
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001447 .writeString(processCmdlines.valueAt(i))
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001448 .writeInt(pid)
1449 .writeInt(-1001) // Placeholder for native processes, OOM_SCORE_ADJ_MIN - 1.
1450 .writeInt(snapshot.rssInKilobytes)
1451 .writeInt(snapshot.anonRssInKilobytes)
1452 .writeInt(snapshot.swapInKilobytes)
1453 .writeInt(snapshot.anonRssInKilobytes + snapshot.swapInKilobytes)
1454 .build();
1455 pulledData.add(e);
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001456 }
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001457 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001458 }
1459
1460 private void registerSystemIonHeapSize() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001461 int tagId = FrameworkStatsLog.SYSTEM_ION_HEAP_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08001462 mStatsManager.setPullAtomCallback(
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001463 tagId,
1464 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001465 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001466 mStatsCallbackImpl
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001467 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001468 }
1469
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001470 int pullSystemIonHeapSize(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001471 final long systemIonHeapSizeInBytes = readSystemIonHeapSizeFromDebugfs();
1472 StatsEvent e = StatsEvent.newBuilder()
1473 .setAtomId(atomTag)
1474 .writeLong(systemIonHeapSizeInBytes)
1475 .build();
1476 pulledData.add(e);
1477 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001478 }
1479
Rafal Slawikbdd5a502020-01-14 14:14:29 +00001480 private void registerIonHeapSize() {
Rafal Slawikded83052020-02-28 13:20:13 +00001481 if (!new File("/sys/kernel/ion/total_heaps_kb").exists()) {
1482 return;
1483 }
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001484 int tagId = FrameworkStatsLog.ION_HEAP_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08001485 mStatsManager.setPullAtomCallback(
Rafal Slawikbdd5a502020-01-14 14:14:29 +00001486 tagId,
1487 /* PullAtomMetadata */ null,
Tej Singh6b979832020-01-02 15:23:02 -08001488 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001489 mStatsCallbackImpl
Rafal Slawikbdd5a502020-01-14 14:14:29 +00001490 );
1491 }
1492
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001493 int pullIonHeapSize(int atomTag, List<StatsEvent> pulledData) {
Rafal Slawikbdd5a502020-01-14 14:14:29 +00001494 int ionHeapSizeInKilobytes = (int) getIonHeapsSizeKb();
1495 StatsEvent e = StatsEvent.newBuilder()
1496 .setAtomId(atomTag)
1497 .writeInt(ionHeapSizeInKilobytes)
1498 .build();
1499 pulledData.add(e);
1500 return StatsManager.PULL_SUCCESS;
1501 }
1502
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001503 private void registerProcessSystemIonHeapSize() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001504 int tagId = FrameworkStatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08001505 mStatsManager.setPullAtomCallback(
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001506 tagId,
1507 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001508 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001509 mStatsCallbackImpl
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001510 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001511 }
1512
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001513 int pullProcessSystemIonHeapSize(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001514 List<IonAllocations> result = readProcessSystemIonHeapSizesFromDebugfs();
1515 for (IonAllocations allocations : result) {
1516 StatsEvent e = StatsEvent.newBuilder()
1517 .setAtomId(atomTag)
1518 .writeInt(getUidForPid(allocations.pid))
1519 .writeString(readCmdlineFromProcfs(allocations.pid))
1520 .writeInt((int) (allocations.totalSizeInBytes / 1024))
1521 .writeInt(allocations.count)
1522 .writeInt((int) (allocations.maxSizeInBytes / 1024))
1523 .build();
1524 pulledData.add(e);
1525 }
1526 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001527 }
1528
1529 private void registerTemperature() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001530 int tagId = FrameworkStatsLog.TEMPERATURE;
Tej Singh72a70a82020-02-26 23:46:29 -08001531 mStatsManager.setPullAtomCallback(
Jeffrey Huangb92de552020-01-15 16:50:07 -08001532 tagId,
1533 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001534 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001535 mStatsCallbackImpl
Jeffrey Huangb92de552020-01-15 16:50:07 -08001536 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001537 }
1538
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001539 int pullTemperature(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb92de552020-01-15 16:50:07 -08001540 IThermalService thermalService = getIThermalService();
1541 if (thermalService == null) {
1542 return StatsManager.PULL_SKIP;
1543 }
1544 final long callingToken = Binder.clearCallingIdentity();
1545 try {
Chris Ye48dbcaa2020-02-10 13:29:01 -08001546 Temperature temperatures[] = thermalService.getCurrentTemperatures();
Jeffrey Huangb92de552020-01-15 16:50:07 -08001547 for (Temperature temp : temperatures) {
1548 StatsEvent e = StatsEvent.newBuilder()
1549 .setAtomId(atomTag)
1550 .writeInt(temp.getType())
1551 .writeString(temp.getName())
1552 .writeInt((int) (temp.getValue() * 10))
1553 .writeInt(temp.getStatus())
1554 .build();
1555 pulledData.add(e);
1556 }
1557 } catch (RemoteException e) {
1558 // Should not happen.
1559 Slog.e(TAG, "Disconnected from thermal service. Cannot pull temperatures.");
1560 return StatsManager.PULL_SKIP;
1561 } finally {
1562 Binder.restoreCallingIdentity(callingToken);
1563 }
1564 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001565 }
1566
1567 private void registerCoolingDevice() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001568 int tagId = FrameworkStatsLog.COOLING_DEVICE;
Tej Singh72a70a82020-02-26 23:46:29 -08001569 mStatsManager.setPullAtomCallback(
Jeffrey Huangb92de552020-01-15 16:50:07 -08001570 tagId,
1571 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001572 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001573 mStatsCallbackImpl
Jeffrey Huangb92de552020-01-15 16:50:07 -08001574 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001575 }
1576
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001577 int pullCooldownDevice(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb92de552020-01-15 16:50:07 -08001578 IThermalService thermalService = getIThermalService();
1579 if (thermalService == null) {
1580 return StatsManager.PULL_SKIP;
1581 }
1582 final long callingToken = Binder.clearCallingIdentity();
1583 try {
Chris Ye48dbcaa2020-02-10 13:29:01 -08001584 CoolingDevice devices[] = thermalService.getCurrentCoolingDevices();
Jeffrey Huangb92de552020-01-15 16:50:07 -08001585 for (CoolingDevice device : devices) {
1586 StatsEvent e = StatsEvent.newBuilder()
1587 .setAtomId(atomTag)
1588 .writeInt(device.getType())
1589 .writeString(device.getName())
1590 .writeInt((int) (device.getValue()))
1591 .build();
1592 pulledData.add(e);
1593 }
1594 } catch (RemoteException e) {
1595 // Should not happen.
1596 Slog.e(TAG, "Disconnected from thermal service. Cannot pull temperatures.");
1597 return StatsManager.PULL_SKIP;
1598 } finally {
1599 Binder.restoreCallingIdentity(callingToken);
1600 }
1601 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001602 }
1603
Jeffrey Huang877adfe2020-01-15 17:16:43 -08001604 private void registerBinderCallsStats() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001605 int tagId = FrameworkStatsLog.BINDER_CALLS;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001606 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huang877adfe2020-01-15 17:16:43 -08001607 .setAdditiveFields(new int[] {4, 5, 6, 8, 12})
1608 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001609 mStatsManager.setPullAtomCallback(
Jeffrey Huang877adfe2020-01-15 17:16:43 -08001610 tagId,
1611 metadata,
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001612 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001613 mStatsCallbackImpl
Jeffrey Huang877adfe2020-01-15 17:16:43 -08001614 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001615 }
1616
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001617 int pullBinderCallsStats(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang877adfe2020-01-15 17:16:43 -08001618 BinderCallsStatsService.Internal binderStats =
1619 LocalServices.getService(BinderCallsStatsService.Internal.class);
1620 if (binderStats == null) {
1621 Slog.e(TAG, "failed to get binderStats");
1622 return StatsManager.PULL_SKIP;
1623 }
1624
1625 List<ExportedCallStat> callStats = binderStats.getExportedCallStats();
1626 binderStats.reset();
1627 for (ExportedCallStat callStat : callStats) {
1628 StatsEvent e = StatsEvent.newBuilder()
1629 .setAtomId(atomTag)
1630 .writeInt(callStat.workSourceUid)
1631 .writeString(callStat.className)
1632 .writeString(callStat.methodName)
1633 .writeLong(callStat.callCount)
1634 .writeLong(callStat.exceptionCount)
1635 .writeLong(callStat.latencyMicros)
1636 .writeLong(callStat.maxLatencyMicros)
1637 .writeLong(callStat.cpuTimeMicros)
1638 .writeLong(callStat.maxCpuTimeMicros)
1639 .writeLong(callStat.maxReplySizeBytes)
1640 .writeLong(callStat.maxRequestSizeBytes)
1641 .writeLong(callStat.recordedCallCount)
1642 .writeInt(callStat.screenInteractive ? 1 : 0)
1643 .writeInt(callStat.callingUid)
1644 .build();
1645 pulledData.add(e);
1646 }
1647 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001648 }
1649
Jeffrey Huang877adfe2020-01-15 17:16:43 -08001650 private void registerBinderCallsStatsExceptions() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001651 int tagId = FrameworkStatsLog.BINDER_CALLS_EXCEPTIONS;
Tej Singh72a70a82020-02-26 23:46:29 -08001652 mStatsManager.setPullAtomCallback(
Jeffrey Huang877adfe2020-01-15 17:16:43 -08001653 tagId,
1654 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001655 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001656 mStatsCallbackImpl
Jeffrey Huang877adfe2020-01-15 17:16:43 -08001657 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001658 }
1659
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001660 int pullBinderCallsStatsExceptions(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang877adfe2020-01-15 17:16:43 -08001661 BinderCallsStatsService.Internal binderStats =
1662 LocalServices.getService(BinderCallsStatsService.Internal.class);
1663 if (binderStats == null) {
1664 Slog.e(TAG, "failed to get binderStats");
1665 return StatsManager.PULL_SKIP;
1666 }
1667
1668 ArrayMap<String, Integer> exceptionStats = binderStats.getExportedExceptionStats();
1669 // TODO: decouple binder calls exceptions with the rest of the binder calls data so that we
1670 // can reset the exception stats.
1671 for (Map.Entry<String, Integer> entry : exceptionStats.entrySet()) {
1672 StatsEvent e = StatsEvent.newBuilder()
1673 .setAtomId(atomTag)
1674 .writeString(entry.getKey())
1675 .writeInt(entry.getValue())
1676 .build();
1677 pulledData.add(e);
1678 }
1679 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001680 }
1681
1682 private void registerLooperStats() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001683 int tagId = FrameworkStatsLog.LOOPER_STATS;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001684 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangfd037c52020-01-16 10:42:59 -08001685 .setAdditiveFields(new int[] {5, 6, 7, 8, 9})
1686 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001687 mStatsManager.setPullAtomCallback(
Jeffrey Huangfd037c52020-01-16 10:42:59 -08001688 tagId,
1689 metadata,
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001690 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001691 mStatsCallbackImpl
Jeffrey Huangfd037c52020-01-16 10:42:59 -08001692 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001693 }
1694
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001695 int pullLooperStats(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangfd037c52020-01-16 10:42:59 -08001696 LooperStats looperStats = LocalServices.getService(LooperStats.class);
1697 if (looperStats == null) {
1698 return StatsManager.PULL_SKIP;
1699 }
1700
1701 List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
1702 looperStats.reset();
1703 for (LooperStats.ExportedEntry entry : entries) {
1704 StatsEvent e = StatsEvent.newBuilder()
1705 .setAtomId(atomTag)
1706 .writeInt(entry.workSourceUid)
1707 .writeString(entry.handlerClassName)
1708 .writeString(entry.threadName)
1709 .writeString(entry.messageName)
1710 .writeLong(entry.messageCount)
1711 .writeLong(entry.exceptionCount)
1712 .writeLong(entry.recordedMessageCount)
1713 .writeLong(entry.totalLatencyMicros)
1714 .writeLong(entry.cpuUsageMicros)
1715 .writeBoolean(entry.isInteractive)
1716 .writeLong(entry.maxCpuUsageMicros)
1717 .writeLong(entry.maxLatencyMicros)
1718 .writeLong(entry.recordedDelayMessageCount)
1719 .writeLong(entry.delayMillis)
1720 .writeLong(entry.maxDelayMillis)
1721 .build();
1722 pulledData.add(e);
1723 }
1724 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001725 }
1726
1727 private void registerDiskStats() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001728 int tagId = FrameworkStatsLog.DISK_STATS;
Tej Singh72a70a82020-02-26 23:46:29 -08001729 mStatsManager.setPullAtomCallback(
Jeffrey Huang95765f02020-01-16 11:33:58 -08001730 tagId,
1731 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001732 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001733 mStatsCallbackImpl
Jeffrey Huang95765f02020-01-16 11:33:58 -08001734 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001735 }
1736
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001737 int pullDiskStats(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang95765f02020-01-16 11:33:58 -08001738 // Run a quick-and-dirty performance test: write 512 bytes
1739 byte[] junk = new byte[512];
1740 for (int i = 0; i < junk.length; i++) junk[i] = (byte) i; // Write nonzero bytes
1741
1742 File tmp = new File(Environment.getDataDirectory(), "system/statsdperftest.tmp");
1743 FileOutputStream fos = null;
1744 IOException error = null;
1745
1746 long before = SystemClock.elapsedRealtime();
1747 try {
1748 fos = new FileOutputStream(tmp);
1749 fos.write(junk);
1750 } catch (IOException e) {
1751 error = e;
1752 } finally {
1753 try {
1754 if (fos != null) fos.close();
1755 } catch (IOException e) {
1756 // Do nothing.
1757 }
1758 }
1759
1760 long latency = SystemClock.elapsedRealtime() - before;
1761 if (tmp.exists()) tmp.delete();
1762
1763 if (error != null) {
1764 Slog.e(TAG, "Error performing diskstats latency test");
1765 latency = -1;
1766 }
1767 // File based encryption.
1768 boolean fileBased = StorageManager.isFileEncryptedNativeOnly();
1769
1770 //Recent disk write speed. Binder call to storaged.
1771 int writeSpeed = -1;
1772 IStoraged storaged = getIStoragedService();
1773 if (storaged == null) {
1774 return StatsManager.PULL_SKIP;
1775 }
1776 try {
1777 writeSpeed = storaged.getRecentPerf();
1778 } catch (RemoteException e) {
1779 Slog.e(TAG, "storaged not found");
1780 }
1781
1782 // Add info pulledData.
1783 StatsEvent e = StatsEvent.newBuilder()
1784 .setAtomId(atomTag)
1785 .writeLong(latency)
1786 .writeBoolean(fileBased)
1787 .writeInt(writeSpeed)
1788 .build();
1789 pulledData.add(e);
1790 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001791 }
1792
1793 private void registerDirectoryUsage() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001794 int tagId = FrameworkStatsLog.DIRECTORY_USAGE;
Tej Singh72a70a82020-02-26 23:46:29 -08001795 mStatsManager.setPullAtomCallback(
Jeffrey Huang95765f02020-01-16 11:33:58 -08001796 tagId,
1797 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001798 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001799 mStatsCallbackImpl
Jeffrey Huang95765f02020-01-16 11:33:58 -08001800 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001801 }
1802
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001803 int pullDirectoryUsage(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang95765f02020-01-16 11:33:58 -08001804 StatFs statFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath());
1805 StatFs statFsSystem = new StatFs(Environment.getRootDirectory().getAbsolutePath());
1806 StatFs statFsCache = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath());
1807
1808 StatsEvent e = StatsEvent.newBuilder()
1809 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001810 .writeInt(FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__DATA)
Jeffrey Huang95765f02020-01-16 11:33:58 -08001811 .writeLong(statFsData.getAvailableBytes())
1812 .writeLong(statFsData.getTotalBytes())
1813 .build();
1814 pulledData.add(e);
1815
1816 e = StatsEvent.newBuilder()
1817 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001818 .writeInt(FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__CACHE)
Jeffrey Huang95765f02020-01-16 11:33:58 -08001819 .writeLong(statFsCache.getAvailableBytes())
1820 .writeLong(statFsCache.getTotalBytes())
1821 .build();
1822 pulledData.add(e);
1823
1824 e = StatsEvent.newBuilder()
1825 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001826 .writeInt(FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__SYSTEM)
Jeffrey Huang95765f02020-01-16 11:33:58 -08001827 .writeLong(statFsSystem.getAvailableBytes())
1828 .writeLong(statFsSystem.getTotalBytes())
1829 .build();
1830 pulledData.add(e);
1831 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001832 }
1833
1834 private void registerAppSize() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001835 int tagId = FrameworkStatsLog.APP_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08001836 mStatsManager.setPullAtomCallback(
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001837 tagId,
1838 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001839 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001840 mStatsCallbackImpl
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001841 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001842 }
1843
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001844 int pullAppSize(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001845 try {
1846 String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
1847 JSONObject json = new JSONObject(jsonStr);
1848 long cache_time = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L);
1849 JSONArray pkg_names = json.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY);
1850 JSONArray app_sizes = json.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY);
1851 JSONArray app_data_sizes = json.getJSONArray(DiskStatsFileLogger.APP_DATA_KEY);
1852 JSONArray app_cache_sizes = json.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY);
1853 // Sanity check: Ensure all 4 lists have the same length.
1854 int length = pkg_names.length();
1855 if (app_sizes.length() != length || app_data_sizes.length() != length
1856 || app_cache_sizes.length() != length) {
1857 Slog.e(TAG, "formatting error in diskstats cache file!");
1858 return StatsManager.PULL_SKIP;
1859 }
1860 for (int i = 0; i < length; i++) {
1861 StatsEvent e = StatsEvent.newBuilder()
1862 .setAtomId(atomTag)
1863 .writeString(pkg_names.getString(i))
1864 .writeLong(app_sizes.optLong(i, /* fallback */ -1L))
1865 .writeLong(app_data_sizes.optLong(i, /* fallback */ -1L))
1866 .writeLong(app_cache_sizes.optLong(i, /* fallback */ -1L))
1867 .writeLong(cache_time)
1868 .build();
1869 pulledData.add(e);
1870 }
1871 } catch (IOException | JSONException e) {
1872 Slog.e(TAG, "exception reading diskstats cache file", e);
1873 return StatsManager.PULL_SKIP;
1874 }
1875 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001876 }
1877
1878 private void registerCategorySize() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001879 int tagId = FrameworkStatsLog.CATEGORY_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08001880 mStatsManager.setPullAtomCallback(
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001881 tagId,
1882 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001883 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001884 mStatsCallbackImpl
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001885 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001886 }
1887
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001888 int pullCategorySize(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001889 try {
1890 String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
1891 JSONObject json = new JSONObject(jsonStr);
1892 long cacheTime = json.optLong(
1893 DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, /* fallback */ -1L);
1894
1895 StatsEvent e = StatsEvent.newBuilder()
1896 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001897 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__APP_SIZE)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001898 .writeLong(json.optLong(
1899 DiskStatsFileLogger.APP_SIZE_AGG_KEY, /* fallback */ -1L))
1900 .writeLong(cacheTime)
1901 .build();
1902 pulledData.add(e);
1903
1904 e = StatsEvent.newBuilder()
1905 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001906 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__APP_DATA_SIZE)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001907 .writeLong(json.optLong(
1908 DiskStatsFileLogger.APP_DATA_SIZE_AGG_KEY, /* fallback */ -1L))
1909 .writeLong(cacheTime)
1910 .build();
1911 pulledData.add(e);
1912
1913 e = StatsEvent.newBuilder()
1914 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001915 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__APP_CACHE_SIZE)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001916 .writeLong(json.optLong(
1917 DiskStatsFileLogger.APP_CACHE_AGG_KEY, /* fallback */ -1L))
1918 .writeLong(cacheTime)
1919 .build();
1920 pulledData.add(e);
1921
1922 e = StatsEvent.newBuilder()
1923 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001924 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__PHOTOS)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001925 .writeLong(json.optLong(
1926 DiskStatsFileLogger.PHOTOS_KEY, /* fallback */ -1L))
1927 .writeLong(cacheTime)
1928 .build();
1929 pulledData.add(e);
1930
1931 e = StatsEvent.newBuilder()
1932 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001933 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__VIDEOS)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001934 .writeLong(
1935 json.optLong(DiskStatsFileLogger.VIDEOS_KEY, /* fallback */ -1L))
1936 .writeLong(cacheTime)
1937 .build();
1938 pulledData.add(e);
1939
1940 e = StatsEvent.newBuilder()
1941 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001942 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__AUDIO)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001943 .writeLong(json.optLong(
1944 DiskStatsFileLogger.AUDIO_KEY, /* fallback */ -1L))
1945 .writeLong(cacheTime)
1946 .build();
1947 pulledData.add(e);
1948
1949 e = StatsEvent.newBuilder()
1950 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001951 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__DOWNLOADS)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001952 .writeLong(
1953 json.optLong(DiskStatsFileLogger.DOWNLOADS_KEY, /* fallback */ -1L))
1954 .writeLong(cacheTime)
1955 .build();
1956 pulledData.add(e);
1957
1958 e = StatsEvent.newBuilder()
Tej Singh5dd1dc92020-01-29 20:44:42 -08001959 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001960 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__SYSTEM)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001961 .writeLong(json.optLong(
1962 DiskStatsFileLogger.SYSTEM_KEY, /* fallback */ -1L))
1963 .writeLong(cacheTime)
1964 .build();
1965 pulledData.add(e);
1966
1967 e = StatsEvent.newBuilder()
1968 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001969 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__OTHER)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001970 .writeLong(json.optLong(
1971 DiskStatsFileLogger.MISC_KEY, /* fallback */ -1L))
1972 .writeLong(cacheTime)
1973 .build();
1974 pulledData.add(e);
1975 } catch (IOException | JSONException e) {
1976 Slog.e(TAG, "exception reading diskstats cache file", e);
1977 return StatsManager.PULL_SKIP;
1978 }
1979 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001980 }
1981
1982 private void registerNumFingerprintsEnrolled() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001983 int tagId = FrameworkStatsLog.NUM_FINGERPRINTS_ENROLLED;
Tej Singh72a70a82020-02-26 23:46:29 -08001984 mStatsManager.setPullAtomCallback(
Jeffrey Huang597a8862020-01-16 14:56:37 -08001985 tagId,
1986 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001987 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001988 mStatsCallbackImpl
Jeffrey Huang597a8862020-01-16 14:56:37 -08001989 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001990 }
1991
1992 private void registerNumFacesEnrolled() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001993 int tagId = FrameworkStatsLog.NUM_FACES_ENROLLED;
Tej Singh72a70a82020-02-26 23:46:29 -08001994 mStatsManager.setPullAtomCallback(
Jeffrey Huang597a8862020-01-16 14:56:37 -08001995 tagId,
1996 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001997 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001998 mStatsCallbackImpl
Jeffrey Huang597a8862020-01-16 14:56:37 -08001999 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002000 }
2001
Jeffrey Huang597a8862020-01-16 14:56:37 -08002002 private int pullNumBiometricsEnrolled(int modality, int atomTag, List<StatsEvent> pulledData) {
2003 final PackageManager pm = mContext.getPackageManager();
2004 FingerprintManager fingerprintManager = null;
2005 FaceManager faceManager = null;
2006
2007 if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
2008 fingerprintManager = mContext.getSystemService(FingerprintManager.class);
2009 }
2010 if (pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
2011 faceManager = mContext.getSystemService(FaceManager.class);
2012 }
2013
2014 if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT && fingerprintManager == null) {
2015 return StatsManager.PULL_SKIP;
2016 }
2017 if (modality == BiometricsProtoEnums.MODALITY_FACE && faceManager == null) {
2018 return StatsManager.PULL_SKIP;
2019 }
2020 UserManager userManager = mContext.getSystemService(UserManager.class);
2021 if (userManager == null) {
2022 return StatsManager.PULL_SKIP;
2023 }
2024
2025 final long token = Binder.clearCallingIdentity();
2026 try {
2027 for (UserInfo user : userManager.getUsers()) {
2028 final int userId = user.getUserHandle().getIdentifier();
2029 int numEnrolled = 0;
2030 if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT) {
2031 numEnrolled = fingerprintManager.getEnrolledFingerprints(userId).size();
2032 } else if (modality == BiometricsProtoEnums.MODALITY_FACE) {
2033 numEnrolled = faceManager.getEnrolledFaces(userId).size();
2034 } else {
2035 return StatsManager.PULL_SKIP;
2036 }
2037 StatsEvent e = StatsEvent.newBuilder()
2038 .setAtomId(atomTag)
2039 .writeInt(userId)
2040 .writeInt(numEnrolled)
2041 .build();
2042 pulledData.add(e);
2043 }
2044 } finally {
2045 Binder.restoreCallingIdentity(token);
2046 }
2047 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002048 }
2049
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002050 private void registerProcStats() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002051 int tagId = FrameworkStatsLog.PROC_STATS;
Tej Singh72a70a82020-02-26 23:46:29 -08002052 mStatsManager.setPullAtomCallback(
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002053 tagId,
2054 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002055 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002056 mStatsCallbackImpl
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002057 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002058 }
2059
2060 private void registerProcStatsPkgProc() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002061 int tagId = FrameworkStatsLog.PROC_STATS_PKG_PROC;
Tej Singh72a70a82020-02-26 23:46:29 -08002062 mStatsManager.setPullAtomCallback(
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002063 tagId,
2064 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002065 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002066 mStatsCallbackImpl
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002067 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002068 }
2069
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002070 private int pullProcStats(int section, int atomTag, List<StatsEvent> pulledData) {
2071 IProcessStats processStatsService = getIProcessStatsService();
2072 if (processStatsService == null) {
2073 return StatsManager.PULL_SKIP;
2074 }
2075
2076 synchronized (mProcessStatsLock) {
2077 final long token = Binder.clearCallingIdentity();
2078 try {
2079 long lastHighWaterMark = readProcStatsHighWaterMark(section);
2080 List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
2081 long highWaterMark = processStatsService.getCommittedStats(
2082 lastHighWaterMark, section, true, statsFiles);
2083 if (statsFiles.size() != 1) {
2084 return StatsManager.PULL_SKIP;
2085 }
2086 unpackStreamedData(atomTag, pulledData, statsFiles);
2087 new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + lastHighWaterMark)
2088 .delete();
2089 new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + highWaterMark)
2090 .createNewFile();
2091 } catch (IOException e) {
2092 Slog.e(TAG, "Getting procstats failed: ", e);
2093 return StatsManager.PULL_SKIP;
2094 } catch (RemoteException e) {
2095 Slog.e(TAG, "Getting procstats failed: ", e);
2096 return StatsManager.PULL_SKIP;
2097 } catch (SecurityException e) {
2098 Slog.e(TAG, "Getting procstats failed: ", e);
2099 return StatsManager.PULL_SKIP;
2100 } finally {
2101 Binder.restoreCallingIdentity(token);
2102 }
2103 }
2104
2105 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002106 }
2107
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002108 // read high watermark for section
2109 private long readProcStatsHighWaterMark(int section) {
2110 try {
2111 File[] files = mBaseDir.listFiles((d, name) -> {
2112 return name.toLowerCase().startsWith(String.valueOf(section) + '_');
2113 });
2114 if (files == null || files.length == 0) {
2115 return 0;
2116 }
2117 if (files.length > 1) {
2118 Slog.e(TAG, "Only 1 file expected for high water mark. Found " + files.length);
2119 }
2120 return Long.valueOf(files[0].getName().split("_")[1]);
2121 } catch (SecurityException e) {
2122 Slog.e(TAG, "Failed to get procstats high watermark file.", e);
2123 } catch (NumberFormatException e) {
2124 Slog.e(TAG, "Failed to parse file name.", e);
2125 }
2126 return 0;
2127 }
2128
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002129 private void registerDiskIO() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002130 int tagId = FrameworkStatsLog.DISK_IO;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002131 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002132 .setAdditiveFields(new int[] {2, 3, 4, 5, 6, 7, 8, 9, 10, 11})
Tej Singh72a70a82020-02-26 23:46:29 -08002133 .setCoolDownMillis(3 * MILLIS_PER_SEC)
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002134 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002135 mStatsManager.setPullAtomCallback(
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002136 tagId,
2137 metadata,
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002138 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002139 mStatsCallbackImpl
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002140 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002141 }
2142
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002143 int pullDiskIO(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002144 mStoragedUidIoStatsReader.readAbsolute((uid, fgCharsRead, fgCharsWrite, fgBytesRead,
2145 fgBytesWrite, bgCharsRead, bgCharsWrite, bgBytesRead, bgBytesWrite,
2146 fgFsync, bgFsync) -> {
2147 StatsEvent e = StatsEvent.newBuilder()
2148 .setAtomId(atomTag)
2149 .writeInt(uid)
2150 .writeLong(fgCharsRead)
2151 .writeLong(fgCharsWrite)
2152 .writeLong(fgBytesRead)
2153 .writeLong(fgBytesWrite)
2154 .writeLong(bgCharsRead)
2155 .writeLong(bgCharsWrite)
2156 .writeLong(bgBytesRead)
2157 .writeLong(bgBytesWrite)
2158 .writeLong(fgFsync)
2159 .writeLong(bgFsync)
2160 .build();
2161 pulledData.add(e);
2162 });
2163 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002164 }
2165
2166 private void registerPowerProfile() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002167 int tagId = FrameworkStatsLog.POWER_PROFILE;
Tej Singh72a70a82020-02-26 23:46:29 -08002168 mStatsManager.setPullAtomCallback(
Jeffrey Huang1a3935c2020-01-13 10:51:17 -08002169 tagId,
2170 /* PullAtomMetadata */ null,
Tej Singh6b979832020-01-02 15:23:02 -08002171 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002172 mStatsCallbackImpl
Jeffrey Huang1a3935c2020-01-13 10:51:17 -08002173 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002174 }
2175
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002176 int pullPowerProfile(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang1a3935c2020-01-13 10:51:17 -08002177 PowerProfile powerProfile = new PowerProfile(mContext);
2178 ProtoOutputStream proto = new ProtoOutputStream();
2179 powerProfile.dumpDebug(proto);
2180 proto.flush();
2181 StatsEvent e = StatsEvent.newBuilder()
2182 .setAtomId(atomTag)
2183 .writeByteArray(proto.getBytes())
2184 .build();
2185 pulledData.add(e);
2186 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002187 }
2188
2189 private void registerProcessCpuTime() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002190 int tagId = FrameworkStatsLog.PROCESS_CPU_TIME;
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002191 // Min cool-down is 5 sec, in line with what ActivityManagerService uses.
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002192 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Tej Singh72a70a82020-02-26 23:46:29 -08002193 .setCoolDownMillis(5 * MILLIS_PER_SEC)
Jeffrey Huang7a9ae132020-01-14 15:44:58 -08002194 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002195 mStatsManager.setPullAtomCallback(
Jeffrey Huang7a9ae132020-01-14 15:44:58 -08002196 tagId,
2197 metadata,
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002198 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002199 mStatsCallbackImpl
Jeffrey Huang7a9ae132020-01-14 15:44:58 -08002200 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002201 }
2202
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002203 int pullProcessCpuTime(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang7a9ae132020-01-14 15:44:58 -08002204 synchronized (mCpuTrackerLock) {
2205 if (mProcessCpuTracker == null) {
2206 mProcessCpuTracker = new ProcessCpuTracker(false);
2207 mProcessCpuTracker.init();
2208 }
2209 mProcessCpuTracker.update();
2210 for (int i = 0; i < mProcessCpuTracker.countStats(); i++) {
2211 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2212 StatsEvent e = StatsEvent.newBuilder()
2213 .setAtomId(atomTag)
2214 .writeInt(st.uid)
2215 .writeString(st.name)
2216 .writeLong(st.base_utime)
2217 .writeLong(st.base_stime)
2218 .build();
2219 pulledData.add(e);
2220 }
2221 }
2222 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002223 }
2224
2225 private void registerCpuTimePerThreadFreq() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002226 int tagId = FrameworkStatsLog.CPU_TIME_PER_THREAD_FREQ;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002227 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangbf4eef82020-01-16 15:38:58 -08002228 .setAdditiveFields(new int[] {7, 9, 11, 13, 15, 17, 19, 21})
2229 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002230 mStatsManager.setPullAtomCallback(
Jeffrey Huangbf4eef82020-01-16 15:38:58 -08002231 tagId,
2232 metadata,
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002233 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002234 mStatsCallbackImpl
Jeffrey Huangbf4eef82020-01-16 15:38:58 -08002235 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002236 }
2237
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002238 int pullCpuTimePerThreadFreq(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangbf4eef82020-01-16 15:38:58 -08002239 if (this.mKernelCpuThreadReader == null) {
2240 Slog.e(TAG, "mKernelCpuThreadReader is null");
2241 return StatsManager.PULL_SKIP;
2242 }
2243 ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages =
2244 this.mKernelCpuThreadReader.getProcessCpuUsageDiffed();
2245 if (processCpuUsages == null) {
2246 Slog.e(TAG, "processCpuUsages is null");
2247 return StatsManager.PULL_SKIP;
2248 }
2249 int[] cpuFrequencies = mKernelCpuThreadReader.getCpuFrequenciesKhz();
2250 if (cpuFrequencies.length > CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES) {
2251 String message = "Expected maximum " + CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES
2252 + " frequencies, but got " + cpuFrequencies.length;
2253 Slog.w(TAG, message);
2254 return StatsManager.PULL_SKIP;
2255 }
2256 for (int i = 0; i < processCpuUsages.size(); i++) {
2257 KernelCpuThreadReader.ProcessCpuUsage processCpuUsage = processCpuUsages.get(i);
2258 ArrayList<KernelCpuThreadReader.ThreadCpuUsage> threadCpuUsages =
2259 processCpuUsage.threadCpuUsages;
2260 for (int j = 0; j < threadCpuUsages.size(); j++) {
2261 KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage = threadCpuUsages.get(j);
2262 if (threadCpuUsage.usageTimesMillis.length != cpuFrequencies.length) {
2263 String message = "Unexpected number of usage times,"
2264 + " expected " + cpuFrequencies.length
2265 + " but got " + threadCpuUsage.usageTimesMillis.length;
2266 Slog.w(TAG, message);
2267 return StatsManager.PULL_SKIP;
2268 }
2269
2270 StatsEvent.Builder e = StatsEvent.newBuilder();
2271 e.setAtomId(atomTag);
2272 e.writeInt(processCpuUsage.uid);
2273 e.writeInt(processCpuUsage.processId);
2274 e.writeInt(threadCpuUsage.threadId);
2275 e.writeString(processCpuUsage.processName);
2276 e.writeString(threadCpuUsage.threadName);
2277 for (int k = 0; k < CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES; k++) {
2278 if (k < cpuFrequencies.length) {
2279 e.writeInt(cpuFrequencies[k]);
2280 e.writeInt(threadCpuUsage.usageTimesMillis[k]);
2281 } else {
2282 // If we have no more frequencies to write, we still must write empty data.
2283 // We know that this data is empty (and not just zero) because all
2284 // frequencies are expected to be greater than zero
2285 e.writeInt(0);
2286 e.writeInt(0);
2287 }
2288 }
2289 pulledData.add(e.build());
2290 }
2291 }
2292 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002293 }
2294
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002295 private BatteryStatsHelper getBatteryStatsHelper() {
2296 if (mBatteryStatsHelper == null) {
2297 final long callingToken = Binder.clearCallingIdentity();
2298 try {
2299 // clearCallingIdentity required for BatteryStatsHelper.checkWifiOnly().
2300 mBatteryStatsHelper = new BatteryStatsHelper(mContext, false);
2301 } finally {
2302 Binder.restoreCallingIdentity(callingToken);
2303 }
2304 mBatteryStatsHelper.create((Bundle) null);
2305 }
2306 long currentTime = SystemClock.elapsedRealtime();
2307 if (currentTime - mBatteryStatsHelperTimestampMs >= MAX_BATTERY_STATS_HELPER_FREQUENCY_MS) {
2308 // Load BatteryStats and do all the calculations.
2309 mBatteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, UserHandle.USER_ALL);
2310 // Calculations are done so we don't need to save the raw BatteryStats data in RAM.
2311 mBatteryStatsHelper.clearStats();
2312 mBatteryStatsHelperTimestampMs = currentTime;
2313 }
2314 return mBatteryStatsHelper;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002315 }
2316
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002317 private long milliAmpHrsToNanoAmpSecs(double mAh) {
2318 return (long) (mAh * MILLI_AMP_HR_TO_NANO_AMP_SECS + 0.5);
2319 }
2320
2321 private void registerDeviceCalculatedPowerUse() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002322 int tagId = FrameworkStatsLog.DEVICE_CALCULATED_POWER_USE;
Tej Singh72a70a82020-02-26 23:46:29 -08002323 mStatsManager.setPullAtomCallback(
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002324 tagId,
2325 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002326 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002327 mStatsCallbackImpl
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002328 );
2329 }
2330
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002331 int pullDeviceCalculatedPowerUse(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002332 BatteryStatsHelper bsHelper = getBatteryStatsHelper();
2333 StatsEvent e = StatsEvent.newBuilder()
2334 .setAtomId(atomTag)
2335 .writeLong(milliAmpHrsToNanoAmpSecs(bsHelper.getComputedPower()))
2336 .build();
2337 pulledData.add(e);
2338 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002339 }
2340
2341 private void registerDeviceCalculatedPowerBlameUid() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002342 int tagId = FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_UID;
Tej Singh72a70a82020-02-26 23:46:29 -08002343 mStatsManager.setPullAtomCallback(
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002344 tagId,
2345 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002346 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002347 mStatsCallbackImpl
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002348 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002349 }
2350
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002351 int pullDeviceCalculatedPowerBlameUid(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002352 final List<BatterySipper> sippers = getBatteryStatsHelper().getUsageList();
2353 if (sippers == null) {
2354 return StatsManager.PULL_SKIP;
2355 }
2356
2357 for (BatterySipper bs : sippers) {
2358 if (bs.drainType != bs.drainType.APP) {
2359 continue;
2360 }
2361 StatsEvent e = StatsEvent.newBuilder()
2362 .setAtomId(atomTag)
2363 .writeInt(bs.uidObj.getUid())
2364 .writeLong(milliAmpHrsToNanoAmpSecs(bs.totalPowerMah))
2365 .build();
2366 pulledData.add(e);
2367 }
2368 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002369 }
2370
2371 private void registerDeviceCalculatedPowerBlameOther() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002372 int tagId = FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_OTHER;
Tej Singh72a70a82020-02-26 23:46:29 -08002373 mStatsManager.setPullAtomCallback(
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002374 tagId,
2375 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002376 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002377 mStatsCallbackImpl
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002378 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002379 }
2380
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002381 int pullDeviceCalculatedPowerBlameOther(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002382 final List<BatterySipper> sippers = getBatteryStatsHelper().getUsageList();
2383 if (sippers == null) {
2384 return StatsManager.PULL_SKIP;
2385 }
2386
2387 for (BatterySipper bs : sippers) {
2388 if (bs.drainType == bs.drainType.APP) {
2389 continue; // This is a separate atom; see pullDeviceCalculatedPowerBlameUid().
2390 }
2391 if (bs.drainType == bs.drainType.USER) {
2392 continue; // This is not supported. We purposefully calculate over USER_ALL.
2393 }
2394 StatsEvent e = StatsEvent.newBuilder()
2395 .setAtomId(atomTag)
2396 .writeInt(bs.drainType.ordinal())
2397 .writeLong(milliAmpHrsToNanoAmpSecs(bs.totalPowerMah))
2398 .build();
2399 pulledData.add(e);
2400 }
2401 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002402 }
2403
2404 private void registerDebugElapsedClock() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002405 int tagId = FrameworkStatsLog.DEBUG_ELAPSED_CLOCK;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002406 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002407 .setAdditiveFields(new int[] {1, 2, 3, 4})
2408 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002409 mStatsManager.setPullAtomCallback(
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002410 tagId,
2411 metadata,
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002412 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002413 mStatsCallbackImpl
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002414 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002415 }
2416
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002417 int pullDebugElapsedClock(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002418 final long elapsedMillis = SystemClock.elapsedRealtime();
2419
2420 synchronized (mDebugElapsedClockLock) {
2421 final long clockDiffMillis = mDebugElapsedClockPreviousValue == 0
2422 ? 0 : elapsedMillis - mDebugElapsedClockPreviousValue;
2423
2424 StatsEvent e = StatsEvent.newBuilder()
2425 .setAtomId(atomTag)
2426 .writeLong(mDebugElapsedClockPullCount)
2427 .writeLong(elapsedMillis)
2428 // Log it twice to be able to test multi-value aggregation from ValueMetric.
2429 .writeLong(elapsedMillis)
2430 .writeLong(clockDiffMillis)
2431 .writeInt(1 /* always set */)
2432 .build();
2433 pulledData.add(e);
2434
2435 if (mDebugElapsedClockPullCount % 2 == 1) {
2436 StatsEvent e2 = StatsEvent.newBuilder()
2437 .setAtomId(atomTag)
2438 .writeLong(mDebugElapsedClockPullCount)
2439 .writeLong(elapsedMillis)
2440 // Log it twice to be able to test multi-value aggregation from ValueMetric.
2441 .writeLong(elapsedMillis)
2442 .writeLong(clockDiffMillis)
2443 .writeInt(2 /* set on odd pulls */)
2444 .build();
2445 pulledData.add(e2);
2446 }
2447
2448 mDebugElapsedClockPullCount++;
2449 mDebugElapsedClockPreviousValue = elapsedMillis;
2450 }
2451
2452 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002453 }
2454
2455 private void registerDebugFailingElapsedClock() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002456 int tagId = FrameworkStatsLog.DEBUG_FAILING_ELAPSED_CLOCK;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002457 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002458 .setAdditiveFields(new int[] {1, 2, 3, 4})
2459 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002460 mStatsManager.setPullAtomCallback(
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002461 tagId,
2462 metadata,
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002463 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002464 mStatsCallbackImpl
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002465 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002466 }
2467
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002468 int pullDebugFailingElapsedClock(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002469 final long elapsedMillis = SystemClock.elapsedRealtime();
2470
2471 synchronized (mDebugFailingElapsedClockLock) {
2472 // Fails every 5 buckets.
2473 if (mDebugFailingElapsedClockPullCount++ % 5 == 0) {
2474 mDebugFailingElapsedClockPreviousValue = elapsedMillis;
2475 Slog.e(TAG, "Failing debug elapsed clock");
2476 return StatsManager.PULL_SKIP;
2477 }
2478
2479 StatsEvent e = StatsEvent.newBuilder()
2480 .setAtomId(atomTag)
2481 .writeLong(mDebugFailingElapsedClockPullCount)
2482 .writeLong(elapsedMillis)
2483 // Log it twice to be able to test multi-value aggregation from ValueMetric.
2484 .writeLong(elapsedMillis)
2485 .writeLong(mDebugFailingElapsedClockPreviousValue == 0
2486 ? 0 : elapsedMillis - mDebugFailingElapsedClockPreviousValue)
2487 .build();
2488 pulledData.add(e);
2489
2490 mDebugFailingElapsedClockPreviousValue = elapsedMillis;
2491 }
2492
2493 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002494 }
2495
2496 private void registerBuildInformation() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002497 int tagId = FrameworkStatsLog.BUILD_INFORMATION;
Tej Singh72a70a82020-02-26 23:46:29 -08002498 mStatsManager.setPullAtomCallback(
Ruchir Rastogi425d8362020-01-14 23:51:46 -08002499 tagId,
2500 null, // use default PullAtomMetadata values
Tej Singh6b979832020-01-02 15:23:02 -08002501 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002502 mStatsCallbackImpl
Ruchir Rastogi425d8362020-01-14 23:51:46 -08002503 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002504 }
2505
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002506 int pullBuildInformation(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi425d8362020-01-14 23:51:46 -08002507 StatsEvent e = StatsEvent.newBuilder()
2508 .setAtomId(atomTag)
2509 .writeString(Build.FINGERPRINT)
2510 .writeString(Build.BRAND)
2511 .writeString(Build.PRODUCT)
2512 .writeString(Build.DEVICE)
Dianne Hackborndb007452019-10-28 16:34:22 -07002513 .writeString(Build.VERSION.RELEASE_OR_CODENAME)
Ruchir Rastogi425d8362020-01-14 23:51:46 -08002514 .writeString(Build.ID)
2515 .writeString(Build.VERSION.INCREMENTAL)
2516 .writeString(Build.TYPE)
2517 .writeString(Build.TAGS)
2518 .build();
2519 pulledData.add(e);
2520 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002521 }
2522
2523 private void registerRoleHolder() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002524 int tagId = FrameworkStatsLog.ROLE_HOLDER;
Tej Singh72a70a82020-02-26 23:46:29 -08002525 mStatsManager.setPullAtomCallback(
Ruchir Rastogie4fd3212020-01-15 00:39:12 -08002526 tagId,
2527 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002528 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002529 mStatsCallbackImpl
Ruchir Rastogie4fd3212020-01-15 00:39:12 -08002530 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002531 }
2532
Ruchir Rastogie4fd3212020-01-15 00:39:12 -08002533 // Add a RoleHolder atom for each package that holds a role.
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002534 int pullRoleHolder(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogie4fd3212020-01-15 00:39:12 -08002535 long callingToken = Binder.clearCallingIdentity();
2536 try {
2537 PackageManager pm = mContext.getPackageManager();
2538 RoleManagerInternal rmi = LocalServices.getService(RoleManagerInternal.class);
2539
2540 List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
2541
2542 int numUsers = users.size();
2543 for (int userNum = 0; userNum < numUsers; userNum++) {
2544 int userId = users.get(userNum).getUserHandle().getIdentifier();
2545
2546 ArrayMap<String, ArraySet<String>> roles = rmi.getRolesAndHolders(userId);
2547
2548 int numRoles = roles.size();
2549 for (int roleNum = 0; roleNum < numRoles; roleNum++) {
2550 String roleName = roles.keyAt(roleNum);
2551 ArraySet<String> holders = roles.valueAt(roleNum);
2552
2553 int numHolders = holders.size();
2554 for (int holderNum = 0; holderNum < numHolders; holderNum++) {
2555 String holderName = holders.valueAt(holderNum);
2556
2557 PackageInfo pkg;
2558 try {
2559 pkg = pm.getPackageInfoAsUser(holderName, 0, userId);
2560 } catch (PackageManager.NameNotFoundException e) {
2561 Slog.w(TAG, "Role holder " + holderName + " not found");
2562 return StatsManager.PULL_SKIP;
2563 }
2564
2565 StatsEvent e = StatsEvent.newBuilder()
2566 .setAtomId(atomTag)
2567 .writeInt(pkg.applicationInfo.uid)
2568 .writeString(holderName)
2569 .writeString(roleName)
2570 .build();
2571 pulledData.add(e);
2572 }
2573 }
2574 }
2575 } finally {
2576 Binder.restoreCallingIdentity(callingToken);
2577 }
2578 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002579 }
2580
2581 private void registerDangerousPermissionState() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002582 int tagId = FrameworkStatsLog.DANGEROUS_PERMISSION_STATE;
Tej Singh72a70a82020-02-26 23:46:29 -08002583 mStatsManager.setPullAtomCallback(
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08002584 tagId,
2585 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002586 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002587 mStatsCallbackImpl
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08002588 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002589 }
2590
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002591 int pullDangerousPermissionState(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08002592 final long token = Binder.clearCallingIdentity();
2593 Set<Integer> reportedUids = new HashSet<>();
2594 try {
2595 PackageManager pm = mContext.getPackageManager();
2596
2597 List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
2598
2599 int numUsers = users.size();
2600 for (int userNum = 0; userNum < numUsers; userNum++) {
2601 UserHandle user = users.get(userNum).getUserHandle();
2602
2603 List<PackageInfo> pkgs = pm.getInstalledPackagesAsUser(
2604 PackageManager.GET_PERMISSIONS, user.getIdentifier());
2605
2606 int numPkgs = pkgs.size();
2607 for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) {
2608 PackageInfo pkg = pkgs.get(pkgNum);
2609
2610 if (pkg.requestedPermissions == null) {
2611 continue;
2612 }
2613
2614 if (reportedUids.contains(pkg.applicationInfo.uid)) {
2615 // do not report same uid twice
2616 continue;
2617 }
2618 reportedUids.add(pkg.applicationInfo.uid);
2619
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002620 if (atomTag == FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED
Stanislav Zholnin39307b02020-01-28 15:47:43 +00002621 && ThreadLocalRandom.current().nextFloat() > 0.01f) {
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08002622 continue;
2623 }
2624
2625 int numPerms = pkg.requestedPermissions.length;
2626 for (int permNum = 0; permNum < numPerms; permNum++) {
2627 String permName = pkg.requestedPermissions[permNum];
2628
2629 PermissionInfo permissionInfo;
2630 int permissionFlags = 0;
2631 try {
2632 permissionInfo = pm.getPermissionInfo(permName, 0);
2633 permissionFlags =
2634 pm.getPermissionFlags(permName, pkg.packageName, user);
2635 } catch (PackageManager.NameNotFoundException ignored) {
2636 continue;
2637 }
2638
2639 if (permissionInfo.getProtection() != PROTECTION_DANGEROUS) {
2640 continue;
2641 }
2642
Stanislav Zholnindbcf85e2020-02-24 18:17:55 +00002643 if (permName.startsWith(COMMON_PERMISSION_PREFIX)) {
2644 permName = permName.substring(COMMON_PERMISSION_PREFIX.length());
2645 }
2646
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08002647 StatsEvent.Builder e = StatsEvent.newBuilder();
2648 e.setAtomId(atomTag);
2649 e.writeString(permName);
2650 e.writeInt(pkg.applicationInfo.uid);
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002651 if (atomTag == FrameworkStatsLog.DANGEROUS_PERMISSION_STATE) {
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08002652 e.writeString("");
2653 }
2654 e.writeBoolean((pkg.requestedPermissionsFlags[permNum]
2655 & REQUESTED_PERMISSION_GRANTED) != 0);
2656 e.writeInt(permissionFlags);
2657
2658 pulledData.add(e.build());
2659 }
2660 }
2661 }
2662 } catch (Throwable t) {
2663 Log.e(TAG, "Could not read permissions", t);
2664 return StatsManager.PULL_SKIP;
2665 } finally {
2666 Binder.restoreCallingIdentity(token);
2667 }
2668 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002669 }
2670
2671 private void registerTimeZoneDataInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002672 int tagId = FrameworkStatsLog.TIME_ZONE_DATA_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08002673 mStatsManager.setPullAtomCallback(
Ruchir Rastogibd2c4ba2020-01-15 14:48:36 -08002674 tagId,
2675 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002676 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002677 mStatsCallbackImpl
Ruchir Rastogibd2c4ba2020-01-15 14:48:36 -08002678 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002679 }
2680
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002681 int pullTimeZoneDataInfo(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogibd2c4ba2020-01-15 14:48:36 -08002682 String tzDbVersion = "Unknown";
2683 try {
2684 tzDbVersion = android.icu.util.TimeZone.getTZDataVersion();
2685 } catch (MissingResourceException e) {
2686 Slog.e(TAG, "Getting tzdb version failed: ", e);
2687 return StatsManager.PULL_SKIP;
2688 }
2689
2690 StatsEvent e = StatsEvent.newBuilder()
2691 .setAtomId(atomTag)
2692 .writeString(tzDbVersion)
2693 .build();
2694 pulledData.add(e);
2695 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002696 }
2697
2698 private void registerExternalStorageInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002699 int tagId = FrameworkStatsLog.EXTERNAL_STORAGE_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08002700 mStatsManager.setPullAtomCallback(
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08002701 tagId,
2702 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002703 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002704 mStatsCallbackImpl
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08002705 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002706 }
2707
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002708 int pullExternalStorageInfo(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08002709 if (mStorageManager == null) {
2710 return StatsManager.PULL_SKIP;
2711 }
2712
2713 List<VolumeInfo> volumes = mStorageManager.getVolumes();
2714 for (VolumeInfo vol : volumes) {
2715 final String envState = VolumeInfo.getEnvironmentForState(vol.getState());
2716 final DiskInfo diskInfo = vol.getDisk();
2717 if (diskInfo != null && envState.equals(Environment.MEDIA_MOUNTED)) {
2718 // Get the type of the volume, if it is adoptable or portable.
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002719 int volumeType = FrameworkStatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__OTHER;
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08002720 if (vol.getType() == TYPE_PUBLIC) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002721 volumeType = FrameworkStatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PUBLIC;
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08002722 } else if (vol.getType() == TYPE_PRIVATE) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002723 volumeType = FrameworkStatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PRIVATE;
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08002724 }
2725
2726 // Get the type of external storage inserted in the device (sd cards, usb, etc.)
2727 int externalStorageType;
2728 if (diskInfo.isSd()) {
2729 externalStorageType = StorageEnums.SD_CARD;
2730 } else if (diskInfo.isUsb()) {
2731 externalStorageType = StorageEnums.USB;
2732 } else {
2733 externalStorageType = StorageEnums.OTHER;
2734 }
2735
2736 StatsEvent e = StatsEvent.newBuilder()
2737 .setAtomId(atomTag)
2738 .writeInt(externalStorageType)
2739 .writeInt(volumeType)
2740 .writeLong(diskInfo.size)
2741 .build();
2742 pulledData.add(e);
2743 }
2744 }
2745 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002746 }
2747
2748 private void registerAppsOnExternalStorageInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002749 int tagId = FrameworkStatsLog.APPS_ON_EXTERNAL_STORAGE_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08002750 mStatsManager.setPullAtomCallback(
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08002751 tagId,
2752 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002753 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002754 mStatsCallbackImpl
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08002755 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002756 }
2757
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002758 int pullAppsOnExternalStorageInfo(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08002759 if (mStorageManager == null) {
2760 return StatsManager.PULL_SKIP;
2761 }
2762
2763 PackageManager pm = mContext.getPackageManager();
2764 List<ApplicationInfo> apps = pm.getInstalledApplications(/*flags=*/ 0);
2765 for (ApplicationInfo appInfo : apps) {
2766 UUID storageUuid = appInfo.storageUuid;
2767 if (storageUuid == null) {
2768 continue;
2769 }
2770
2771 VolumeInfo volumeInfo = mStorageManager.findVolumeByUuid(
2772 appInfo.storageUuid.toString());
2773 if (volumeInfo == null) {
2774 continue;
2775 }
2776
2777 DiskInfo diskInfo = volumeInfo.getDisk();
2778 if (diskInfo == null) {
2779 continue;
2780 }
2781
2782 int externalStorageType = -1;
2783 if (diskInfo.isSd()) {
2784 externalStorageType = StorageEnums.SD_CARD;
2785 } else if (diskInfo.isUsb()) {
2786 externalStorageType = StorageEnums.USB;
2787 } else if (appInfo.isExternal()) {
2788 externalStorageType = StorageEnums.OTHER;
2789 }
2790
2791 // App is installed on external storage.
2792 if (externalStorageType != -1) {
2793 StatsEvent e = StatsEvent.newBuilder()
2794 .setAtomId(atomTag)
2795 .writeInt(externalStorageType)
2796 .writeString(appInfo.packageName)
2797 .build();
2798 pulledData.add(e);
2799 }
2800 }
2801 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002802 }
2803
2804 private void registerFaceSettings() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002805 int tagId = FrameworkStatsLog.FACE_SETTINGS;
Tej Singh72a70a82020-02-26 23:46:29 -08002806 mStatsManager.setPullAtomCallback(
Ruchir Rastogi329c7672020-01-17 15:33:05 -08002807 tagId,
2808 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002809 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002810 mStatsCallbackImpl
Ruchir Rastogi329c7672020-01-17 15:33:05 -08002811 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002812 }
2813
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002814 int pullFaceSettings(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi329c7672020-01-17 15:33:05 -08002815 final long callingToken = Binder.clearCallingIdentity();
2816 try {
2817 List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
2818 int numUsers = users.size();
2819 for (int userNum = 0; userNum < numUsers; userNum++) {
2820 int userId = users.get(userNum).getUserHandle().getIdentifier();
2821
2822 int unlockKeyguardEnabled = Settings.Secure.getIntForUser(
2823 mContext.getContentResolver(),
2824 Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED, 1, userId);
2825 int unlockDismissesKeyguard = Settings.Secure.getIntForUser(
2826 mContext.getContentResolver(),
2827 Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, 0, userId);
2828 int unlockAttentionRequired = Settings.Secure.getIntForUser(
2829 mContext.getContentResolver(),
2830 Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED, 1, userId);
2831 int unlockAppEnabled = Settings.Secure.getIntForUser(
2832 mContext.getContentResolver(),
2833 Settings.Secure.FACE_UNLOCK_APP_ENABLED, 1, userId);
2834 int unlockAlwaysRequireConfirmation = Settings.Secure.getIntForUser(
2835 mContext.getContentResolver(),
2836 Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, 0, userId);
2837 int unlockDiversityRequired = Settings.Secure.getIntForUser(
2838 mContext.getContentResolver(),
2839 Settings.Secure.FACE_UNLOCK_DIVERSITY_REQUIRED, 1, userId);
2840
2841 StatsEvent e = StatsEvent.newBuilder()
2842 .setAtomId(atomTag)
2843 .writeBoolean(unlockKeyguardEnabled != 0)
2844 .writeBoolean(unlockDismissesKeyguard != 0)
2845 .writeBoolean(unlockAttentionRequired != 0)
2846 .writeBoolean(unlockAppEnabled != 0)
2847 .writeBoolean(unlockAlwaysRequireConfirmation != 0)
2848 .writeBoolean(unlockDiversityRequired != 0)
2849 .build();
2850 pulledData.add(e);
2851 }
2852 } finally {
2853 Binder.restoreCallingIdentity(callingToken);
2854 }
2855 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002856 }
2857
2858 private void registerAppOps() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002859 int tagId = FrameworkStatsLog.APP_OPS;
Tej Singh72a70a82020-02-26 23:46:29 -08002860 mStatsManager.setPullAtomCallback(
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08002861 tagId,
2862 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002863 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002864 mStatsCallbackImpl
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08002865 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002866 }
2867
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00002868 private void registerRuntimeAppOpAccessMessage() {
2869 int tagId = FrameworkStatsLog.RUNTIME_APP_OP_ACCESS;
Tej Singh72a70a82020-02-26 23:46:29 -08002870 mStatsManager.setPullAtomCallback(
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00002871 tagId,
2872 null, // use default PullAtomMetadata values
2873 BackgroundThread.getExecutor(),
2874 mStatsCallbackImpl
2875 );
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00002876 }
2877
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002878 int pullAppOps(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002879 final long token = Binder.clearCallingIdentity();
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08002880 try {
2881 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
2882
2883 CompletableFuture<HistoricalOps> ops = new CompletableFuture<>();
Stanislav Zholnin050abc32020-02-17 14:14:52 +00002884 HistoricalOpsRequest histOpsRequest = new HistoricalOpsRequest.Builder(0,
2885 Long.MAX_VALUE).setFlags(OP_FLAGS_PULLED).build();
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08002886 appOps.getHistoricalOps(histOpsRequest, mContext.getMainExecutor(), ops::complete);
2887
2888 HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
2889 TimeUnit.MILLISECONDS);
Stanislav Zholnin59199132020-03-06 14:19:25 +00002890 processHistoricalOps(histOps, atomTag, pulledData);
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08002891 } catch (Throwable t) {
2892 // TODO: catch exceptions at a more granular level
2893 Slog.e(TAG, "Could not read appops", t);
2894 return StatsManager.PULL_SKIP;
2895 } finally {
2896 Binder.restoreCallingIdentity(token);
2897 }
2898 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002899 }
2900
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002901 private void registerAttributedAppOps() {
2902 int tagId = FrameworkStatsLog.ATTRIBUTED_APP_OPS;
Tej Singh72a70a82020-02-26 23:46:29 -08002903 mStatsManager.setPullAtomCallback(
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00002904 tagId,
2905 null, // use default PullAtomMetadata values
2906 BackgroundThread.getExecutor(),
2907 mStatsCallbackImpl
2908 );
2909 }
2910
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002911 int pullAttributedAppOps(int atomTag, List<StatsEvent> pulledData) {
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00002912 final long token = Binder.clearCallingIdentity();
2913 try {
2914 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
2915
2916 CompletableFuture<HistoricalOps> ops = new CompletableFuture<>();
2917 HistoricalOpsRequest histOpsRequest =
2918 new HistoricalOpsRequest.Builder(0, Long.MAX_VALUE).setFlags(
2919 OP_FLAGS_PULLED).build();
2920 appOps.getHistoricalOps(histOpsRequest, mContext.getMainExecutor(), ops::complete);
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00002921 HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
2922 TimeUnit.MILLISECONDS);
Stanislav Zholnin59199132020-03-06 14:19:25 +00002923 if (mAppOpsSamplingRate == 0) {
2924 mAppOpsSamplingRate = constrain((5000 * 100) / estimateAppOpsSize(), 1, 100);
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00002925 }
Stanislav Zholnin59199132020-03-06 14:19:25 +00002926 processHistoricalOps(histOps, atomTag, pulledData);
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00002927 } catch (Throwable t) {
2928 // TODO: catch exceptions at a more granular level
2929 Slog.e(TAG, "Could not read appops", t);
2930 return StatsManager.PULL_SKIP;
2931 } finally {
2932 Binder.restoreCallingIdentity(token);
2933 }
2934 return StatsManager.PULL_SUCCESS;
2935 }
2936
Stanislav Zholnin59199132020-03-06 14:19:25 +00002937 private int estimateAppOpsSize() throws Exception {
2938 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
2939
2940 CompletableFuture<HistoricalOps> ops = new CompletableFuture<>();
2941 HistoricalOpsRequest histOpsRequest =
2942 new HistoricalOpsRequest.Builder(
2943 Instant.now().minus(1, ChronoUnit.DAYS).toEpochMilli(),
2944 Long.MAX_VALUE).setFlags(
2945 OP_FLAGS_PULLED).build();
2946 appOps.getHistoricalOps(histOpsRequest, mContext.getMainExecutor(), ops::complete);
2947 HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
2948 TimeUnit.MILLISECONDS);
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002949 return processHistoricalOps(histOps, FrameworkStatsLog.ATTRIBUTED_APP_OPS, null);
Stanislav Zholnin59199132020-03-06 14:19:25 +00002950 }
2951
2952 int processHistoricalOps(HistoricalOps histOps, int atomTag, List<StatsEvent> pulledData) {
2953 int counter = 0;
2954 for (int uidIdx = 0; uidIdx < histOps.getUidCount(); uidIdx++) {
2955 final HistoricalUidOps uidOps = histOps.getUidOpsAt(uidIdx);
2956 final int uid = uidOps.getUid();
2957 for (int pkgIdx = 0; pkgIdx < uidOps.getPackageCount(); pkgIdx++) {
2958 final HistoricalPackageOps packageOps = uidOps.getPackageOpsAt(pkgIdx);
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002959 if (atomTag == FrameworkStatsLog.ATTRIBUTED_APP_OPS) {
2960 for (int attributionIdx = 0;
2961 attributionIdx < packageOps.getAttributedOpsCount(); attributionIdx++) {
2962 final AppOpsManager.AttributedHistoricalOps attributedOps =
2963 packageOps.getAttributedOpsAt(attributionIdx);
2964 for (int opIdx = 0; opIdx < attributedOps.getOpCount(); opIdx++) {
2965 final AppOpsManager.HistoricalOp op = attributedOps.getOpAt(opIdx);
Stanislav Zholnin59199132020-03-06 14:19:25 +00002966 counter += processHistoricalOp(op, atomTag, pulledData, uid,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002967 packageOps.getPackageName(), attributedOps.getTag());
Stanislav Zholnin59199132020-03-06 14:19:25 +00002968 }
2969 }
2970 } else if (atomTag == FrameworkStatsLog.APP_OPS) {
2971 for (int opIdx = 0; opIdx < packageOps.getOpCount(); opIdx++) {
2972 final AppOpsManager.HistoricalOp op = packageOps.getOpAt(opIdx);
2973 counter += processHistoricalOp(op, atomTag, pulledData, uid,
2974 packageOps.getPackageName(), null);
2975 }
2976 }
2977 }
2978 }
2979 return counter;
2980 }
2981
2982 private int processHistoricalOp(AppOpsManager.HistoricalOp op, int atomTag,
2983 @Nullable List<StatsEvent> pulledData, int uid, String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002984 @Nullable String attributionTag) {
2985 if (atomTag == FrameworkStatsLog.ATTRIBUTED_APP_OPS) {
Stanislav Zholnin59199132020-03-06 14:19:25 +00002986 if (pulledData == null) { // this is size estimation call
2987 if (op.getForegroundAccessCount(OP_FLAGS_PULLED) + op.getBackgroundAccessCount(
2988 OP_FLAGS_PULLED) == 0) {
2989 return 0;
2990 } else {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002991 return 32 + packageName.length() + (attributionTag == null ? 1
2992 : attributionTag.length());
Stanislav Zholnin59199132020-03-06 14:19:25 +00002993 }
2994 } else {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002995 if (abs((op.getOpCode() + attributionTag + packageName).hashCode() + RANDOM_SEED)
2996 % 100 >= mAppOpsSamplingRate) {
Stanislav Zholnin59199132020-03-06 14:19:25 +00002997 return 0;
2998 }
2999 }
3000 }
3001
3002 StatsEvent.Builder e = StatsEvent.newBuilder();
3003 e.setAtomId(atomTag);
3004 e.writeInt(uid);
3005 e.writeString(packageName);
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003006 if (atomTag == FrameworkStatsLog.ATTRIBUTED_APP_OPS) {
3007 e.writeString(attributionTag);
Stanislav Zholnin59199132020-03-06 14:19:25 +00003008 }
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003009 if (atomTag == FrameworkStatsLog.ATTRIBUTED_APP_OPS) {
Stanislav Zholnin59199132020-03-06 14:19:25 +00003010 e.writeString(op.getOpName());
3011 } else {
3012 e.writeInt(op.getOpCode());
3013 }
3014 e.writeLong(op.getForegroundAccessCount(OP_FLAGS_PULLED));
3015 e.writeLong(op.getBackgroundAccessCount(OP_FLAGS_PULLED));
3016 e.writeLong(op.getForegroundRejectCount(OP_FLAGS_PULLED));
3017 e.writeLong(op.getBackgroundRejectCount(OP_FLAGS_PULLED));
3018 e.writeLong(op.getForegroundAccessDuration(OP_FLAGS_PULLED));
3019 e.writeLong(op.getBackgroundAccessDuration(OP_FLAGS_PULLED));
3020
3021 String perm = AppOpsManager.opToPermission(op.getOpCode());
3022 if (perm == null) {
3023 e.writeBoolean(false);
3024 } else {
3025 PermissionInfo permInfo;
3026 try {
3027 permInfo = mContext.getPackageManager().getPermissionInfo(
3028 perm,
3029 0);
3030 e.writeBoolean(
3031 permInfo.getProtection() == PROTECTION_DANGEROUS);
3032 } catch (PackageManager.NameNotFoundException exception) {
3033 e.writeBoolean(false);
3034 }
3035 }
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003036 if (atomTag == FrameworkStatsLog.ATTRIBUTED_APP_OPS) {
Stanislav Zholnin59199132020-03-06 14:19:25 +00003037 e.writeInt(mAppOpsSamplingRate);
3038 }
3039 pulledData.add(e.build());
3040 return 0;
3041 }
3042
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003043 int pullRuntimeAppOpAccessMessage(int atomTag, List<StatsEvent> pulledData) {
3044 final long token = Binder.clearCallingIdentity();
3045 try {
3046 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
3047
3048 RuntimeAppOpAccessMessage message = appOps.collectRuntimeAppOpAccessMessage();
3049 if (message == null) {
3050 Slog.i(TAG, "No runtime appop access message collected");
3051 return StatsManager.PULL_SUCCESS;
3052 }
3053
3054 StatsEvent.Builder e = StatsEvent.newBuilder();
3055 e.setAtomId(atomTag);
3056 e.writeInt(message.getUid());
3057 e.writeString(message.getPackageName());
3058 e.writeString(message.getOp());
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003059 if (message.getAttributionTag() == null) {
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003060 e.writeString("");
3061 } else {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003062 e.writeString(message.getAttributionTag());
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003063 }
3064 e.writeString(message.getMessage());
3065 e.writeInt(message.getSamplingStrategy());
3066
3067 pulledData.add(e.build());
3068 } catch (Throwable t) {
3069 // TODO: catch exceptions at a more granular level
3070 Slog.e(TAG, "Could not read runtime appop access message", t);
3071 return StatsManager.PULL_SKIP;
3072 } finally {
3073 Binder.restoreCallingIdentity(token);
3074 }
3075 return StatsManager.PULL_SUCCESS;
3076 }
3077
Jeffrey Huang730bf962020-01-16 15:59:52 -08003078 static void unpackStreamedData(int atomTag, List<StatsEvent> pulledData,
3079 List<ParcelFileDescriptor> statsFiles) throws IOException {
3080 InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(statsFiles.get(0));
3081 int[] len = new int[1];
3082 byte[] stats = readFully(stream, len);
3083 StatsEvent e = StatsEvent.newBuilder()
3084 .setAtomId(atomTag)
3085 .writeByteArray(Arrays.copyOf(stats, len[0]))
3086 .build();
3087 pulledData.add(e);
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003088 }
3089
Jeffrey Huang730bf962020-01-16 15:59:52 -08003090 static byte[] readFully(InputStream stream, int[] outLen) throws IOException {
3091 int pos = 0;
3092 final int initialAvail = stream.available();
3093 byte[] data = new byte[initialAvail > 0 ? (initialAvail + 1) : 16384];
3094 while (true) {
3095 int amt = stream.read(data, pos, data.length - pos);
3096 if (DEBUG) {
3097 Slog.i(TAG, "Read " + amt + " bytes at " + pos + " of avail " + data.length);
3098 }
3099 if (amt < 0) {
3100 if (DEBUG) {
3101 Slog.i(TAG, "**** FINISHED READING: pos=" + pos + " len=" + data.length);
3102 }
3103 outLen[0] = pos;
3104 return data;
3105 }
3106 pos += amt;
3107 if (pos >= data.length) {
3108 byte[] newData = new byte[pos + 16384];
3109 if (DEBUG) {
3110 Slog.i(TAG, "Copying " + pos + " bytes to new array len " + newData.length);
3111 }
3112 System.arraycopy(data, 0, newData, 0, pos);
3113 data = newData;
3114 }
3115 }
3116 }
3117
3118 private void registerNotificationRemoteViews() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003119 int tagId = FrameworkStatsLog.NOTIFICATION_REMOTE_VIEWS;
Tej Singh72a70a82020-02-26 23:46:29 -08003120 mStatsManager.setPullAtomCallback(
Jeffrey Huang730bf962020-01-16 15:59:52 -08003121 tagId,
3122 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08003123 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003124 mStatsCallbackImpl
Jeffrey Huang730bf962020-01-16 15:59:52 -08003125 );
3126 }
3127
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003128 int pullNotificationRemoteViews(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang730bf962020-01-16 15:59:52 -08003129 INotificationManager notificationManagerService = getINotificationManagerService();
3130 if (notificationManagerService == null) {
3131 return StatsManager.PULL_SKIP;
3132 }
3133 final long callingToken = Binder.clearCallingIdentity();
3134 try {
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08003135 // determine last pull tine. Copy file trick from pullProcStats?
Jeffrey Huang730bf962020-01-16 15:59:52 -08003136 long wallClockNanos = SystemClock.currentTimeMicro() * 1000L;
3137 long lastNotificationStatsNs = wallClockNanos -
3138 TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS);
3139
3140 List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
3141 notificationManagerService.pullStats(lastNotificationStatsNs,
3142 NotificationManagerService.REPORT_REMOTE_VIEWS, true, statsFiles);
3143 if (statsFiles.size() != 1) {
3144 return StatsManager.PULL_SKIP;
3145 }
3146 unpackStreamedData(atomTag, pulledData, statsFiles);
3147 } catch (IOException e) {
3148 Slog.e(TAG, "Getting notistats failed: ", e);
3149 return StatsManager.PULL_SKIP;
3150 } catch (RemoteException e) {
3151 Slog.e(TAG, "Getting notistats failed: ", e);
3152 return StatsManager.PULL_SKIP;
3153 } catch (SecurityException e) {
3154 Slog.e(TAG, "Getting notistats failed: ", e);
3155 return StatsManager.PULL_SKIP;
3156 } finally {
3157 Binder.restoreCallingIdentity(callingToken);
3158 }
3159 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003160 }
3161
3162 private void registerDangerousPermissionStateSampled() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003163 int tagId = FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED;
Tej Singh72a70a82020-02-26 23:46:29 -08003164 mStatsManager.setPullAtomCallback(
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003165 tagId,
3166 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08003167 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003168 mStatsCallbackImpl
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003169 );
Tej Singh953ad862020-01-03 12:47:07 -08003170 }
Jeffrey Huangbf130832020-01-22 15:48:26 -08003171
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003172 private void registerBatteryLevel() {
3173 int tagId = FrameworkStatsLog.BATTERY_LEVEL;
Tej Singh72a70a82020-02-26 23:46:29 -08003174 mStatsManager.setPullAtomCallback(
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003175 tagId,
3176 null, // use default PullAtomMetadata values
3177 BackgroundThread.getExecutor(),
3178 mStatsCallbackImpl
3179 );
3180 }
3181
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003182 private void registerRemainingBatteryCapacity() {
3183 int tagId = FrameworkStatsLog.REMAINING_BATTERY_CAPACITY;
Tej Singh72a70a82020-02-26 23:46:29 -08003184 mStatsManager.setPullAtomCallback(
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003185 tagId,
3186 null, // use default PullAtomMetadata values
3187 BackgroundThread.getExecutor(),
3188 mStatsCallbackImpl
3189 );
3190 }
3191
3192 private void registerFullBatteryCapacity() {
3193 int tagId = FrameworkStatsLog.FULL_BATTERY_CAPACITY;
Tej Singh72a70a82020-02-26 23:46:29 -08003194 mStatsManager.setPullAtomCallback(
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003195 tagId,
3196 null, // use default PullAtomMetadata values
3197 BackgroundThread.getExecutor(),
3198 mStatsCallbackImpl
3199 );
3200 }
3201
3202 private void registerBatteryVoltage() {
3203 int tagId = FrameworkStatsLog.BATTERY_VOLTAGE;
Tej Singh72a70a82020-02-26 23:46:29 -08003204 mStatsManager.setPullAtomCallback(
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003205 tagId,
3206 null, // use default PullAtomMetadata values
3207 BackgroundThread.getExecutor(),
3208 mStatsCallbackImpl
3209 );
3210 }
3211
3212 private void registerBatteryCycleCount() {
3213 int tagId = FrameworkStatsLog.BATTERY_CYCLE_COUNT;
Tej Singh72a70a82020-02-26 23:46:29 -08003214 mStatsManager.setPullAtomCallback(
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003215 tagId,
3216 null, // use default PullAtomMetadata values
3217 BackgroundThread.getExecutor(),
3218 mStatsCallbackImpl
3219 );
3220 }
3221
3222 int pullHealthHal(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003223 IHealth healthService = mHealthService.getLastService();
3224 if (healthService == null) {
3225 return StatsManager.PULL_SKIP;
3226 }
3227 try {
3228 healthService.getHealthInfo((result, value) -> {
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003229 int pulledValue;
3230 switch(atomTag) {
3231 case FrameworkStatsLog.BATTERY_LEVEL:
3232 pulledValue = value.legacy.batteryLevel;
3233 break;
3234 case FrameworkStatsLog.REMAINING_BATTERY_CAPACITY:
3235 pulledValue = value.legacy.batteryChargeCounter;
3236 break;
3237 case FrameworkStatsLog.FULL_BATTERY_CAPACITY:
3238 pulledValue = value.legacy.batteryFullCharge;
3239 break;
3240 case FrameworkStatsLog.BATTERY_VOLTAGE:
3241 pulledValue = value.legacy.batteryVoltage;
3242 break;
3243 case FrameworkStatsLog.BATTERY_CYCLE_COUNT:
3244 pulledValue = value.legacy.batteryCycleCount;
3245 break;
3246 default:
3247 throw new IllegalStateException("Invalid atomTag in healthHal puller: "
3248 + atomTag);
3249 }
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003250 StatsEvent e = StatsEvent.newBuilder()
3251 .setAtomId(atomTag)
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003252 .writeInt(pulledValue)
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003253 .build();
3254 pulledData.add(e);
3255 });
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003256 } catch (RemoteException | IllegalStateException e) {
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003257 return StatsManager.PULL_SKIP;
3258 }
3259 return StatsManager.PULL_SUCCESS;
3260 }
Jeffrey Huangbf130832020-01-22 15:48:26 -08003261
3262 // Thermal event received from vendor thermal management subsystem
3263 private static final class ThermalEventListener extends IThermalEventListener.Stub {
3264 @Override
3265 public void notifyThrottling(Temperature temp) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003266 FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_THROTTLING_SEVERITY_STATE_CHANGED,
3267 temp.getType(), temp.getName(), (int) (temp.getValue() * 10), temp.getStatus());
Jeffrey Huangbf130832020-01-22 15:48:26 -08003268 }
3269 }
3270
3271 private static final class ConnectivityStatsCallback extends
3272 ConnectivityManager.NetworkCallback {
3273 @Override
3274 public void onAvailable(Network network) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003275 FrameworkStatsLog.write(FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED, network.netId,
3276 FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED__STATE__CONNECTED);
Jeffrey Huangbf130832020-01-22 15:48:26 -08003277 }
3278
3279 @Override
3280 public void onLost(Network network) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003281 FrameworkStatsLog.write(FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED, network.netId,
3282 FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED__STATE__DISCONNECTED);
Jeffrey Huangbf130832020-01-22 15:48:26 -08003283 }
3284 }
Tej Singh953ad862020-01-03 12:47:07 -08003285}