blob: 3b4c4235d8a45ba80a914430f6e10b4ab7a8beb3 [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;
junyulai212a5f0e2020-02-07 17:42:39 +080021import static android.app.usage.NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080022import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
23import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS;
junyulai592c6052020-04-29 16:09:01 +080024import static android.net.NetworkTemplate.NETWORK_TYPE_ALL;
Rafal Slawikbdd5a502020-01-14 14:14:29 +000025import static android.os.Debug.getIonHeapsSizeKb;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080026import static android.os.Process.getUidForPid;
27import static android.os.storage.VolumeInfo.TYPE_PRIVATE;
28import static android.os.storage.VolumeInfo.TYPE_PUBLIC;
Stanislav Zholnin59199132020-03-06 14:19:25 +000029import static android.util.MathUtils.abs;
30import static android.util.MathUtils.constrain;
Tej Singh953ad862020-01-03 12:47:07 -080031
Muhammad Qureshi22e52da2020-03-30 21:14:21 -070032import static com.android.internal.util.FrameworkStatsLog.ANNOTATION_ID_IS_UID;
Muhammad Qureshi09fc8c42020-05-06 14:50:54 -070033import static com.android.internal.util.FrameworkStatsLog.ANNOTATION_ID_TRUNCATE_TIMESTAMP;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080034import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
Tej Singh250e7aa2020-01-16 13:16:21 -080035import static com.android.server.stats.pull.IonMemoryUtil.readProcessSystemIonHeapSizesFromDebugfs;
36import static com.android.server.stats.pull.IonMemoryUtil.readSystemIonHeapSizeFromDebugfs;
Ioannis Ilkos754eb072020-01-27 16:42:24 +000037import static com.android.server.stats.pull.ProcfsMemoryUtil.getProcessCmdlines;
Tej Singh250e7aa2020-01-16 13:16:21 -080038import static com.android.server.stats.pull.ProcfsMemoryUtil.readCmdlineFromProcfs;
39import static com.android.server.stats.pull.ProcfsMemoryUtil.readMemorySnapshotFromProcfs;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080040
junyulai212a5f0e2020-02-07 17:42:39 +080041import static java.util.concurrent.TimeUnit.MICROSECONDS;
42
43import android.annotation.NonNull;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080044import android.annotation.Nullable;
45import android.app.ActivityManagerInternal;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080046import android.app.AppOpsManager;
47import android.app.AppOpsManager.HistoricalOps;
48import android.app.AppOpsManager.HistoricalOpsRequest;
49import android.app.AppOpsManager.HistoricalPackageOps;
50import android.app.AppOpsManager.HistoricalUidOps;
51import android.app.INotificationManager;
52import android.app.ProcessMemoryState;
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +000053import android.app.RuntimeAppOpAccessMessage;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080054import android.app.StatsManager;
55import android.app.StatsManager.PullAtomMetadata;
56import android.bluetooth.BluetoothActivityEnergyInfo;
57import android.bluetooth.BluetoothAdapter;
58import android.bluetooth.UidTraffic;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080059import android.content.Context;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080060import android.content.pm.ApplicationInfo;
61import android.content.pm.PackageInfo;
62import android.content.pm.PackageManager;
63import android.content.pm.PermissionInfo;
64import android.content.pm.UserInfo;
65import android.hardware.biometrics.BiometricsProtoEnums;
66import android.hardware.face.FaceManager;
67import android.hardware.fingerprint.FingerprintManager;
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -080068import android.hardware.health.V2_0.IHealth;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080069import android.net.ConnectivityManager;
70import android.net.INetworkStatsService;
junyulai212a5f0e2020-02-07 17:42:39 +080071import android.net.INetworkStatsSession;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080072import android.net.Network;
73import android.net.NetworkRequest;
74import android.net.NetworkStats;
junyulai212a5f0e2020-02-07 17:42:39 +080075import android.net.NetworkTemplate;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080076import android.net.wifi.WifiManager;
77import android.os.BatteryStats;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080078import android.os.Binder;
79import android.os.Build;
80import android.os.Bundle;
81import android.os.CoolingDevice;
82import android.os.Environment;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080083import android.os.IStoraged;
84import android.os.IThermalEventListener;
85import android.os.IThermalService;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080086import android.os.ParcelFileDescriptor;
87import android.os.Parcelable;
88import android.os.RemoteException;
89import android.os.ServiceManager;
90import android.os.StatFs;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080091import android.os.SynchronousResultReceiver;
92import android.os.SystemClock;
93import android.os.SystemProperties;
94import android.os.Temperature;
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +000095import android.os.Trace;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080096import android.os.UserHandle;
97import android.os.UserManager;
98import android.os.connectivity.WifiActivityEnergyInfo;
99import android.os.storage.DiskInfo;
100import android.os.storage.StorageManager;
101import android.os.storage.VolumeInfo;
Stanislav Zholnin2f63e582020-04-19 12:10:05 +0100102import android.provider.DeviceConfig;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800103import android.provider.Settings;
104import android.stats.storage.StorageEnums;
105import android.telephony.ModemActivityInfo;
106import android.telephony.TelephonyManager;
107import android.util.ArrayMap;
108import android.util.ArraySet;
109import android.util.Log;
110import android.util.Slog;
Ioannis Ilkos754eb072020-01-27 16:42:24 +0000111import android.util.SparseArray;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800112import android.util.StatsEvent;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800113import android.util.proto.ProtoOutputStream;
114
115import com.android.internal.annotations.GuardedBy;
116import com.android.internal.app.procstats.IProcessStats;
117import com.android.internal.app.procstats.ProcessStats;
Tej Singh953ad862020-01-03 12:47:07 -0800118import com.android.internal.os.BackgroundThread;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800119import com.android.internal.os.BatterySipper;
120import com.android.internal.os.BatteryStatsHelper;
121import com.android.internal.os.BinderCallsStats.ExportedCallStat;
122import com.android.internal.os.KernelCpuSpeedReader;
123import com.android.internal.os.KernelCpuThreadReader;
124import com.android.internal.os.KernelCpuThreadReaderDiff;
125import com.android.internal.os.KernelCpuThreadReaderSettingsObserver;
126import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader;
127import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader;
128import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader;
129import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader;
130import com.android.internal.os.KernelWakelockReader;
131import com.android.internal.os.KernelWakelockStats;
132import com.android.internal.os.LooperStats;
133import com.android.internal.os.PowerProfile;
134import com.android.internal.os.ProcessCpuTracker;
135import com.android.internal.os.StoragedUidIoStatsReader;
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -0800136import com.android.internal.util.FrameworkStatsLog;
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -0800137import com.android.server.BatteryService;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800138import com.android.server.BinderCallsStatsService;
139import com.android.server.LocalServices;
Tej Singh953ad862020-01-03 12:47:07 -0800140import com.android.server.SystemService;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800141import com.android.server.SystemServiceManager;
142import com.android.server.am.MemoryStatUtil.MemoryStat;
143import com.android.server.notification.NotificationManagerService;
144import com.android.server.role.RoleManagerInternal;
Tej Singh250e7aa2020-01-16 13:16:21 -0800145import com.android.server.stats.pull.IonMemoryUtil.IonAllocations;
146import com.android.server.stats.pull.ProcfsMemoryUtil.MemorySnapshot;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800147import com.android.server.storage.DiskStatsFileLogger;
148import com.android.server.storage.DiskStatsLoggingService;
149
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800150import libcore.io.IoUtils;
151
152import org.json.JSONArray;
153import org.json.JSONException;
154import org.json.JSONObject;
155
156import java.io.File;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800157import java.io.FileOutputStream;
158import java.io.IOException;
159import java.io.InputStream;
Stanislav Zholnin59199132020-03-06 14:19:25 +0000160import java.time.Instant;
161import java.time.temporal.ChronoUnit;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800162import java.util.ArrayList;
163import java.util.Arrays;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800164import java.util.HashSet;
165import java.util.List;
166import java.util.Map;
Ruchir Rastogibd2c4ba2020-01-15 14:48:36 -0800167import java.util.MissingResourceException;
Stanislav Zholnin59199132020-03-06 14:19:25 +0000168import java.util.Random;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800169import java.util.Set;
170import java.util.UUID;
171import java.util.concurrent.CompletableFuture;
172import java.util.concurrent.Executor;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800173import java.util.concurrent.ThreadLocalRandom;
174import java.util.concurrent.TimeUnit;
175import java.util.concurrent.TimeoutException;
Tej Singh953ad862020-01-03 12:47:07 -0800176
177/**
178 * SystemService containing PullAtomCallbacks that are registered with statsd.
179 *
180 * @hide
181 */
182public class StatsPullAtomService extends SystemService {
183 private static final String TAG = "StatsPullAtomService";
184 private static final boolean DEBUG = true;
185
Stanislav Zholnin59199132020-03-06 14:19:25 +0000186 // Random seed stable for StatsPullAtomService life cycle - can be used for stable sampling
187 private static final int RANDOM_SEED = new Random().nextInt();
188
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800189 /**
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800190 * Lowest available uid for apps.
191 *
192 * <p>Used to quickly discard memory snapshots of the zygote forks from native process
193 * measurements.
194 */
195 private static final int MIN_APP_UID = 10_000;
196
Jeffrey Huangfa917892020-01-10 16:58:03 -0800197 private static final String RESULT_RECEIVER_CONTROLLER_KEY = "controller_activity";
198 /**
199 * How long to wait on an individual subsystem to return its stats.
200 */
201 private static final long EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS = 2000;
Tej Singh72a70a82020-02-26 23:46:29 -0800202 private static final long MILLIS_PER_SEC = 1000;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800203 private static final long MILLI_AMP_HR_TO_NANO_AMP_SECS = 1_000_000L * 3600L;
204
205 private static final int MAX_BATTERY_STATS_HELPER_FREQUENCY_MS = 1000;
206 private static final int CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES = 8;
Stanislav Zholnind20eacc2020-03-02 18:44:45 +0000207 private static final int OP_FLAGS_PULLED = OP_FLAG_SELF | OP_FLAG_TRUSTED_PROXY;
Stanislav Zholnindbcf85e2020-02-24 18:17:55 +0000208 private static final String COMMON_PERMISSION_PREFIX = "android.permission.";
Stanislav Zholnin2f63e582020-04-19 12:10:05 +0100209 private static final String APP_OPS_TARGET_COLLECTION_SIZE = "app_ops_target_collection_size";
Stanislav Zholnina093ae72020-04-18 19:14:17 +0100210 private static final String DANGEROUS_PERMISSION_STATE_SAMPLE_RATE =
211 "dangerous_permission_state_sample_rate";
Jeffrey Huangfa917892020-01-10 16:58:03 -0800212
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800213 private final Object mNetworkStatsLock = new Object();
214 @GuardedBy("mNetworkStatsLock")
junyulai212a5f0e2020-02-07 17:42:39 +0800215 @Nullable
216 private INetworkStatsSession mNetworkStatsSession;
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800217
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800218 private final Object mThermalLock = new Object();
219 @GuardedBy("mThermalLock")
220 private IThermalService mThermalService;
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800221
Jeffrey Huang95765f02020-01-16 11:33:58 -0800222 private final Object mStoragedLock = new Object();
223 @GuardedBy("mStoragedLock")
224 private IStoraged mStorageService;
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800225
Jeffrey Huang730bf962020-01-16 15:59:52 -0800226 private final Object mNotificationStatsLock = new Object();
227 @GuardedBy("mNotificationStatsLock")
228 private INotificationManager mNotificationManagerService;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800229
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800230 private final Object mProcessStatsLock = new Object();
231 @GuardedBy("mProcessStatsLock")
232 private IProcessStats mProcessStatsService;
233
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800234 private final Object mCpuTrackerLock = new Object();
235 @GuardedBy("mCpuTrackerLock")
236 private ProcessCpuTracker mProcessCpuTracker;
237
238 private final Object mDebugElapsedClockLock = new Object();
239 @GuardedBy("mDebugElapsedClockLock")
240 private long mDebugElapsedClockPreviousValue = 0;
241 @GuardedBy("mDebugElapsedClockLock")
242 private long mDebugElapsedClockPullCount = 0;
243
244 private final Object mDebugFailingElapsedClockLock = new Object();
245 @GuardedBy("mDebugFailingElapsedClockLock")
246 private long mDebugFailingElapsedClockPreviousValue = 0;
247 @GuardedBy("mDebugFailingElapsedClockLock")
248 private long mDebugFailingElapsedClockPullCount = 0;
249
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800250 private final Context mContext;
251 private StatsManager mStatsManager;
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -0800252 private StorageManager mStorageManager;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800253 private WifiManager mWifiManager;
254 private TelephonyManager mTelephony;
255
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800256 private KernelWakelockReader mKernelWakelockReader;
257 private KernelWakelockStats mTmpWakelockStats;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800258
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800259 private StoragedUidIoStatsReader mStoragedUidIoStatsReader;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800260
261 private KernelCpuSpeedReader[] mKernelCpuSpeedReaders;
262 // Disables throttler on CPU time readers.
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800263 private KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader;
264 private KernelCpuUidFreqTimeReader mCpuUidFreqTimeReader;
265 private KernelCpuUidActiveTimeReader mCpuUidActiveTimeReader;
266 private KernelCpuUidClusterTimeReader mCpuUidClusterTimeReader;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800267
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800268 private File mBaseDir;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800269
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -0800270 private BatteryService.HealthServiceWrapper mHealthService;
271
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800272 @Nullable
273 private KernelCpuThreadReaderDiff mKernelCpuThreadReader;
274
275 private BatteryStatsHelper mBatteryStatsHelper = null;
276 private long mBatteryStatsHelperTimestampMs = -MAX_BATTERY_STATS_HELPER_FREQUENCY_MS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800277
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800278 private StatsPullAtomCallbackImpl mStatsCallbackImpl;
279
Stanislav Zholnin59199132020-03-06 14:19:25 +0000280 private int mAppOpsSamplingRate = 0;
281
Tej Singh953ad862020-01-03 12:47:07 -0800282 public StatsPullAtomService(Context context) {
283 super(context);
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800284 mContext = context;
Tej Singh953ad862020-01-03 12:47:07 -0800285 }
286
Jeffrey Huang4c527162020-01-30 17:53:13 -0800287 private native void nativeInit();
288
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800289 /**
290 * Use of this StatsPullAtomCallbackImpl means we avoid one class per tagId, which we would
291 * get if we used lambdas.
292 *
293 * The pull methods are intentionally left to be package private to avoid the creation
294 * of synthetic methods to save unnecessary bytecode.
295 */
296 private class StatsPullAtomCallbackImpl implements StatsManager.StatsPullAtomCallback {
297 @Override
298 public int onPullAtom(int atomTag, List<StatsEvent> data) {
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000299 if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
300 Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StatsPull-" + atomTag);
301 }
302 try {
303 switch (atomTag) {
304 case FrameworkStatsLog.WIFI_BYTES_TRANSFER:
junyulai212a5f0e2020-02-07 17:42:39 +0800305 return pullWifiBytesTransfer(atomTag, data, false);
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000306 case FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG:
junyulai212a5f0e2020-02-07 17:42:39 +0800307 return pullWifiBytesTransfer(atomTag, data, true);
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000308 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER:
junyulai212a5f0e2020-02-07 17:42:39 +0800309 return pullMobileBytesTransfer(atomTag, data, false);
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000310 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG:
junyulai212a5f0e2020-02-07 17:42:39 +0800311 return pullMobileBytesTransfer(atomTag, data, true);
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000312 case FrameworkStatsLog.BLUETOOTH_BYTES_TRANSFER:
313 return pullBluetoothBytesTransfer(atomTag, data);
314 case FrameworkStatsLog.KERNEL_WAKELOCK:
315 return pullKernelWakelock(atomTag, data);
316 case FrameworkStatsLog.CPU_TIME_PER_FREQ:
317 return pullCpuTimePerFreq(atomTag, data);
318 case FrameworkStatsLog.CPU_TIME_PER_UID:
319 return pullCpuTimePerUid(atomTag, data);
320 case FrameworkStatsLog.CPU_TIME_PER_UID_FREQ:
321 return pullCpuTimeperUidFreq(atomTag, data);
322 case FrameworkStatsLog.CPU_ACTIVE_TIME:
323 return pullCpuActiveTime(atomTag, data);
324 case FrameworkStatsLog.CPU_CLUSTER_TIME:
325 return pullCpuClusterTime(atomTag, data);
326 case FrameworkStatsLog.WIFI_ACTIVITY_INFO:
327 return pullWifiActivityInfo(atomTag, data);
328 case FrameworkStatsLog.MODEM_ACTIVITY_INFO:
329 return pullModemActivityInfo(atomTag, data);
330 case FrameworkStatsLog.BLUETOOTH_ACTIVITY_INFO:
331 return pullBluetoothActivityInfo(atomTag, data);
332 case FrameworkStatsLog.SYSTEM_ELAPSED_REALTIME:
333 return pullSystemElapsedRealtime(atomTag, data);
334 case FrameworkStatsLog.SYSTEM_UPTIME:
335 return pullSystemUptime(atomTag, data);
336 case FrameworkStatsLog.PROCESS_MEMORY_STATE:
337 return pullProcessMemoryState(atomTag, data);
338 case FrameworkStatsLog.PROCESS_MEMORY_HIGH_WATER_MARK:
339 return pullProcessMemoryHighWaterMark(atomTag, data);
340 case FrameworkStatsLog.PROCESS_MEMORY_SNAPSHOT:
341 return pullProcessMemorySnapshot(atomTag, data);
342 case FrameworkStatsLog.SYSTEM_ION_HEAP_SIZE:
343 return pullSystemIonHeapSize(atomTag, data);
344 case FrameworkStatsLog.ION_HEAP_SIZE:
345 return pullIonHeapSize(atomTag, data);
346 case FrameworkStatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE:
347 return pullProcessSystemIonHeapSize(atomTag, data);
348 case FrameworkStatsLog.TEMPERATURE:
349 return pullTemperature(atomTag, data);
350 case FrameworkStatsLog.COOLING_DEVICE:
351 return pullCooldownDevice(atomTag, data);
352 case FrameworkStatsLog.BINDER_CALLS:
353 return pullBinderCallsStats(atomTag, data);
354 case FrameworkStatsLog.BINDER_CALLS_EXCEPTIONS:
355 return pullBinderCallsStatsExceptions(atomTag, data);
356 case FrameworkStatsLog.LOOPER_STATS:
357 return pullLooperStats(atomTag, data);
358 case FrameworkStatsLog.DISK_STATS:
359 return pullDiskStats(atomTag, data);
360 case FrameworkStatsLog.DIRECTORY_USAGE:
361 return pullDirectoryUsage(atomTag, data);
362 case FrameworkStatsLog.APP_SIZE:
363 return pullAppSize(atomTag, data);
364 case FrameworkStatsLog.CATEGORY_SIZE:
365 return pullCategorySize(atomTag, data);
366 case FrameworkStatsLog.NUM_FINGERPRINTS_ENROLLED:
367 return pullNumBiometricsEnrolled(
368 BiometricsProtoEnums.MODALITY_FINGERPRINT, atomTag, data);
369 case FrameworkStatsLog.NUM_FACES_ENROLLED:
370 return pullNumBiometricsEnrolled(
371 BiometricsProtoEnums.MODALITY_FACE, atomTag, data);
372 case FrameworkStatsLog.PROC_STATS:
373 return pullProcStats(ProcessStats.REPORT_ALL, atomTag, data);
374 case FrameworkStatsLog.PROC_STATS_PKG_PROC:
375 return pullProcStats(ProcessStats.REPORT_PKG_PROC_STATS, atomTag, data);
376 case FrameworkStatsLog.DISK_IO:
377 return pullDiskIO(atomTag, data);
378 case FrameworkStatsLog.POWER_PROFILE:
379 return pullPowerProfile(atomTag, data);
380 case FrameworkStatsLog.PROCESS_CPU_TIME:
381 return pullProcessCpuTime(atomTag, data);
382 case FrameworkStatsLog.CPU_TIME_PER_THREAD_FREQ:
383 return pullCpuTimePerThreadFreq(atomTag, data);
384 case FrameworkStatsLog.DEVICE_CALCULATED_POWER_USE:
385 return pullDeviceCalculatedPowerUse(atomTag, data);
386 case FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_UID:
387 return pullDeviceCalculatedPowerBlameUid(atomTag, data);
388 case FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_OTHER:
389 return pullDeviceCalculatedPowerBlameOther(atomTag, data);
390 case FrameworkStatsLog.DEBUG_ELAPSED_CLOCK:
391 return pullDebugElapsedClock(atomTag, data);
392 case FrameworkStatsLog.DEBUG_FAILING_ELAPSED_CLOCK:
393 return pullDebugFailingElapsedClock(atomTag, data);
394 case FrameworkStatsLog.BUILD_INFORMATION:
395 return pullBuildInformation(atomTag, data);
396 case FrameworkStatsLog.ROLE_HOLDER:
397 return pullRoleHolder(atomTag, data);
398 case FrameworkStatsLog.DANGEROUS_PERMISSION_STATE:
399 return pullDangerousPermissionState(atomTag, data);
400 case FrameworkStatsLog.TIME_ZONE_DATA_INFO:
401 return pullTimeZoneDataInfo(atomTag, data);
402 case FrameworkStatsLog.EXTERNAL_STORAGE_INFO:
403 return pullExternalStorageInfo(atomTag, data);
404 case FrameworkStatsLog.APPS_ON_EXTERNAL_STORAGE_INFO:
405 return pullAppsOnExternalStorageInfo(atomTag, data);
406 case FrameworkStatsLog.FACE_SETTINGS:
407 return pullFaceSettings(atomTag, data);
408 case FrameworkStatsLog.APP_OPS:
409 return pullAppOps(atomTag, data);
410 case FrameworkStatsLog.RUNTIME_APP_OP_ACCESS:
411 return pullRuntimeAppOpAccessMessage(atomTag, data);
412 case FrameworkStatsLog.NOTIFICATION_REMOTE_VIEWS:
413 return pullNotificationRemoteViews(atomTag, data);
414 case FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED:
415 return pullDangerousPermissionState(atomTag, data);
416 case FrameworkStatsLog.BATTERY_LEVEL:
417 case FrameworkStatsLog.REMAINING_BATTERY_CAPACITY:
418 case FrameworkStatsLog.FULL_BATTERY_CAPACITY:
419 case FrameworkStatsLog.BATTERY_VOLTAGE:
420 case FrameworkStatsLog.BATTERY_CYCLE_COUNT:
421 return pullHealthHal(atomTag, data);
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -0800422 case FrameworkStatsLog.ATTRIBUTED_APP_OPS:
423 return pullAttributedAppOps(atomTag, data);
Raff Tsai87cefd42020-04-07 14:25:02 +0800424 case FrameworkStatsLog.SETTING_SNAPSHOT:
425 return pullSettingsStats(atomTag, data);
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000426 default:
427 throw new UnsupportedOperationException("Unknown tagId=" + atomTag);
428 }
429 } finally {
430 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800431 }
432 }
433 }
434
Tej Singh953ad862020-01-03 12:47:07 -0800435 @Override
436 public void onStart() {
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800437 // no op
438 }
439
440 @Override
441 public void onBootPhase(int phase) {
442 super.onBootPhase(phase);
443 if (phase == PHASE_SYSTEM_SERVICES_READY) {
444 BackgroundThread.getHandler().post(() -> {
Jeffrey Huang4c527162020-01-30 17:53:13 -0800445 nativeInit();
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800446 initializePullersState();
447 registerAllPullers();
448 registerEventListeners();
449 });
450 }
451 }
452
453 void initializePullersState() {
454 // Get Context Managers
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800455 mStatsManager = (StatsManager) mContext.getSystemService(Context.STATS_MANAGER);
Jeffrey Huang4df57402020-01-14 11:57:22 -0800456 mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
Jeffrey Huang1f818892020-01-14 12:05:05 -0800457 mTelephony = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -0800458 mStorageManager = (StorageManager) mContext.getSystemService(StorageManager.class);
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -0800459
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800460 // Initialize DiskIO
461 mStoragedUidIoStatsReader = new StoragedUidIoStatsReader();
Jeffrey Huangbf130832020-01-22 15:48:26 -0800462
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800463 // Initialize PROC_STATS
Jeffrey Huangb2cdb1a52020-02-24 15:26:13 -0800464 mBaseDir = new File(SystemServiceManager.ensureSystemDir(), "stats_pull");
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800465
466 // Disables throttler on CPU time readers.
467 mCpuUidUserSysTimeReader = new KernelCpuUidUserSysTimeReader(false);
468 mCpuUidFreqTimeReader = new KernelCpuUidFreqTimeReader(false);
469 mCpuUidActiveTimeReader = new KernelCpuUidActiveTimeReader(false);
470 mCpuUidClusterTimeReader = new KernelCpuUidClusterTimeReader(false);
471
472 // Initialize state for KERNEL_WAKELOCK
473 mKernelWakelockReader = new KernelWakelockReader();
474 mTmpWakelockStats = new KernelWakelockStats();
Jeffrey Huangbf130832020-01-22 15:48:26 -0800475
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800476 // Initialize state for CPU_TIME_PER_FREQ atom
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -0800477 PowerProfile powerProfile = new PowerProfile(mContext);
478 final int numClusters = powerProfile.getNumCpuClusters();
479 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters];
480 int firstCpuOfCluster = 0;
481 for (int i = 0; i < numClusters; i++) {
482 final int numSpeedSteps = powerProfile.getNumSpeedStepsInCpuCluster(i);
483 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster,
484 numSpeedSteps);
485 firstCpuOfCluster += powerProfile.getNumCoresInCpuCluster(i);
486 }
Jeffrey Huangbf4eef82020-01-16 15:38:58 -0800487
488 // Used for CPU_TIME_PER_THREAD_FREQ
489 mKernelCpuThreadReader =
490 KernelCpuThreadReaderSettingsObserver.getSettingsModifiedReader(mContext);
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800491
492 // Used by PROC_STATS and PROC_STATS_PKG_PROC atoms
493 mBaseDir.mkdirs();
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -0800494
495 // Initialize HealthService
496 mHealthService = new BatteryService.HealthServiceWrapper();
497 try {
498 mHealthService.init();
499 } catch (RemoteException e) {
500 Slog.e(TAG, "failed to initialize healthHalWrapper");
501 }
Tej Singh953ad862020-01-03 12:47:07 -0800502 }
503
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800504 void registerEventListeners() {
505 final ConnectivityManager connectivityManager =
506 (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
507 // Default NetworkRequest should cover all transport types.
508 final NetworkRequest request = new NetworkRequest.Builder().build();
509 connectivityManager.registerNetworkCallback(request, new ConnectivityStatsCallback());
510
511 // Enable push notifications of throttling from vendor thermal
512 // management subsystem via thermalservice.
513 IThermalService thermalService = getIThermalService();
514 if (thermalService != null) {
515 try {
516 thermalService.registerThermalEventListener(new ThermalEventListener());
517 Slog.i(TAG, "register thermal listener successfully");
518 } catch (RemoteException e) {
519 Slog.i(TAG, "failed to register thermal listener");
520 }
Tej Singh953ad862020-01-03 12:47:07 -0800521 }
522 }
523
524 void registerAllPullers() {
525 if (DEBUG) {
526 Slog.d(TAG, "Registering all pullers with statsd");
527 }
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800528 mStatsCallbackImpl = new StatsPullAtomCallbackImpl();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800529 registerWifiBytesTransfer();
530 registerWifiBytesTransferBackground();
531 registerMobileBytesTransfer();
532 registerMobileBytesTransferBackground();
533 registerBluetoothBytesTransfer();
534 registerKernelWakelock();
535 registerCpuTimePerFreq();
536 registerCpuTimePerUid();
537 registerCpuTimePerUidFreq();
538 registerCpuActiveTime();
539 registerCpuClusterTime();
540 registerWifiActivityInfo();
541 registerModemActivityInfo();
542 registerBluetoothActivityInfo();
543 registerSystemElapsedRealtime();
544 registerSystemUptime();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800545 registerProcessMemoryState();
546 registerProcessMemoryHighWaterMark();
547 registerProcessMemorySnapshot();
548 registerSystemIonHeapSize();
Rafal Slawikbdd5a502020-01-14 14:14:29 +0000549 registerIonHeapSize();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800550 registerProcessSystemIonHeapSize();
551 registerTemperature();
552 registerCoolingDevice();
Jeffrey Huang877adfe2020-01-15 17:16:43 -0800553 registerBinderCallsStats();
554 registerBinderCallsStatsExceptions();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800555 registerLooperStats();
556 registerDiskStats();
557 registerDirectoryUsage();
558 registerAppSize();
559 registerCategorySize();
560 registerNumFingerprintsEnrolled();
561 registerNumFacesEnrolled();
562 registerProcStats();
563 registerProcStatsPkgProc();
564 registerDiskIO();
565 registerPowerProfile();
566 registerProcessCpuTime();
567 registerCpuTimePerThreadFreq();
568 registerDeviceCalculatedPowerUse();
569 registerDeviceCalculatedPowerBlameUid();
570 registerDeviceCalculatedPowerBlameOther();
571 registerDebugElapsedClock();
572 registerDebugFailingElapsedClock();
573 registerBuildInformation();
574 registerRoleHolder();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800575 registerTimeZoneDataInfo();
576 registerExternalStorageInfo();
577 registerAppsOnExternalStorageInfo();
578 registerFaceSettings();
579 registerAppOps();
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -0800580 registerAttributedAppOps();
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +0000581 registerRuntimeAppOpAccessMessage();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800582 registerNotificationRemoteViews();
583 registerDangerousPermissionState();
584 registerDangerousPermissionStateSampled();
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -0800585 registerBatteryLevel();
Jeffrey Huang43f4d262020-01-30 14:03:31 -0800586 registerRemainingBatteryCapacity();
587 registerFullBatteryCapacity();
588 registerBatteryVoltage();
589 registerBatteryCycleCount();
Raff Tsai87cefd42020-04-07 14:25:02 +0800590 registerSettingsStats();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800591 }
592
junyulai212a5f0e2020-02-07 17:42:39 +0800593 /**
594 * Return the {@code INetworkStatsSession} object that holds the necessary properties needed
595 * for the subsequent queries to {@link com.android.server.net.NetworkStatsService}. Or
596 * null if the service or binder cannot be obtained.
597 */
598 @Nullable
599 private INetworkStatsSession getNetworkStatsSession() {
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800600 synchronized (mNetworkStatsLock) {
junyulai212a5f0e2020-02-07 17:42:39 +0800601 if (mNetworkStatsSession != null) return mNetworkStatsSession;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800602
junyulai212a5f0e2020-02-07 17:42:39 +0800603 final INetworkStatsService networkStatsService =
604 INetworkStatsService.Stub.asInterface(
605 ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
606 if (networkStatsService == null) return null;
607
608 try {
609 networkStatsService.asBinder().linkToDeath(() -> {
610 synchronized (mNetworkStatsLock) {
611 mNetworkStatsSession = null;
612 }
613 }, /* flags */ 0);
614 mNetworkStatsSession = networkStatsService.openSessionForUsageStats(
615 FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, mContext.getOpPackageName());
616 } catch (RemoteException e) {
617 Slog.e(TAG, "Cannot get NetworkStats session", e);
618 mNetworkStatsSession = null;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800619 }
junyulai212a5f0e2020-02-07 17:42:39 +0800620
621 return mNetworkStatsSession;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800622 }
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800623 }
624
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800625 private IThermalService getIThermalService() {
626 synchronized (mThermalLock) {
627 if (mThermalService == null) {
628 mThermalService = IThermalService.Stub.asInterface(
629 ServiceManager.getService(Context.THERMAL_SERVICE));
630 if (mThermalService != null) {
631 try {
632 mThermalService.asBinder().linkToDeath(() -> {
633 synchronized (mThermalLock) {
634 mThermalService = null;
635 }
636 }, /* flags */ 0);
637 } catch (RemoteException e) {
638 Slog.e(TAG, "linkToDeath with thermalService failed", e);
639 mThermalService = null;
640 }
641 }
642 }
643 return mThermalService;
644 }
645 }
Jeffrey Huang95765f02020-01-16 11:33:58 -0800646
647 private IStoraged getIStoragedService() {
648 synchronized (mStoragedLock) {
649 if (mStorageService == null) {
650 mStorageService = IStoraged.Stub.asInterface(
651 ServiceManager.getService("storaged"));
652 }
653 if (mStorageService != null) {
654 try {
655 mStorageService.asBinder().linkToDeath(() -> {
656 synchronized (mStoragedLock) {
657 mStorageService = null;
658 }
659 }, /* flags */ 0);
660 } catch (RemoteException e) {
661 Slog.e(TAG, "linkToDeath with storagedService failed", e);
662 mStorageService = null;
663 }
664 }
665 }
666 return mStorageService;
667 }
668
Jeffrey Huang730bf962020-01-16 15:59:52 -0800669 private INotificationManager getINotificationManagerService() {
670 synchronized (mNotificationStatsLock) {
671 if (mNotificationManagerService == null) {
672 mNotificationManagerService = INotificationManager.Stub.asInterface(
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800673 ServiceManager.getService(Context.NOTIFICATION_SERVICE));
Jeffrey Huang730bf962020-01-16 15:59:52 -0800674 }
675 if (mNotificationManagerService != null) {
676 try {
677 mNotificationManagerService.asBinder().linkToDeath(() -> {
678 synchronized (mNotificationStatsLock) {
679 mNotificationManagerService = null;
680 }
681 }, /* flags */ 0);
682 } catch (RemoteException e) {
683 Slog.e(TAG, "linkToDeath with notificationManager failed", e);
684 mNotificationManagerService = null;
685 }
686 }
687 }
688 return mNotificationManagerService;
689 }
690
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800691 private IProcessStats getIProcessStatsService() {
692 synchronized (mProcessStatsLock) {
693 if (mProcessStatsService == null) {
694 mProcessStatsService = IProcessStats.Stub.asInterface(
695 ServiceManager.getService(ProcessStats.SERVICE_NAME));
696 }
697 if (mProcessStatsService != null) {
698 try {
699 mProcessStatsService.asBinder().linkToDeath(() -> {
700 synchronized (mProcessStatsLock) {
701 mProcessStatsService = null;
702 }
703 }, /* flags */ 0);
704 } catch (RemoteException e) {
705 Slog.e(TAG, "linkToDeath with ProcessStats failed", e);
706 mProcessStatsService = null;
707 }
708 }
709 }
710 return mProcessStatsService;
711 }
712
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800713 private void registerWifiBytesTransfer() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -0800714 int tagId = FrameworkStatsLog.WIFI_BYTES_TRANSFER;
Tej Singh6b979832020-01-02 15:23:02 -0800715 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800716 .setAdditiveFields(new int[] {2, 3, 4, 5})
717 .build();
Tej Singh72a70a82020-02-26 23:46:29 -0800718 mStatsManager.setPullAtomCallback(
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800719 tagId,
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800720 metadata,
Tej Singh6b979832020-01-02 15:23:02 -0800721 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800722 mStatsCallbackImpl
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800723 );
724 }
725
junyulai212a5f0e2020-02-07 17:42:39 +0800726 private int pullWifiBytesTransfer(
727 int atomTag, @NonNull List<StatsEvent> pulledData, boolean withFgbg) {
728 final NetworkTemplate template = NetworkTemplate.buildTemplateWifiWildcard();
729 final NetworkStats stats = getUidNetworkStatsSinceBoot(template, withFgbg);
junyulai592c6052020-04-29 16:09:01 +0800730
731 // Return with PULL_SKIP to indicate there is an error.
732 if (stats == null) return StatsManager.PULL_SKIP;
733
734 addNetworkStats(atomTag, pulledData, stats, withFgbg, 0 /* ratType */);
735 return StatsManager.PULL_SUCCESS;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800736 }
737
junyulai212a5f0e2020-02-07 17:42:39 +0800738 private int pullMobileBytesTransfer(
739 int atomTag, @NonNull List<StatsEvent> pulledData, boolean withFgbg) {
junyulai592c6052020-04-29 16:09:01 +0800740 final NetworkTemplate template =
741 NetworkTemplate.buildTemplateMobileWithRatType(null, NETWORK_TYPE_ALL);
742 final NetworkStats stats = getUidNetworkStatsSinceBoot(template, withFgbg);
743
744 // Return with PULL_SKIP to indicate there is an error.
745 if (stats == null) return StatsManager.PULL_SKIP;
746
747 addNetworkStats(atomTag, pulledData, stats, withFgbg, NETWORK_TYPE_ALL);
748 return StatsManager.PULL_SUCCESS;
junyulai212a5f0e2020-02-07 17:42:39 +0800749 }
750
751 private void addNetworkStats(int atomTag, @NonNull List<StatsEvent> ret,
junyulai317ba5b2020-02-11 14:59:38 +0800752 @NonNull NetworkStats stats, boolean withFgbg, int ratType) {
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800753 int size = stats.size();
junyulai212a5f0e2020-02-07 17:42:39 +0800754 final NetworkStats.Entry entry = new NetworkStats.Entry(); // For recycling
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800755 for (int j = 0; j < size; j++) {
756 stats.getValues(j, entry);
757 StatsEvent.Builder e = StatsEvent.newBuilder();
junyulai212a5f0e2020-02-07 17:42:39 +0800758 e.setAtomId(atomTag);
Muhammad Qureshi09fc8c42020-05-06 14:50:54 -0700759 switch (atomTag) {
760 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER:
761 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG:
762 e.addBooleanAnnotation(ANNOTATION_ID_TRUNCATE_TIMESTAMP, true);
763 break;
764 default:
765 }
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800766 e.writeInt(entry.uid);
Muhammad Qureshi22e52da2020-03-30 21:14:21 -0700767 e.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
junyulai212a5f0e2020-02-07 17:42:39 +0800768 if (withFgbg) {
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800769 e.writeInt(entry.set);
770 }
771 e.writeLong(entry.rxBytes);
772 e.writeLong(entry.rxPackets);
773 e.writeLong(entry.txBytes);
774 e.writeLong(entry.txPackets);
775 ret.add(e.build());
776 }
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800777 }
778
junyulai212a5f0e2020-02-07 17:42:39 +0800779 @Nullable private NetworkStats getUidNetworkStatsSinceBoot(
780 @NonNull NetworkTemplate template, boolean withFgbg) {
781
782 final long elapsedMillisSinceBoot = SystemClock.elapsedRealtime();
783 final long currentTimeInMillis = MICROSECONDS.toMillis(SystemClock.currentTimeMicro());
784 try {
785 final NetworkStats stats = getNetworkStatsSession().getSummaryForAllUid(template,
786 currentTimeInMillis - elapsedMillisSinceBoot, currentTimeInMillis, false);
787 return withFgbg ? rollupNetworkStatsByFgbg(stats) : stats.groupedByUid();
788 } catch (RemoteException | NullPointerException e) {
789 Slog.e(TAG, "Pulling netstats for " + template
790 + " fgbg= " + withFgbg + " bytes has error", e);
791 }
792 return null;
793 }
794
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800795 /**
796 * Allows rollups per UID but keeping the set (foreground/background) slicing.
797 * Adapted from groupedByUid in frameworks/base/core/java/android/net/NetworkStats.java
798 */
junyulai212a5f0e2020-02-07 17:42:39 +0800799 @NonNull private NetworkStats rollupNetworkStatsByFgbg(@NonNull NetworkStats stats) {
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800800 final NetworkStats ret = new NetworkStats(stats.getElapsedRealtime(), 1);
801
802 final NetworkStats.Entry entry = new NetworkStats.Entry();
803 entry.iface = NetworkStats.IFACE_ALL;
804 entry.tag = NetworkStats.TAG_NONE;
805 entry.metered = NetworkStats.METERED_ALL;
806 entry.roaming = NetworkStats.ROAMING_ALL;
807
808 int size = stats.size();
junyulai212a5f0e2020-02-07 17:42:39 +0800809 final NetworkStats.Entry recycle = new NetworkStats.Entry(); // Used for retrieving values
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800810 for (int i = 0; i < size; i++) {
811 stats.getValues(i, recycle);
812
813 // Skip specific tags, since already counted in TAG_NONE
814 if (recycle.tag != NetworkStats.TAG_NONE) continue;
815
816 entry.set = recycle.set; // Allows slicing by background/foreground
817 entry.uid = recycle.uid;
818 entry.rxBytes = recycle.rxBytes;
819 entry.rxPackets = recycle.rxPackets;
820 entry.txBytes = recycle.txBytes;
821 entry.txPackets = recycle.txPackets;
822 // Operations purposefully omitted since we don't use them for statsd.
823 ret.combineValues(entry);
824 }
825 return ret;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800826 }
827
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800828 private void registerWifiBytesTransferBackground() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -0800829 int tagId = FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG;
Tej Singh6b979832020-01-02 15:23:02 -0800830 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800831 .setAdditiveFields(new int[] {3, 4, 5, 6})
832 .build();
Tej Singh72a70a82020-02-26 23:46:29 -0800833 mStatsManager.setPullAtomCallback(
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800834 tagId,
835 metadata,
Tej Singh6b979832020-01-02 15:23:02 -0800836 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800837 mStatsCallbackImpl
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800838 );
839 }
840
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800841 private void registerMobileBytesTransfer() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -0800842 int tagId = FrameworkStatsLog.MOBILE_BYTES_TRANSFER;
Tej Singh6b979832020-01-02 15:23:02 -0800843 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangc8785422020-01-10 15:54:53 -0800844 .setAdditiveFields(new int[] {2, 3, 4, 5})
845 .build();
Tej Singh72a70a82020-02-26 23:46:29 -0800846 mStatsManager.setPullAtomCallback(
Jeffrey Huangc8785422020-01-10 15:54:53 -0800847 tagId,
848 metadata,
Tej Singh6b979832020-01-02 15:23:02 -0800849 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800850 mStatsCallbackImpl
Jeffrey Huangc8785422020-01-10 15:54:53 -0800851 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800852 }
853
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800854 private void registerMobileBytesTransferBackground() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -0800855 int tagId = FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG;
Tej Singh6b979832020-01-02 15:23:02 -0800856 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huang89864442020-01-10 16:35:51 -0800857 .setAdditiveFields(new int[] {3, 4, 5, 6})
858 .build();
Tej Singh72a70a82020-02-26 23:46:29 -0800859 mStatsManager.setPullAtomCallback(
Jeffrey Huang89864442020-01-10 16:35:51 -0800860 tagId,
861 metadata,
Tej Singh6b979832020-01-02 15:23:02 -0800862 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800863 mStatsCallbackImpl
Jeffrey Huang89864442020-01-10 16:35:51 -0800864 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800865 }
866
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800867 private void registerBluetoothBytesTransfer() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -0800868 int tagId = FrameworkStatsLog.BLUETOOTH_BYTES_TRANSFER;
Tej Singh6b979832020-01-02 15:23:02 -0800869 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangfa917892020-01-10 16:58:03 -0800870 .setAdditiveFields(new int[] {2, 3})
871 .build();
Tej Singh72a70a82020-02-26 23:46:29 -0800872 mStatsManager.setPullAtomCallback(
Jeffrey Huangfa917892020-01-10 16:58:03 -0800873 tagId,
874 metadata,
Tej Singh6b979832020-01-02 15:23:02 -0800875 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800876 mStatsCallbackImpl
Jeffrey Huangfa917892020-01-10 16:58:03 -0800877 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800878 }
879
Jeffrey Huangfa917892020-01-10 16:58:03 -0800880 /**
881 * Helper method to extract the Parcelable controller info from a
882 * SynchronousResultReceiver.
883 */
884 private static <T extends Parcelable> T awaitControllerInfo(
885 @Nullable SynchronousResultReceiver receiver) {
886 if (receiver == null) {
887 return null;
888 }
889
890 try {
891 final SynchronousResultReceiver.Result result =
892 receiver.awaitResult(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS);
893 if (result.bundle != null) {
894 // This is the final destination for the Bundle.
895 result.bundle.setDefusable(true);
896
897 final T data = result.bundle.getParcelable(RESULT_RECEIVER_CONTROLLER_KEY);
898 if (data != null) {
899 return data;
900 }
901 }
Jeffrey Huangfa917892020-01-10 16:58:03 -0800902 } catch (TimeoutException e) {
903 Slog.w(TAG, "timeout reading " + receiver.getName() + " stats");
904 }
905 return null;
906 }
907
908 private synchronized BluetoothActivityEnergyInfo fetchBluetoothData() {
909 // TODO: Investigate whether the synchronized keyword is needed.
910 final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
911 if (adapter != null) {
912 SynchronousResultReceiver bluetoothReceiver = new SynchronousResultReceiver(
913 "bluetooth");
914 adapter.requestControllerActivityEnergyInfo(bluetoothReceiver);
915 return awaitControllerInfo(bluetoothReceiver);
916 } else {
917 Slog.e(TAG, "Failed to get bluetooth adapter!");
918 return null;
919 }
920 }
921
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800922 int pullBluetoothBytesTransfer(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangfa917892020-01-10 16:58:03 -0800923 BluetoothActivityEnergyInfo info = fetchBluetoothData();
924 if (info == null || info.getUidTraffic() == null) {
925 return StatsManager.PULL_SKIP;
926 }
927 for (UidTraffic traffic : info.getUidTraffic()) {
928 StatsEvent e = StatsEvent.newBuilder()
929 .setAtomId(atomTag)
930 .writeInt(traffic.getUid())
Muhammad Qureshi22e52da2020-03-30 21:14:21 -0700931 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangfa917892020-01-10 16:58:03 -0800932 .writeLong(traffic.getRxBytes())
933 .writeLong(traffic.getTxBytes())
934 .build();
935 pulledData.add(e);
936 }
937 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800938 }
939
940 private void registerKernelWakelock() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -0800941 int tagId = FrameworkStatsLog.KERNEL_WAKELOCK;
Tej Singh72a70a82020-02-26 23:46:29 -0800942 mStatsManager.setPullAtomCallback(
Jeffrey Huanga6e5a9b2020-01-13 15:59:16 -0800943 tagId,
944 /* PullAtomMetadata */ null,
Tej Singh6b979832020-01-02 15:23:02 -0800945 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800946 mStatsCallbackImpl
Jeffrey Huanga6e5a9b2020-01-13 15:59:16 -0800947 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800948 }
949
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800950 int pullKernelWakelock(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huanga6e5a9b2020-01-13 15:59:16 -0800951 final KernelWakelockStats wakelockStats =
952 mKernelWakelockReader.readKernelWakelockStats(mTmpWakelockStats);
953 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) {
954 String name = ent.getKey();
955 KernelWakelockStats.Entry kws = ent.getValue();
956 StatsEvent e = StatsEvent.newBuilder()
957 .setAtomId(atomTag)
958 .writeString(name)
959 .writeInt(kws.mCount)
960 .writeInt(kws.mVersion)
961 .writeLong(kws.mTotalTime)
962 .build();
963 pulledData.add(e);
964 }
965 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800966 }
967
968 private void registerCpuTimePerFreq() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -0800969 int tagId = FrameworkStatsLog.CPU_TIME_PER_FREQ;
Tej Singh6b979832020-01-02 15:23:02 -0800970 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -0800971 .setAdditiveFields(new int[] {3})
972 .build();
Tej Singh72a70a82020-02-26 23:46:29 -0800973 mStatsManager.setPullAtomCallback(
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -0800974 tagId,
975 metadata,
Tej Singh6b979832020-01-02 15:23:02 -0800976 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800977 mStatsCallbackImpl
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -0800978 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800979 }
980
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800981 int pullCpuTimePerFreq(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -0800982 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) {
983 long[] clusterTimeMs = mKernelCpuSpeedReaders[cluster].readAbsolute();
984 if (clusterTimeMs != null) {
985 for (int speed = clusterTimeMs.length - 1; speed >= 0; --speed) {
986 StatsEvent e = StatsEvent.newBuilder()
987 .setAtomId(atomTag)
988 .writeInt(cluster)
989 .writeInt(speed)
990 .writeLong(clusterTimeMs[speed])
991 .build();
992 pulledData.add(e);
993 }
994 }
995 }
996 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800997 }
998
999 private void registerCpuTimePerUid() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001000 int tagId = FrameworkStatsLog.CPU_TIME_PER_UID;
Tej Singh6b979832020-01-02 15:23:02 -08001001 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangd5f053e2020-01-13 16:27:53 -08001002 .setAdditiveFields(new int[] {2, 3})
1003 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001004 mStatsManager.setPullAtomCallback(
Jeffrey Huangd5f053e2020-01-13 16:27:53 -08001005 tagId,
1006 metadata,
Tej Singh6b979832020-01-02 15:23:02 -08001007 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001008 mStatsCallbackImpl
Jeffrey Huangd5f053e2020-01-13 16:27:53 -08001009 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001010 }
1011
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001012 int pullCpuTimePerUid(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangd5f053e2020-01-13 16:27:53 -08001013 mCpuUidUserSysTimeReader.readAbsolute((uid, timesUs) -> {
1014 long userTimeUs = timesUs[0], systemTimeUs = timesUs[1];
1015 StatsEvent e = StatsEvent.newBuilder()
1016 .setAtomId(atomTag)
1017 .writeInt(uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001018 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangd5f053e2020-01-13 16:27:53 -08001019 .writeLong(userTimeUs)
1020 .writeLong(systemTimeUs)
1021 .build();
1022 pulledData.add(e);
1023 });
1024 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001025 }
1026
1027 private void registerCpuTimePerUidFreq() {
Jeffrey Huanga9899302020-01-13 16:34:03 -08001028 // the throttling is 3sec, handled in
1029 // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001030 int tagId = FrameworkStatsLog.CPU_TIME_PER_UID_FREQ;
Tej Singh6b979832020-01-02 15:23:02 -08001031 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huanga9899302020-01-13 16:34:03 -08001032 .setAdditiveFields(new int[] {4})
1033 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001034 mStatsManager.setPullAtomCallback(
Jeffrey Huanga9899302020-01-13 16:34:03 -08001035 tagId,
1036 metadata,
Tej Singh6b979832020-01-02 15:23:02 -08001037 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001038 mStatsCallbackImpl
Jeffrey Huanga9899302020-01-13 16:34:03 -08001039 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001040 }
1041
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001042 int pullCpuTimeperUidFreq(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huanga9899302020-01-13 16:34:03 -08001043 mCpuUidFreqTimeReader.readAbsolute((uid, cpuFreqTimeMs) -> {
1044 for (int freqIndex = 0; freqIndex < cpuFreqTimeMs.length; ++freqIndex) {
1045 if (cpuFreqTimeMs[freqIndex] != 0) {
1046 StatsEvent e = StatsEvent.newBuilder()
1047 .setAtomId(atomTag)
1048 .writeInt(uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001049 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huanga9899302020-01-13 16:34:03 -08001050 .writeInt(freqIndex)
1051 .writeLong(cpuFreqTimeMs[freqIndex])
1052 .build();
1053 pulledData.add(e);
1054 }
1055 }
1056 });
1057 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001058 }
1059
1060 private void registerCpuActiveTime() {
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001061 // the throttling is 3sec, handled in
1062 // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001063 int tagId = FrameworkStatsLog.CPU_ACTIVE_TIME;
Tej Singh6b979832020-01-02 15:23:02 -08001064 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001065 .setAdditiveFields(new int[] {2})
1066 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001067 mStatsManager.setPullAtomCallback(
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001068 tagId,
1069 metadata,
Tej Singh6b979832020-01-02 15:23:02 -08001070 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001071 mStatsCallbackImpl
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001072 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001073 }
1074
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001075 int pullCpuActiveTime(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001076 mCpuUidActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> {
1077 StatsEvent e = StatsEvent.newBuilder()
1078 .setAtomId(atomTag)
1079 .writeInt(uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001080 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001081 .writeLong(cpuActiveTimesMs)
1082 .build();
1083 pulledData.add(e);
1084 });
1085 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001086 }
1087
1088 private void registerCpuClusterTime() {
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001089 // the throttling is 3sec, handled in
1090 // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001091 int tagId = FrameworkStatsLog.CPU_CLUSTER_TIME;
Tej Singh6b979832020-01-02 15:23:02 -08001092 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001093 .setAdditiveFields(new int[] {3})
1094 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001095 mStatsManager.setPullAtomCallback(
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001096 tagId,
1097 metadata,
Tej Singh6b979832020-01-02 15:23:02 -08001098 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001099 mStatsCallbackImpl
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001100 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001101 }
1102
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001103 int pullCpuClusterTime(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001104 mCpuUidClusterTimeReader.readAbsolute((uid, cpuClusterTimesMs) -> {
1105 for (int i = 0; i < cpuClusterTimesMs.length; i++) {
1106 StatsEvent e = StatsEvent.newBuilder()
1107 .setAtomId(atomTag)
1108 .writeInt(uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001109 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001110 .writeInt(i)
1111 .writeLong(cpuClusterTimesMs[i])
1112 .build();
1113 pulledData.add(e);
1114 }
1115 });
1116 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001117 }
1118
1119 private void registerWifiActivityInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001120 int tagId = FrameworkStatsLog.WIFI_ACTIVITY_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08001121 mStatsManager.setPullAtomCallback(
Jeffrey Huang4df57402020-01-14 11:57:22 -08001122 tagId,
1123 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001124 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001125 mStatsCallbackImpl
Jeffrey Huang4df57402020-01-14 11:57:22 -08001126 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001127 }
1128
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001129 int pullWifiActivityInfo(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang4df57402020-01-14 11:57:22 -08001130 long token = Binder.clearCallingIdentity();
1131 try {
1132 SynchronousResultReceiver wifiReceiver = new SynchronousResultReceiver("wifi");
1133 mWifiManager.getWifiActivityEnergyInfoAsync(
1134 new Executor() {
1135 @Override
1136 public void execute(Runnable runnable) {
1137 // run the listener on the binder thread, if it was run on the main
1138 // thread it would deadlock since we would be waiting on ourselves
1139 runnable.run();
1140 }
1141 },
1142 info -> {
1143 Bundle bundle = new Bundle();
1144 bundle.putParcelable(BatteryStats.RESULT_RECEIVER_CONTROLLER_KEY, info);
1145 wifiReceiver.send(0, bundle);
1146 }
1147 );
1148 final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver);
1149 if (wifiInfo == null) {
1150 return StatsManager.PULL_SKIP;
1151 }
1152 StatsEvent e = StatsEvent.newBuilder()
1153 .setAtomId(atomTag)
1154 .writeLong(wifiInfo.getTimeSinceBootMillis())
1155 .writeInt(wifiInfo.getStackState())
1156 .writeLong(wifiInfo.getControllerTxDurationMillis())
1157 .writeLong(wifiInfo.getControllerRxDurationMillis())
1158 .writeLong(wifiInfo.getControllerIdleDurationMillis())
1159 .writeLong(wifiInfo.getControllerEnergyUsedMicroJoules())
1160 .build();
1161 pulledData.add(e);
1162 } catch (RuntimeException e) {
1163 Slog.e(TAG, "failed to getWifiActivityEnergyInfoAsync", e);
1164 return StatsManager.PULL_SKIP;
1165 } finally {
1166 Binder.restoreCallingIdentity(token);
1167 }
1168 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001169 }
1170
1171 private void registerModemActivityInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001172 int tagId = FrameworkStatsLog.MODEM_ACTIVITY_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08001173 mStatsManager.setPullAtomCallback(
Jeffrey Huang1f818892020-01-14 12:05:05 -08001174 tagId,
1175 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001176 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001177 mStatsCallbackImpl
Jeffrey Huang1f818892020-01-14 12:05:05 -08001178 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001179 }
1180
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001181 int pullModemActivityInfo(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang1f818892020-01-14 12:05:05 -08001182 long token = Binder.clearCallingIdentity();
1183 try {
1184 SynchronousResultReceiver modemReceiver = new SynchronousResultReceiver("telephony");
1185 mTelephony.requestModemActivityInfo(modemReceiver);
1186 final ModemActivityInfo modemInfo = awaitControllerInfo(modemReceiver);
1187 if (modemInfo == null) {
1188 return StatsManager.PULL_SKIP;
1189 }
1190 StatsEvent e = StatsEvent.newBuilder()
1191 .setAtomId(atomTag)
1192 .writeLong(modemInfo.getTimestamp())
1193 .writeLong(modemInfo.getSleepTimeMillis())
1194 .writeLong(modemInfo.getIdleTimeMillis())
1195 .writeLong(modemInfo.getTransmitPowerInfo().get(0).getTimeInMillis())
1196 .writeLong(modemInfo.getTransmitPowerInfo().get(1).getTimeInMillis())
1197 .writeLong(modemInfo.getTransmitPowerInfo().get(2).getTimeInMillis())
1198 .writeLong(modemInfo.getTransmitPowerInfo().get(3).getTimeInMillis())
1199 .writeLong(modemInfo.getTransmitPowerInfo().get(4).getTimeInMillis())
1200 .writeLong(modemInfo.getReceiveTimeMillis())
1201 .build();
1202 pulledData.add(e);
1203 } finally {
1204 Binder.restoreCallingIdentity(token);
1205 }
1206 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001207 }
1208
1209 private void registerBluetoothActivityInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001210 int tagId = FrameworkStatsLog.BLUETOOTH_ACTIVITY_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08001211 mStatsManager.setPullAtomCallback(
Jeffrey Huangaafccb32020-01-13 10:16:58 -08001212 tagId,
1213 /* metadata */ null,
Tej Singh6b979832020-01-02 15:23:02 -08001214 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001215 mStatsCallbackImpl
Jeffrey Huangaafccb32020-01-13 10:16:58 -08001216 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001217 }
1218
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001219 int pullBluetoothActivityInfo(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangaafccb32020-01-13 10:16:58 -08001220 BluetoothActivityEnergyInfo info = fetchBluetoothData();
1221 if (info == null) {
1222 return StatsManager.PULL_SKIP;
1223 }
1224 StatsEvent e = StatsEvent.newBuilder()
1225 .setAtomId(atomTag)
1226 .writeLong(info.getTimeStamp())
1227 .writeInt(info.getBluetoothStackState())
1228 .writeLong(info.getControllerTxTimeMillis())
1229 .writeLong(info.getControllerRxTimeMillis())
1230 .writeLong(info.getControllerIdleTimeMillis())
1231 .writeLong(info.getControllerEnergyUsed())
1232 .build();
1233 pulledData.add(e);
1234 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001235 }
1236
1237 private void registerSystemElapsedRealtime() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001238 int tagId = FrameworkStatsLog.SYSTEM_ELAPSED_REALTIME;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001239 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Tej Singh72a70a82020-02-26 23:46:29 -08001240 .setCoolDownMillis(MILLIS_PER_SEC)
1241 .setTimeoutMillis(MILLIS_PER_SEC / 2)
Jeffrey Huang882f99a2020-01-14 14:33:52 -08001242 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001243 mStatsManager.setPullAtomCallback(
Jeffrey Huang882f99a2020-01-14 14:33:52 -08001244 tagId,
1245 metadata,
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001246 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001247 mStatsCallbackImpl
Jeffrey Huang882f99a2020-01-14 14:33:52 -08001248 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001249 }
1250
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001251 int pullSystemElapsedRealtime(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang882f99a2020-01-14 14:33:52 -08001252 StatsEvent e = StatsEvent.newBuilder()
1253 .setAtomId(atomTag)
1254 .writeLong(SystemClock.elapsedRealtime())
1255 .build();
1256 pulledData.add(e);
1257 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001258 }
1259
1260 private void registerSystemUptime() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001261 int tagId = FrameworkStatsLog.SYSTEM_UPTIME;
Tej Singh72a70a82020-02-26 23:46:29 -08001262 mStatsManager.setPullAtomCallback(
Ruchir Rastogice29fc12020-01-09 17:08:20 -08001263 tagId,
1264 null, // use default PullAtomMetadata values
Tej Singh6b979832020-01-02 15:23:02 -08001265 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001266 mStatsCallbackImpl
Ruchir Rastogice29fc12020-01-09 17:08:20 -08001267 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001268 }
1269
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001270 int pullSystemUptime(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogice29fc12020-01-09 17:08:20 -08001271 StatsEvent e = StatsEvent.newBuilder()
1272 .setAtomId(atomTag)
tsaichristinedc1c34a2020-03-18 14:43:06 -07001273 .writeLong(SystemClock.uptimeMillis())
Ruchir Rastogice29fc12020-01-09 17:08:20 -08001274 .build();
1275 pulledData.add(e);
1276 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001277 }
1278
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001279 private void registerProcessMemoryState() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001280 int tagId = FrameworkStatsLog.PROCESS_MEMORY_STATE;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001281 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001282 .setAdditiveFields(new int[] {4, 5, 6, 7, 8})
1283 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001284 mStatsManager.setPullAtomCallback(
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001285 tagId,
1286 metadata,
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001287 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001288 mStatsCallbackImpl
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001289 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001290 }
1291
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001292 int pullProcessMemoryState(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001293 List<ProcessMemoryState> processMemoryStates =
1294 LocalServices.getService(ActivityManagerInternal.class)
1295 .getMemoryStateForProcesses();
1296 for (ProcessMemoryState processMemoryState : processMemoryStates) {
1297 final MemoryStat memoryStat = readMemoryStatFromFilesystem(processMemoryState.uid,
1298 processMemoryState.pid);
1299 if (memoryStat == null) {
1300 continue;
1301 }
1302 StatsEvent e = StatsEvent.newBuilder()
1303 .setAtomId(atomTag)
1304 .writeInt(processMemoryState.uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001305 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001306 .writeString(processMemoryState.processName)
1307 .writeInt(processMemoryState.oomScore)
1308 .writeLong(memoryStat.pgfault)
1309 .writeLong(memoryStat.pgmajfault)
1310 .writeLong(memoryStat.rssInBytes)
1311 .writeLong(memoryStat.cacheInBytes)
1312 .writeLong(memoryStat.swapInBytes)
1313 .writeLong(-1) // unused
1314 .writeLong(-1) // unused
1315 .writeInt(-1) // unused
1316 .build();
1317 pulledData.add(e);
1318 }
1319 return StatsManager.PULL_SUCCESS;
1320 }
1321
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001322 private static boolean isAppUid(int uid) {
1323 return uid >= MIN_APP_UID;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001324 }
1325
1326 private void registerProcessMemoryHighWaterMark() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001327 int tagId = FrameworkStatsLog.PROCESS_MEMORY_HIGH_WATER_MARK;
Tej Singh72a70a82020-02-26 23:46:29 -08001328 mStatsManager.setPullAtomCallback(
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001329 tagId,
1330 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001331 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001332 mStatsCallbackImpl
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001333 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001334 }
1335
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001336 int pullProcessMemoryHighWaterMark(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001337 List<ProcessMemoryState> managedProcessList =
1338 LocalServices.getService(ActivityManagerInternal.class)
1339 .getMemoryStateForProcesses();
1340 for (ProcessMemoryState managedProcess : managedProcessList) {
1341 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(managedProcess.pid);
1342 if (snapshot == null) {
1343 continue;
1344 }
1345 StatsEvent e = StatsEvent.newBuilder()
1346 .setAtomId(atomTag)
1347 .writeInt(managedProcess.uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001348 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001349 .writeString(managedProcess.processName)
1350 // RSS high-water mark in bytes.
1351 .writeLong(snapshot.rssHighWaterMarkInKilobytes * 1024L)
1352 .writeInt(snapshot.rssHighWaterMarkInKilobytes)
1353 .build();
1354 pulledData.add(e);
1355 }
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001356 // Complement the data with native system processes
1357 SparseArray<String> processCmdlines = getProcessCmdlines();
1358 managedProcessList.forEach(managedProcess -> processCmdlines.delete(managedProcess.pid));
1359 int size = processCmdlines.size();
1360 for (int i = 0; i < size; ++i) {
1361 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(processCmdlines.keyAt(i));
1362 if (snapshot == null || isAppUid(snapshot.uid)) {
1363 continue;
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001364 }
1365 StatsEvent e = StatsEvent.newBuilder()
1366 .setAtomId(atomTag)
1367 .writeInt(snapshot.uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001368 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001369 .writeString(processCmdlines.valueAt(i))
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001370 // RSS high-water mark in bytes.
1371 .writeLong(snapshot.rssHighWaterMarkInKilobytes * 1024L)
1372 .writeInt(snapshot.rssHighWaterMarkInKilobytes)
1373 .build();
1374 pulledData.add(e);
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001375 }
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001376 // Invoke rss_hwm_reset binary to reset RSS HWM counters for all processes.
1377 SystemProperties.set("sys.rss_hwm_reset.on", "1");
1378 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001379 }
1380
1381 private void registerProcessMemorySnapshot() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001382 int tagId = FrameworkStatsLog.PROCESS_MEMORY_SNAPSHOT;
Tej Singh72a70a82020-02-26 23:46:29 -08001383 mStatsManager.setPullAtomCallback(
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001384 tagId,
1385 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001386 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001387 mStatsCallbackImpl
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001388 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001389 }
1390
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001391 int pullProcessMemorySnapshot(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001392 List<ProcessMemoryState> managedProcessList =
1393 LocalServices.getService(ActivityManagerInternal.class)
1394 .getMemoryStateForProcesses();
1395 for (ProcessMemoryState managedProcess : managedProcessList) {
1396 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(managedProcess.pid);
1397 if (snapshot == null) {
1398 continue;
1399 }
1400 StatsEvent e = StatsEvent.newBuilder()
Ioannis Ilkosda5d8812020-01-27 16:04:10 +00001401 .setAtomId(atomTag)
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001402 .writeInt(managedProcess.uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001403 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001404 .writeString(managedProcess.processName)
1405 .writeInt(managedProcess.pid)
1406 .writeInt(managedProcess.oomScore)
1407 .writeInt(snapshot.rssInKilobytes)
1408 .writeInt(snapshot.anonRssInKilobytes)
1409 .writeInt(snapshot.swapInKilobytes)
1410 .writeInt(snapshot.anonRssInKilobytes + snapshot.swapInKilobytes)
1411 .build();
1412 pulledData.add(e);
1413 }
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001414 // Complement the data with native system processes. Given these measurements can be taken
1415 // in response to LMKs happening, we want to first collect the managed app stats (to
1416 // maximize the probability that a heavyweight process will be sampled before it dies).
1417 SparseArray<String> processCmdlines = getProcessCmdlines();
1418 managedProcessList.forEach(managedProcess -> processCmdlines.delete(managedProcess.pid));
1419 int size = processCmdlines.size();
1420 for (int i = 0; i < size; ++i) {
1421 int pid = processCmdlines.keyAt(i);
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001422 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(pid);
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001423 if (snapshot == null || isAppUid(snapshot.uid)) {
1424 continue;
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001425 }
1426 StatsEvent e = StatsEvent.newBuilder()
1427 .setAtomId(atomTag)
1428 .writeInt(snapshot.uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001429 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001430 .writeString(processCmdlines.valueAt(i))
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001431 .writeInt(pid)
1432 .writeInt(-1001) // Placeholder for native processes, OOM_SCORE_ADJ_MIN - 1.
1433 .writeInt(snapshot.rssInKilobytes)
1434 .writeInt(snapshot.anonRssInKilobytes)
1435 .writeInt(snapshot.swapInKilobytes)
1436 .writeInt(snapshot.anonRssInKilobytes + snapshot.swapInKilobytes)
1437 .build();
1438 pulledData.add(e);
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001439 }
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001440 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001441 }
1442
1443 private void registerSystemIonHeapSize() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001444 int tagId = FrameworkStatsLog.SYSTEM_ION_HEAP_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08001445 mStatsManager.setPullAtomCallback(
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001446 tagId,
1447 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001448 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001449 mStatsCallbackImpl
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001450 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001451 }
1452
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001453 int pullSystemIonHeapSize(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001454 final long systemIonHeapSizeInBytes = readSystemIonHeapSizeFromDebugfs();
1455 StatsEvent e = StatsEvent.newBuilder()
1456 .setAtomId(atomTag)
1457 .writeLong(systemIonHeapSizeInBytes)
1458 .build();
1459 pulledData.add(e);
1460 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001461 }
1462
Rafal Slawikbdd5a502020-01-14 14:14:29 +00001463 private void registerIonHeapSize() {
Rafal Slawikded83052020-02-28 13:20:13 +00001464 if (!new File("/sys/kernel/ion/total_heaps_kb").exists()) {
1465 return;
1466 }
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001467 int tagId = FrameworkStatsLog.ION_HEAP_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08001468 mStatsManager.setPullAtomCallback(
Rafal Slawikbdd5a502020-01-14 14:14:29 +00001469 tagId,
1470 /* PullAtomMetadata */ null,
Tej Singh6b979832020-01-02 15:23:02 -08001471 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001472 mStatsCallbackImpl
Rafal Slawikbdd5a502020-01-14 14:14:29 +00001473 );
1474 }
1475
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001476 int pullIonHeapSize(int atomTag, List<StatsEvent> pulledData) {
Rafal Slawikbdd5a502020-01-14 14:14:29 +00001477 int ionHeapSizeInKilobytes = (int) getIonHeapsSizeKb();
1478 StatsEvent e = StatsEvent.newBuilder()
1479 .setAtomId(atomTag)
1480 .writeInt(ionHeapSizeInKilobytes)
1481 .build();
1482 pulledData.add(e);
1483 return StatsManager.PULL_SUCCESS;
1484 }
1485
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001486 private void registerProcessSystemIonHeapSize() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001487 int tagId = FrameworkStatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08001488 mStatsManager.setPullAtomCallback(
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001489 tagId,
1490 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001491 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001492 mStatsCallbackImpl
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001493 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001494 }
1495
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001496 int pullProcessSystemIonHeapSize(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001497 List<IonAllocations> result = readProcessSystemIonHeapSizesFromDebugfs();
1498 for (IonAllocations allocations : result) {
1499 StatsEvent e = StatsEvent.newBuilder()
1500 .setAtomId(atomTag)
1501 .writeInt(getUidForPid(allocations.pid))
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001502 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001503 .writeString(readCmdlineFromProcfs(allocations.pid))
1504 .writeInt((int) (allocations.totalSizeInBytes / 1024))
1505 .writeInt(allocations.count)
1506 .writeInt((int) (allocations.maxSizeInBytes / 1024))
1507 .build();
1508 pulledData.add(e);
1509 }
1510 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001511 }
1512
1513 private void registerTemperature() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001514 int tagId = FrameworkStatsLog.TEMPERATURE;
Tej Singh72a70a82020-02-26 23:46:29 -08001515 mStatsManager.setPullAtomCallback(
Jeffrey Huangb92de552020-01-15 16:50:07 -08001516 tagId,
1517 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001518 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001519 mStatsCallbackImpl
Jeffrey Huangb92de552020-01-15 16:50:07 -08001520 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001521 }
1522
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001523 int pullTemperature(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb92de552020-01-15 16:50:07 -08001524 IThermalService thermalService = getIThermalService();
1525 if (thermalService == null) {
1526 return StatsManager.PULL_SKIP;
1527 }
1528 final long callingToken = Binder.clearCallingIdentity();
1529 try {
Chris Ye48dbcaa2020-02-10 13:29:01 -08001530 Temperature temperatures[] = thermalService.getCurrentTemperatures();
Jeffrey Huangb92de552020-01-15 16:50:07 -08001531 for (Temperature temp : temperatures) {
1532 StatsEvent e = StatsEvent.newBuilder()
1533 .setAtomId(atomTag)
1534 .writeInt(temp.getType())
1535 .writeString(temp.getName())
1536 .writeInt((int) (temp.getValue() * 10))
1537 .writeInt(temp.getStatus())
1538 .build();
1539 pulledData.add(e);
1540 }
1541 } catch (RemoteException e) {
1542 // Should not happen.
1543 Slog.e(TAG, "Disconnected from thermal service. Cannot pull temperatures.");
1544 return StatsManager.PULL_SKIP;
1545 } finally {
1546 Binder.restoreCallingIdentity(callingToken);
1547 }
1548 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001549 }
1550
1551 private void registerCoolingDevice() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001552 int tagId = FrameworkStatsLog.COOLING_DEVICE;
Tej Singh72a70a82020-02-26 23:46:29 -08001553 mStatsManager.setPullAtomCallback(
Jeffrey Huangb92de552020-01-15 16:50:07 -08001554 tagId,
1555 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001556 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001557 mStatsCallbackImpl
Jeffrey Huangb92de552020-01-15 16:50:07 -08001558 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001559 }
1560
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001561 int pullCooldownDevice(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb92de552020-01-15 16:50:07 -08001562 IThermalService thermalService = getIThermalService();
1563 if (thermalService == null) {
1564 return StatsManager.PULL_SKIP;
1565 }
1566 final long callingToken = Binder.clearCallingIdentity();
1567 try {
Chris Ye48dbcaa2020-02-10 13:29:01 -08001568 CoolingDevice devices[] = thermalService.getCurrentCoolingDevices();
Jeffrey Huangb92de552020-01-15 16:50:07 -08001569 for (CoolingDevice device : devices) {
1570 StatsEvent e = StatsEvent.newBuilder()
1571 .setAtomId(atomTag)
1572 .writeInt(device.getType())
1573 .writeString(device.getName())
1574 .writeInt((int) (device.getValue()))
1575 .build();
1576 pulledData.add(e);
1577 }
1578 } catch (RemoteException e) {
1579 // Should not happen.
1580 Slog.e(TAG, "Disconnected from thermal service. Cannot pull temperatures.");
1581 return StatsManager.PULL_SKIP;
1582 } finally {
1583 Binder.restoreCallingIdentity(callingToken);
1584 }
1585 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001586 }
1587
Jeffrey Huang877adfe2020-01-15 17:16:43 -08001588 private void registerBinderCallsStats() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001589 int tagId = FrameworkStatsLog.BINDER_CALLS;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001590 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huang877adfe2020-01-15 17:16:43 -08001591 .setAdditiveFields(new int[] {4, 5, 6, 8, 12})
1592 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001593 mStatsManager.setPullAtomCallback(
Jeffrey Huang877adfe2020-01-15 17:16:43 -08001594 tagId,
1595 metadata,
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001596 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001597 mStatsCallbackImpl
Jeffrey Huang877adfe2020-01-15 17:16:43 -08001598 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001599 }
1600
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001601 int pullBinderCallsStats(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang877adfe2020-01-15 17:16:43 -08001602 BinderCallsStatsService.Internal binderStats =
1603 LocalServices.getService(BinderCallsStatsService.Internal.class);
1604 if (binderStats == null) {
1605 Slog.e(TAG, "failed to get binderStats");
1606 return StatsManager.PULL_SKIP;
1607 }
1608
1609 List<ExportedCallStat> callStats = binderStats.getExportedCallStats();
1610 binderStats.reset();
1611 for (ExportedCallStat callStat : callStats) {
1612 StatsEvent e = StatsEvent.newBuilder()
1613 .setAtomId(atomTag)
1614 .writeInt(callStat.workSourceUid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001615 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huang877adfe2020-01-15 17:16:43 -08001616 .writeString(callStat.className)
1617 .writeString(callStat.methodName)
1618 .writeLong(callStat.callCount)
1619 .writeLong(callStat.exceptionCount)
1620 .writeLong(callStat.latencyMicros)
1621 .writeLong(callStat.maxLatencyMicros)
1622 .writeLong(callStat.cpuTimeMicros)
1623 .writeLong(callStat.maxCpuTimeMicros)
1624 .writeLong(callStat.maxReplySizeBytes)
1625 .writeLong(callStat.maxRequestSizeBytes)
1626 .writeLong(callStat.recordedCallCount)
1627 .writeInt(callStat.screenInteractive ? 1 : 0)
1628 .writeInt(callStat.callingUid)
1629 .build();
1630 pulledData.add(e);
1631 }
1632 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001633 }
1634
Jeffrey Huang877adfe2020-01-15 17:16:43 -08001635 private void registerBinderCallsStatsExceptions() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001636 int tagId = FrameworkStatsLog.BINDER_CALLS_EXCEPTIONS;
Tej Singh72a70a82020-02-26 23:46:29 -08001637 mStatsManager.setPullAtomCallback(
Jeffrey Huang877adfe2020-01-15 17:16:43 -08001638 tagId,
1639 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001640 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001641 mStatsCallbackImpl
Jeffrey Huang877adfe2020-01-15 17:16:43 -08001642 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001643 }
1644
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001645 int pullBinderCallsStatsExceptions(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang877adfe2020-01-15 17:16:43 -08001646 BinderCallsStatsService.Internal binderStats =
1647 LocalServices.getService(BinderCallsStatsService.Internal.class);
1648 if (binderStats == null) {
1649 Slog.e(TAG, "failed to get binderStats");
1650 return StatsManager.PULL_SKIP;
1651 }
1652
1653 ArrayMap<String, Integer> exceptionStats = binderStats.getExportedExceptionStats();
1654 // TODO: decouple binder calls exceptions with the rest of the binder calls data so that we
1655 // can reset the exception stats.
1656 for (Map.Entry<String, Integer> entry : exceptionStats.entrySet()) {
1657 StatsEvent e = StatsEvent.newBuilder()
1658 .setAtomId(atomTag)
1659 .writeString(entry.getKey())
1660 .writeInt(entry.getValue())
1661 .build();
1662 pulledData.add(e);
1663 }
1664 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001665 }
1666
1667 private void registerLooperStats() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001668 int tagId = FrameworkStatsLog.LOOPER_STATS;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001669 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangfd037c52020-01-16 10:42:59 -08001670 .setAdditiveFields(new int[] {5, 6, 7, 8, 9})
1671 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001672 mStatsManager.setPullAtomCallback(
Jeffrey Huangfd037c52020-01-16 10:42:59 -08001673 tagId,
1674 metadata,
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001675 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001676 mStatsCallbackImpl
Jeffrey Huangfd037c52020-01-16 10:42:59 -08001677 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001678 }
1679
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001680 int pullLooperStats(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangfd037c52020-01-16 10:42:59 -08001681 LooperStats looperStats = LocalServices.getService(LooperStats.class);
1682 if (looperStats == null) {
1683 return StatsManager.PULL_SKIP;
1684 }
1685
1686 List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
1687 looperStats.reset();
1688 for (LooperStats.ExportedEntry entry : entries) {
1689 StatsEvent e = StatsEvent.newBuilder()
1690 .setAtomId(atomTag)
1691 .writeInt(entry.workSourceUid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001692 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangfd037c52020-01-16 10:42:59 -08001693 .writeString(entry.handlerClassName)
1694 .writeString(entry.threadName)
1695 .writeString(entry.messageName)
1696 .writeLong(entry.messageCount)
1697 .writeLong(entry.exceptionCount)
1698 .writeLong(entry.recordedMessageCount)
1699 .writeLong(entry.totalLatencyMicros)
1700 .writeLong(entry.cpuUsageMicros)
1701 .writeBoolean(entry.isInteractive)
1702 .writeLong(entry.maxCpuUsageMicros)
1703 .writeLong(entry.maxLatencyMicros)
1704 .writeLong(entry.recordedDelayMessageCount)
1705 .writeLong(entry.delayMillis)
1706 .writeLong(entry.maxDelayMillis)
1707 .build();
1708 pulledData.add(e);
1709 }
1710 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001711 }
1712
1713 private void registerDiskStats() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001714 int tagId = FrameworkStatsLog.DISK_STATS;
Tej Singh72a70a82020-02-26 23:46:29 -08001715 mStatsManager.setPullAtomCallback(
Jeffrey Huang95765f02020-01-16 11:33:58 -08001716 tagId,
1717 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001718 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001719 mStatsCallbackImpl
Jeffrey Huang95765f02020-01-16 11:33:58 -08001720 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001721 }
1722
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001723 int pullDiskStats(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang95765f02020-01-16 11:33:58 -08001724 // Run a quick-and-dirty performance test: write 512 bytes
1725 byte[] junk = new byte[512];
1726 for (int i = 0; i < junk.length; i++) junk[i] = (byte) i; // Write nonzero bytes
1727
1728 File tmp = new File(Environment.getDataDirectory(), "system/statsdperftest.tmp");
1729 FileOutputStream fos = null;
1730 IOException error = null;
1731
1732 long before = SystemClock.elapsedRealtime();
1733 try {
1734 fos = new FileOutputStream(tmp);
1735 fos.write(junk);
1736 } catch (IOException e) {
1737 error = e;
1738 } finally {
1739 try {
1740 if (fos != null) fos.close();
1741 } catch (IOException e) {
1742 // Do nothing.
1743 }
1744 }
1745
1746 long latency = SystemClock.elapsedRealtime() - before;
1747 if (tmp.exists()) tmp.delete();
1748
1749 if (error != null) {
1750 Slog.e(TAG, "Error performing diskstats latency test");
1751 latency = -1;
1752 }
1753 // File based encryption.
1754 boolean fileBased = StorageManager.isFileEncryptedNativeOnly();
1755
1756 //Recent disk write speed. Binder call to storaged.
1757 int writeSpeed = -1;
1758 IStoraged storaged = getIStoragedService();
1759 if (storaged == null) {
1760 return StatsManager.PULL_SKIP;
1761 }
1762 try {
1763 writeSpeed = storaged.getRecentPerf();
1764 } catch (RemoteException e) {
1765 Slog.e(TAG, "storaged not found");
1766 }
1767
1768 // Add info pulledData.
1769 StatsEvent e = StatsEvent.newBuilder()
1770 .setAtomId(atomTag)
1771 .writeLong(latency)
1772 .writeBoolean(fileBased)
1773 .writeInt(writeSpeed)
1774 .build();
1775 pulledData.add(e);
1776 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001777 }
1778
1779 private void registerDirectoryUsage() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001780 int tagId = FrameworkStatsLog.DIRECTORY_USAGE;
Tej Singh72a70a82020-02-26 23:46:29 -08001781 mStatsManager.setPullAtomCallback(
Jeffrey Huang95765f02020-01-16 11:33:58 -08001782 tagId,
1783 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001784 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001785 mStatsCallbackImpl
Jeffrey Huang95765f02020-01-16 11:33:58 -08001786 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001787 }
1788
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001789 int pullDirectoryUsage(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang95765f02020-01-16 11:33:58 -08001790 StatFs statFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath());
1791 StatFs statFsSystem = new StatFs(Environment.getRootDirectory().getAbsolutePath());
1792 StatFs statFsCache = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath());
1793
1794 StatsEvent e = StatsEvent.newBuilder()
1795 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001796 .writeInt(FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__DATA)
Jeffrey Huang95765f02020-01-16 11:33:58 -08001797 .writeLong(statFsData.getAvailableBytes())
1798 .writeLong(statFsData.getTotalBytes())
1799 .build();
1800 pulledData.add(e);
1801
1802 e = StatsEvent.newBuilder()
1803 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001804 .writeInt(FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__CACHE)
Jeffrey Huang95765f02020-01-16 11:33:58 -08001805 .writeLong(statFsCache.getAvailableBytes())
1806 .writeLong(statFsCache.getTotalBytes())
1807 .build();
1808 pulledData.add(e);
1809
1810 e = StatsEvent.newBuilder()
1811 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001812 .writeInt(FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__SYSTEM)
Jeffrey Huang95765f02020-01-16 11:33:58 -08001813 .writeLong(statFsSystem.getAvailableBytes())
1814 .writeLong(statFsSystem.getTotalBytes())
1815 .build();
1816 pulledData.add(e);
1817 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001818 }
1819
1820 private void registerAppSize() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001821 int tagId = FrameworkStatsLog.APP_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08001822 mStatsManager.setPullAtomCallback(
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001823 tagId,
1824 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001825 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001826 mStatsCallbackImpl
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001827 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001828 }
1829
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001830 int pullAppSize(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001831 try {
1832 String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
1833 JSONObject json = new JSONObject(jsonStr);
1834 long cache_time = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L);
1835 JSONArray pkg_names = json.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY);
1836 JSONArray app_sizes = json.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY);
1837 JSONArray app_data_sizes = json.getJSONArray(DiskStatsFileLogger.APP_DATA_KEY);
1838 JSONArray app_cache_sizes = json.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY);
1839 // Sanity check: Ensure all 4 lists have the same length.
1840 int length = pkg_names.length();
1841 if (app_sizes.length() != length || app_data_sizes.length() != length
1842 || app_cache_sizes.length() != length) {
1843 Slog.e(TAG, "formatting error in diskstats cache file!");
1844 return StatsManager.PULL_SKIP;
1845 }
1846 for (int i = 0; i < length; i++) {
1847 StatsEvent e = StatsEvent.newBuilder()
1848 .setAtomId(atomTag)
1849 .writeString(pkg_names.getString(i))
1850 .writeLong(app_sizes.optLong(i, /* fallback */ -1L))
1851 .writeLong(app_data_sizes.optLong(i, /* fallback */ -1L))
1852 .writeLong(app_cache_sizes.optLong(i, /* fallback */ -1L))
1853 .writeLong(cache_time)
1854 .build();
1855 pulledData.add(e);
1856 }
1857 } catch (IOException | JSONException e) {
1858 Slog.e(TAG, "exception reading diskstats cache file", e);
1859 return StatsManager.PULL_SKIP;
1860 }
1861 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001862 }
1863
1864 private void registerCategorySize() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001865 int tagId = FrameworkStatsLog.CATEGORY_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08001866 mStatsManager.setPullAtomCallback(
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001867 tagId,
1868 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001869 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001870 mStatsCallbackImpl
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001871 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001872 }
1873
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001874 int pullCategorySize(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001875 try {
1876 String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
1877 JSONObject json = new JSONObject(jsonStr);
1878 long cacheTime = json.optLong(
1879 DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, /* fallback */ -1L);
1880
1881 StatsEvent e = StatsEvent.newBuilder()
1882 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001883 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__APP_SIZE)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001884 .writeLong(json.optLong(
1885 DiskStatsFileLogger.APP_SIZE_AGG_KEY, /* fallback */ -1L))
1886 .writeLong(cacheTime)
1887 .build();
1888 pulledData.add(e);
1889
1890 e = StatsEvent.newBuilder()
1891 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001892 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__APP_DATA_SIZE)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001893 .writeLong(json.optLong(
1894 DiskStatsFileLogger.APP_DATA_SIZE_AGG_KEY, /* fallback */ -1L))
1895 .writeLong(cacheTime)
1896 .build();
1897 pulledData.add(e);
1898
1899 e = StatsEvent.newBuilder()
1900 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001901 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__APP_CACHE_SIZE)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001902 .writeLong(json.optLong(
1903 DiskStatsFileLogger.APP_CACHE_AGG_KEY, /* fallback */ -1L))
1904 .writeLong(cacheTime)
1905 .build();
1906 pulledData.add(e);
1907
1908 e = StatsEvent.newBuilder()
1909 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001910 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__PHOTOS)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001911 .writeLong(json.optLong(
1912 DiskStatsFileLogger.PHOTOS_KEY, /* fallback */ -1L))
1913 .writeLong(cacheTime)
1914 .build();
1915 pulledData.add(e);
1916
1917 e = StatsEvent.newBuilder()
1918 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001919 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__VIDEOS)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001920 .writeLong(
1921 json.optLong(DiskStatsFileLogger.VIDEOS_KEY, /* fallback */ -1L))
1922 .writeLong(cacheTime)
1923 .build();
1924 pulledData.add(e);
1925
1926 e = StatsEvent.newBuilder()
1927 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001928 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__AUDIO)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001929 .writeLong(json.optLong(
1930 DiskStatsFileLogger.AUDIO_KEY, /* fallback */ -1L))
1931 .writeLong(cacheTime)
1932 .build();
1933 pulledData.add(e);
1934
1935 e = StatsEvent.newBuilder()
1936 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001937 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__DOWNLOADS)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001938 .writeLong(
1939 json.optLong(DiskStatsFileLogger.DOWNLOADS_KEY, /* fallback */ -1L))
1940 .writeLong(cacheTime)
1941 .build();
1942 pulledData.add(e);
1943
1944 e = StatsEvent.newBuilder()
Tej Singh5dd1dc92020-01-29 20:44:42 -08001945 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001946 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__SYSTEM)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001947 .writeLong(json.optLong(
1948 DiskStatsFileLogger.SYSTEM_KEY, /* fallback */ -1L))
1949 .writeLong(cacheTime)
1950 .build();
1951 pulledData.add(e);
1952
1953 e = StatsEvent.newBuilder()
1954 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001955 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__OTHER)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08001956 .writeLong(json.optLong(
1957 DiskStatsFileLogger.MISC_KEY, /* fallback */ -1L))
1958 .writeLong(cacheTime)
1959 .build();
1960 pulledData.add(e);
1961 } catch (IOException | JSONException e) {
1962 Slog.e(TAG, "exception reading diskstats cache file", e);
1963 return StatsManager.PULL_SKIP;
1964 }
1965 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001966 }
1967
1968 private void registerNumFingerprintsEnrolled() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001969 int tagId = FrameworkStatsLog.NUM_FINGERPRINTS_ENROLLED;
Tej Singh72a70a82020-02-26 23:46:29 -08001970 mStatsManager.setPullAtomCallback(
Jeffrey Huang597a8862020-01-16 14:56:37 -08001971 tagId,
1972 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001973 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001974 mStatsCallbackImpl
Jeffrey Huang597a8862020-01-16 14:56:37 -08001975 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001976 }
1977
1978 private void registerNumFacesEnrolled() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001979 int tagId = FrameworkStatsLog.NUM_FACES_ENROLLED;
Tej Singh72a70a82020-02-26 23:46:29 -08001980 mStatsManager.setPullAtomCallback(
Jeffrey Huang597a8862020-01-16 14:56:37 -08001981 tagId,
1982 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001983 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001984 mStatsCallbackImpl
Jeffrey Huang597a8862020-01-16 14:56:37 -08001985 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001986 }
1987
Jeffrey Huang597a8862020-01-16 14:56:37 -08001988 private int pullNumBiometricsEnrolled(int modality, int atomTag, List<StatsEvent> pulledData) {
1989 final PackageManager pm = mContext.getPackageManager();
1990 FingerprintManager fingerprintManager = null;
1991 FaceManager faceManager = null;
1992
1993 if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
1994 fingerprintManager = mContext.getSystemService(FingerprintManager.class);
1995 }
1996 if (pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
1997 faceManager = mContext.getSystemService(FaceManager.class);
1998 }
1999
2000 if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT && fingerprintManager == null) {
2001 return StatsManager.PULL_SKIP;
2002 }
2003 if (modality == BiometricsProtoEnums.MODALITY_FACE && faceManager == null) {
2004 return StatsManager.PULL_SKIP;
2005 }
2006 UserManager userManager = mContext.getSystemService(UserManager.class);
2007 if (userManager == null) {
2008 return StatsManager.PULL_SKIP;
2009 }
2010
2011 final long token = Binder.clearCallingIdentity();
2012 try {
2013 for (UserInfo user : userManager.getUsers()) {
2014 final int userId = user.getUserHandle().getIdentifier();
2015 int numEnrolled = 0;
2016 if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT) {
2017 numEnrolled = fingerprintManager.getEnrolledFingerprints(userId).size();
2018 } else if (modality == BiometricsProtoEnums.MODALITY_FACE) {
2019 numEnrolled = faceManager.getEnrolledFaces(userId).size();
2020 } else {
2021 return StatsManager.PULL_SKIP;
2022 }
2023 StatsEvent e = StatsEvent.newBuilder()
2024 .setAtomId(atomTag)
2025 .writeInt(userId)
2026 .writeInt(numEnrolled)
2027 .build();
2028 pulledData.add(e);
2029 }
2030 } finally {
2031 Binder.restoreCallingIdentity(token);
2032 }
2033 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002034 }
2035
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002036 private void registerProcStats() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002037 int tagId = FrameworkStatsLog.PROC_STATS;
Tej Singh72a70a82020-02-26 23:46:29 -08002038 mStatsManager.setPullAtomCallback(
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002039 tagId,
2040 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002041 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002042 mStatsCallbackImpl
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002043 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002044 }
2045
2046 private void registerProcStatsPkgProc() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002047 int tagId = FrameworkStatsLog.PROC_STATS_PKG_PROC;
Tej Singh72a70a82020-02-26 23:46:29 -08002048 mStatsManager.setPullAtomCallback(
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002049 tagId,
2050 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002051 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002052 mStatsCallbackImpl
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002053 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002054 }
2055
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002056 private int pullProcStats(int section, int atomTag, List<StatsEvent> pulledData) {
2057 IProcessStats processStatsService = getIProcessStatsService();
2058 if (processStatsService == null) {
2059 return StatsManager.PULL_SKIP;
2060 }
2061
2062 synchronized (mProcessStatsLock) {
2063 final long token = Binder.clearCallingIdentity();
2064 try {
Richard Gaywood863a7212020-03-16 17:49:54 +00002065 // force procstats to flush & combine old files into one store
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002066 long lastHighWaterMark = readProcStatsHighWaterMark(section);
2067 List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
Richard Gaywood863a7212020-03-16 17:49:54 +00002068
2069 ProcessStats procStats = new ProcessStats(false);
2070 long highWaterMark = processStatsService.getCommittedStatsMerged(
2071 lastHighWaterMark, section, true, statsFiles, procStats);
2072
2073 // aggregate the data together for westworld consumption
2074 ProtoOutputStream proto = new ProtoOutputStream();
2075 procStats.dumpAggregatedProtoForStatsd(proto);
2076
2077 StatsEvent e = StatsEvent.newBuilder()
2078 .setAtomId(atomTag)
2079 .writeByteArray(proto.getBytes())
2080 .build();
2081 pulledData.add(e);
2082
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002083 new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + lastHighWaterMark)
2084 .delete();
2085 new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + highWaterMark)
2086 .createNewFile();
Richard Gaywood863a7212020-03-16 17:49:54 +00002087 } catch (RemoteException | IOException e) {
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002088 Slog.e(TAG, "Getting procstats failed: ", e);
2089 return StatsManager.PULL_SKIP;
2090 } finally {
2091 Binder.restoreCallingIdentity(token);
2092 }
2093 }
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002094 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002095 }
2096
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002097 // read high watermark for section
2098 private long readProcStatsHighWaterMark(int section) {
2099 try {
2100 File[] files = mBaseDir.listFiles((d, name) -> {
2101 return name.toLowerCase().startsWith(String.valueOf(section) + '_');
2102 });
2103 if (files == null || files.length == 0) {
2104 return 0;
2105 }
2106 if (files.length > 1) {
2107 Slog.e(TAG, "Only 1 file expected for high water mark. Found " + files.length);
2108 }
2109 return Long.valueOf(files[0].getName().split("_")[1]);
2110 } catch (SecurityException e) {
2111 Slog.e(TAG, "Failed to get procstats high watermark file.", e);
2112 } catch (NumberFormatException e) {
2113 Slog.e(TAG, "Failed to parse file name.", e);
2114 }
2115 return 0;
2116 }
2117
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002118 private void registerDiskIO() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002119 int tagId = FrameworkStatsLog.DISK_IO;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002120 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002121 .setAdditiveFields(new int[] {2, 3, 4, 5, 6, 7, 8, 9, 10, 11})
Tej Singh72a70a82020-02-26 23:46:29 -08002122 .setCoolDownMillis(3 * MILLIS_PER_SEC)
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002123 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002124 mStatsManager.setPullAtomCallback(
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002125 tagId,
2126 metadata,
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002127 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002128 mStatsCallbackImpl
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002129 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002130 }
2131
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002132 int pullDiskIO(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002133 mStoragedUidIoStatsReader.readAbsolute((uid, fgCharsRead, fgCharsWrite, fgBytesRead,
2134 fgBytesWrite, bgCharsRead, bgCharsWrite, bgBytesRead, bgBytesWrite,
2135 fgFsync, bgFsync) -> {
2136 StatsEvent e = StatsEvent.newBuilder()
2137 .setAtomId(atomTag)
2138 .writeInt(uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07002139 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002140 .writeLong(fgCharsRead)
2141 .writeLong(fgCharsWrite)
2142 .writeLong(fgBytesRead)
2143 .writeLong(fgBytesWrite)
2144 .writeLong(bgCharsRead)
2145 .writeLong(bgCharsWrite)
2146 .writeLong(bgBytesRead)
2147 .writeLong(bgBytesWrite)
2148 .writeLong(fgFsync)
2149 .writeLong(bgFsync)
2150 .build();
2151 pulledData.add(e);
2152 });
2153 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002154 }
2155
2156 private void registerPowerProfile() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002157 int tagId = FrameworkStatsLog.POWER_PROFILE;
Tej Singh72a70a82020-02-26 23:46:29 -08002158 mStatsManager.setPullAtomCallback(
Jeffrey Huang1a3935c2020-01-13 10:51:17 -08002159 tagId,
2160 /* PullAtomMetadata */ null,
Tej Singh6b979832020-01-02 15:23:02 -08002161 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002162 mStatsCallbackImpl
Jeffrey Huang1a3935c2020-01-13 10:51:17 -08002163 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002164 }
2165
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002166 int pullPowerProfile(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang1a3935c2020-01-13 10:51:17 -08002167 PowerProfile powerProfile = new PowerProfile(mContext);
2168 ProtoOutputStream proto = new ProtoOutputStream();
2169 powerProfile.dumpDebug(proto);
2170 proto.flush();
2171 StatsEvent e = StatsEvent.newBuilder()
2172 .setAtomId(atomTag)
2173 .writeByteArray(proto.getBytes())
2174 .build();
2175 pulledData.add(e);
2176 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002177 }
2178
2179 private void registerProcessCpuTime() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002180 int tagId = FrameworkStatsLog.PROCESS_CPU_TIME;
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002181 // Min cool-down is 5 sec, in line with what ActivityManagerService uses.
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002182 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Tej Singh72a70a82020-02-26 23:46:29 -08002183 .setCoolDownMillis(5 * MILLIS_PER_SEC)
Jeffrey Huang7a9ae132020-01-14 15:44:58 -08002184 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002185 mStatsManager.setPullAtomCallback(
Jeffrey Huang7a9ae132020-01-14 15:44:58 -08002186 tagId,
2187 metadata,
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002188 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002189 mStatsCallbackImpl
Jeffrey Huang7a9ae132020-01-14 15:44:58 -08002190 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002191 }
2192
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002193 int pullProcessCpuTime(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang7a9ae132020-01-14 15:44:58 -08002194 synchronized (mCpuTrackerLock) {
2195 if (mProcessCpuTracker == null) {
2196 mProcessCpuTracker = new ProcessCpuTracker(false);
2197 mProcessCpuTracker.init();
2198 }
2199 mProcessCpuTracker.update();
2200 for (int i = 0; i < mProcessCpuTracker.countStats(); i++) {
2201 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2202 StatsEvent e = StatsEvent.newBuilder()
2203 .setAtomId(atomTag)
2204 .writeInt(st.uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07002205 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huang7a9ae132020-01-14 15:44:58 -08002206 .writeString(st.name)
2207 .writeLong(st.base_utime)
2208 .writeLong(st.base_stime)
2209 .build();
2210 pulledData.add(e);
2211 }
2212 }
2213 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002214 }
2215
2216 private void registerCpuTimePerThreadFreq() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002217 int tagId = FrameworkStatsLog.CPU_TIME_PER_THREAD_FREQ;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002218 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangbf4eef82020-01-16 15:38:58 -08002219 .setAdditiveFields(new int[] {7, 9, 11, 13, 15, 17, 19, 21})
2220 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002221 mStatsManager.setPullAtomCallback(
Jeffrey Huangbf4eef82020-01-16 15:38:58 -08002222 tagId,
2223 metadata,
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002224 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002225 mStatsCallbackImpl
Jeffrey Huangbf4eef82020-01-16 15:38:58 -08002226 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002227 }
2228
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002229 int pullCpuTimePerThreadFreq(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangbf4eef82020-01-16 15:38:58 -08002230 if (this.mKernelCpuThreadReader == null) {
2231 Slog.e(TAG, "mKernelCpuThreadReader is null");
2232 return StatsManager.PULL_SKIP;
2233 }
2234 ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages =
2235 this.mKernelCpuThreadReader.getProcessCpuUsageDiffed();
2236 if (processCpuUsages == null) {
2237 Slog.e(TAG, "processCpuUsages is null");
2238 return StatsManager.PULL_SKIP;
2239 }
2240 int[] cpuFrequencies = mKernelCpuThreadReader.getCpuFrequenciesKhz();
2241 if (cpuFrequencies.length > CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES) {
2242 String message = "Expected maximum " + CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES
2243 + " frequencies, but got " + cpuFrequencies.length;
2244 Slog.w(TAG, message);
2245 return StatsManager.PULL_SKIP;
2246 }
2247 for (int i = 0; i < processCpuUsages.size(); i++) {
2248 KernelCpuThreadReader.ProcessCpuUsage processCpuUsage = processCpuUsages.get(i);
2249 ArrayList<KernelCpuThreadReader.ThreadCpuUsage> threadCpuUsages =
2250 processCpuUsage.threadCpuUsages;
2251 for (int j = 0; j < threadCpuUsages.size(); j++) {
2252 KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage = threadCpuUsages.get(j);
2253 if (threadCpuUsage.usageTimesMillis.length != cpuFrequencies.length) {
2254 String message = "Unexpected number of usage times,"
2255 + " expected " + cpuFrequencies.length
2256 + " but got " + threadCpuUsage.usageTimesMillis.length;
2257 Slog.w(TAG, message);
2258 return StatsManager.PULL_SKIP;
2259 }
2260
2261 StatsEvent.Builder e = StatsEvent.newBuilder();
2262 e.setAtomId(atomTag);
2263 e.writeInt(processCpuUsage.uid);
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07002264 e.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
Jeffrey Huangbf4eef82020-01-16 15:38:58 -08002265 e.writeInt(processCpuUsage.processId);
2266 e.writeInt(threadCpuUsage.threadId);
2267 e.writeString(processCpuUsage.processName);
2268 e.writeString(threadCpuUsage.threadName);
2269 for (int k = 0; k < CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES; k++) {
2270 if (k < cpuFrequencies.length) {
2271 e.writeInt(cpuFrequencies[k]);
2272 e.writeInt(threadCpuUsage.usageTimesMillis[k]);
2273 } else {
2274 // If we have no more frequencies to write, we still must write empty data.
2275 // We know that this data is empty (and not just zero) because all
2276 // frequencies are expected to be greater than zero
2277 e.writeInt(0);
2278 e.writeInt(0);
2279 }
2280 }
2281 pulledData.add(e.build());
2282 }
2283 }
2284 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002285 }
2286
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002287 private BatteryStatsHelper getBatteryStatsHelper() {
2288 if (mBatteryStatsHelper == null) {
2289 final long callingToken = Binder.clearCallingIdentity();
2290 try {
2291 // clearCallingIdentity required for BatteryStatsHelper.checkWifiOnly().
2292 mBatteryStatsHelper = new BatteryStatsHelper(mContext, false);
2293 } finally {
2294 Binder.restoreCallingIdentity(callingToken);
2295 }
2296 mBatteryStatsHelper.create((Bundle) null);
2297 }
2298 long currentTime = SystemClock.elapsedRealtime();
2299 if (currentTime - mBatteryStatsHelperTimestampMs >= MAX_BATTERY_STATS_HELPER_FREQUENCY_MS) {
2300 // Load BatteryStats and do all the calculations.
2301 mBatteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, UserHandle.USER_ALL);
2302 // Calculations are done so we don't need to save the raw BatteryStats data in RAM.
2303 mBatteryStatsHelper.clearStats();
2304 mBatteryStatsHelperTimestampMs = currentTime;
2305 }
2306 return mBatteryStatsHelper;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002307 }
2308
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002309 private long milliAmpHrsToNanoAmpSecs(double mAh) {
2310 return (long) (mAh * MILLI_AMP_HR_TO_NANO_AMP_SECS + 0.5);
2311 }
2312
2313 private void registerDeviceCalculatedPowerUse() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002314 int tagId = FrameworkStatsLog.DEVICE_CALCULATED_POWER_USE;
Tej Singh72a70a82020-02-26 23:46:29 -08002315 mStatsManager.setPullAtomCallback(
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002316 tagId,
2317 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002318 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002319 mStatsCallbackImpl
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002320 );
2321 }
2322
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002323 int pullDeviceCalculatedPowerUse(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002324 BatteryStatsHelper bsHelper = getBatteryStatsHelper();
2325 StatsEvent e = StatsEvent.newBuilder()
2326 .setAtomId(atomTag)
2327 .writeLong(milliAmpHrsToNanoAmpSecs(bsHelper.getComputedPower()))
2328 .build();
2329 pulledData.add(e);
2330 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002331 }
2332
2333 private void registerDeviceCalculatedPowerBlameUid() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002334 int tagId = FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_UID;
Tej Singh72a70a82020-02-26 23:46:29 -08002335 mStatsManager.setPullAtomCallback(
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002336 tagId,
2337 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002338 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002339 mStatsCallbackImpl
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002340 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002341 }
2342
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002343 int pullDeviceCalculatedPowerBlameUid(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002344 final List<BatterySipper> sippers = getBatteryStatsHelper().getUsageList();
2345 if (sippers == null) {
2346 return StatsManager.PULL_SKIP;
2347 }
2348
2349 for (BatterySipper bs : sippers) {
2350 if (bs.drainType != bs.drainType.APP) {
2351 continue;
2352 }
2353 StatsEvent e = StatsEvent.newBuilder()
2354 .setAtomId(atomTag)
2355 .writeInt(bs.uidObj.getUid())
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07002356 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002357 .writeLong(milliAmpHrsToNanoAmpSecs(bs.totalPowerMah))
2358 .build();
2359 pulledData.add(e);
2360 }
2361 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002362 }
2363
2364 private void registerDeviceCalculatedPowerBlameOther() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002365 int tagId = FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_OTHER;
Tej Singh72a70a82020-02-26 23:46:29 -08002366 mStatsManager.setPullAtomCallback(
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002367 tagId,
2368 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002369 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002370 mStatsCallbackImpl
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002371 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002372 }
2373
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002374 int pullDeviceCalculatedPowerBlameOther(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002375 final List<BatterySipper> sippers = getBatteryStatsHelper().getUsageList();
2376 if (sippers == null) {
2377 return StatsManager.PULL_SKIP;
2378 }
2379
2380 for (BatterySipper bs : sippers) {
2381 if (bs.drainType == bs.drainType.APP) {
2382 continue; // This is a separate atom; see pullDeviceCalculatedPowerBlameUid().
2383 }
2384 if (bs.drainType == bs.drainType.USER) {
2385 continue; // This is not supported. We purposefully calculate over USER_ALL.
2386 }
2387 StatsEvent e = StatsEvent.newBuilder()
2388 .setAtomId(atomTag)
2389 .writeInt(bs.drainType.ordinal())
2390 .writeLong(milliAmpHrsToNanoAmpSecs(bs.totalPowerMah))
2391 .build();
2392 pulledData.add(e);
2393 }
2394 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002395 }
2396
2397 private void registerDebugElapsedClock() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002398 int tagId = FrameworkStatsLog.DEBUG_ELAPSED_CLOCK;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002399 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002400 .setAdditiveFields(new int[] {1, 2, 3, 4})
2401 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002402 mStatsManager.setPullAtomCallback(
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002403 tagId,
2404 metadata,
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002405 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002406 mStatsCallbackImpl
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002407 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002408 }
2409
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002410 int pullDebugElapsedClock(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002411 final long elapsedMillis = SystemClock.elapsedRealtime();
2412
2413 synchronized (mDebugElapsedClockLock) {
2414 final long clockDiffMillis = mDebugElapsedClockPreviousValue == 0
2415 ? 0 : elapsedMillis - mDebugElapsedClockPreviousValue;
2416
2417 StatsEvent e = StatsEvent.newBuilder()
2418 .setAtomId(atomTag)
2419 .writeLong(mDebugElapsedClockPullCount)
2420 .writeLong(elapsedMillis)
2421 // Log it twice to be able to test multi-value aggregation from ValueMetric.
2422 .writeLong(elapsedMillis)
2423 .writeLong(clockDiffMillis)
2424 .writeInt(1 /* always set */)
2425 .build();
2426 pulledData.add(e);
2427
2428 if (mDebugElapsedClockPullCount % 2 == 1) {
2429 StatsEvent e2 = StatsEvent.newBuilder()
2430 .setAtomId(atomTag)
2431 .writeLong(mDebugElapsedClockPullCount)
2432 .writeLong(elapsedMillis)
2433 // Log it twice to be able to test multi-value aggregation from ValueMetric.
2434 .writeLong(elapsedMillis)
2435 .writeLong(clockDiffMillis)
2436 .writeInt(2 /* set on odd pulls */)
2437 .build();
2438 pulledData.add(e2);
2439 }
2440
2441 mDebugElapsedClockPullCount++;
2442 mDebugElapsedClockPreviousValue = elapsedMillis;
2443 }
2444
2445 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002446 }
2447
2448 private void registerDebugFailingElapsedClock() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002449 int tagId = FrameworkStatsLog.DEBUG_FAILING_ELAPSED_CLOCK;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002450 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002451 .setAdditiveFields(new int[] {1, 2, 3, 4})
2452 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002453 mStatsManager.setPullAtomCallback(
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002454 tagId,
2455 metadata,
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002456 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002457 mStatsCallbackImpl
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002458 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002459 }
2460
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002461 int pullDebugFailingElapsedClock(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002462 final long elapsedMillis = SystemClock.elapsedRealtime();
2463
2464 synchronized (mDebugFailingElapsedClockLock) {
2465 // Fails every 5 buckets.
2466 if (mDebugFailingElapsedClockPullCount++ % 5 == 0) {
2467 mDebugFailingElapsedClockPreviousValue = elapsedMillis;
2468 Slog.e(TAG, "Failing debug elapsed clock");
2469 return StatsManager.PULL_SKIP;
2470 }
2471
2472 StatsEvent e = StatsEvent.newBuilder()
2473 .setAtomId(atomTag)
2474 .writeLong(mDebugFailingElapsedClockPullCount)
2475 .writeLong(elapsedMillis)
2476 // Log it twice to be able to test multi-value aggregation from ValueMetric.
2477 .writeLong(elapsedMillis)
2478 .writeLong(mDebugFailingElapsedClockPreviousValue == 0
2479 ? 0 : elapsedMillis - mDebugFailingElapsedClockPreviousValue)
2480 .build();
2481 pulledData.add(e);
2482
2483 mDebugFailingElapsedClockPreviousValue = elapsedMillis;
2484 }
2485
2486 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002487 }
2488
2489 private void registerBuildInformation() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002490 int tagId = FrameworkStatsLog.BUILD_INFORMATION;
Tej Singh72a70a82020-02-26 23:46:29 -08002491 mStatsManager.setPullAtomCallback(
Ruchir Rastogi425d8362020-01-14 23:51:46 -08002492 tagId,
2493 null, // use default PullAtomMetadata values
Tej Singh6b979832020-01-02 15:23:02 -08002494 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002495 mStatsCallbackImpl
Ruchir Rastogi425d8362020-01-14 23:51:46 -08002496 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002497 }
2498
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002499 int pullBuildInformation(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi425d8362020-01-14 23:51:46 -08002500 StatsEvent e = StatsEvent.newBuilder()
2501 .setAtomId(atomTag)
2502 .writeString(Build.FINGERPRINT)
2503 .writeString(Build.BRAND)
2504 .writeString(Build.PRODUCT)
2505 .writeString(Build.DEVICE)
Dianne Hackborndb007452019-10-28 16:34:22 -07002506 .writeString(Build.VERSION.RELEASE_OR_CODENAME)
Ruchir Rastogi425d8362020-01-14 23:51:46 -08002507 .writeString(Build.ID)
2508 .writeString(Build.VERSION.INCREMENTAL)
2509 .writeString(Build.TYPE)
2510 .writeString(Build.TAGS)
2511 .build();
2512 pulledData.add(e);
2513 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002514 }
2515
2516 private void registerRoleHolder() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002517 int tagId = FrameworkStatsLog.ROLE_HOLDER;
Tej Singh72a70a82020-02-26 23:46:29 -08002518 mStatsManager.setPullAtomCallback(
Ruchir Rastogie4fd3212020-01-15 00:39:12 -08002519 tagId,
2520 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002521 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002522 mStatsCallbackImpl
Ruchir Rastogie4fd3212020-01-15 00:39:12 -08002523 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002524 }
2525
Ruchir Rastogie4fd3212020-01-15 00:39:12 -08002526 // Add a RoleHolder atom for each package that holds a role.
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002527 int pullRoleHolder(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogie4fd3212020-01-15 00:39:12 -08002528 long callingToken = Binder.clearCallingIdentity();
2529 try {
2530 PackageManager pm = mContext.getPackageManager();
2531 RoleManagerInternal rmi = LocalServices.getService(RoleManagerInternal.class);
2532
2533 List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
2534
2535 int numUsers = users.size();
2536 for (int userNum = 0; userNum < numUsers; userNum++) {
2537 int userId = users.get(userNum).getUserHandle().getIdentifier();
2538
2539 ArrayMap<String, ArraySet<String>> roles = rmi.getRolesAndHolders(userId);
2540
2541 int numRoles = roles.size();
2542 for (int roleNum = 0; roleNum < numRoles; roleNum++) {
2543 String roleName = roles.keyAt(roleNum);
2544 ArraySet<String> holders = roles.valueAt(roleNum);
2545
2546 int numHolders = holders.size();
2547 for (int holderNum = 0; holderNum < numHolders; holderNum++) {
2548 String holderName = holders.valueAt(holderNum);
2549
2550 PackageInfo pkg;
2551 try {
2552 pkg = pm.getPackageInfoAsUser(holderName, 0, userId);
2553 } catch (PackageManager.NameNotFoundException e) {
2554 Slog.w(TAG, "Role holder " + holderName + " not found");
2555 return StatsManager.PULL_SKIP;
2556 }
2557
2558 StatsEvent e = StatsEvent.newBuilder()
2559 .setAtomId(atomTag)
2560 .writeInt(pkg.applicationInfo.uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07002561 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Ruchir Rastogie4fd3212020-01-15 00:39:12 -08002562 .writeString(holderName)
2563 .writeString(roleName)
2564 .build();
2565 pulledData.add(e);
2566 }
2567 }
2568 }
2569 } finally {
2570 Binder.restoreCallingIdentity(callingToken);
2571 }
2572 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002573 }
2574
2575 private void registerDangerousPermissionState() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002576 int tagId = FrameworkStatsLog.DANGEROUS_PERMISSION_STATE;
Tej Singh72a70a82020-02-26 23:46:29 -08002577 mStatsManager.setPullAtomCallback(
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08002578 tagId,
2579 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002580 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002581 mStatsCallbackImpl
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08002582 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002583 }
2584
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002585 int pullDangerousPermissionState(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08002586 final long token = Binder.clearCallingIdentity();
Stanislav Zholnina093ae72020-04-18 19:14:17 +01002587 float samplingRate = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_PERMISSIONS,
2588 DANGEROUS_PERMISSION_STATE_SAMPLE_RATE, 0.02f);
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08002589 Set<Integer> reportedUids = new HashSet<>();
2590 try {
2591 PackageManager pm = mContext.getPackageManager();
2592
2593 List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
2594
2595 int numUsers = users.size();
2596 for (int userNum = 0; userNum < numUsers; userNum++) {
2597 UserHandle user = users.get(userNum).getUserHandle();
2598
2599 List<PackageInfo> pkgs = pm.getInstalledPackagesAsUser(
2600 PackageManager.GET_PERMISSIONS, user.getIdentifier());
2601
2602 int numPkgs = pkgs.size();
2603 for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) {
2604 PackageInfo pkg = pkgs.get(pkgNum);
2605
2606 if (pkg.requestedPermissions == null) {
2607 continue;
2608 }
2609
2610 if (reportedUids.contains(pkg.applicationInfo.uid)) {
2611 // do not report same uid twice
2612 continue;
2613 }
2614 reportedUids.add(pkg.applicationInfo.uid);
2615
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002616 if (atomTag == FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED
Stanislav Zholnina093ae72020-04-18 19:14:17 +01002617 && ThreadLocalRandom.current().nextFloat() > samplingRate) {
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08002618 continue;
2619 }
2620
2621 int numPerms = pkg.requestedPermissions.length;
2622 for (int permNum = 0; permNum < numPerms; permNum++) {
2623 String permName = pkg.requestedPermissions[permNum];
2624
2625 PermissionInfo permissionInfo;
2626 int permissionFlags = 0;
2627 try {
2628 permissionInfo = pm.getPermissionInfo(permName, 0);
2629 permissionFlags =
2630 pm.getPermissionFlags(permName, pkg.packageName, user);
2631 } catch (PackageManager.NameNotFoundException ignored) {
2632 continue;
2633 }
2634
2635 if (permissionInfo.getProtection() != PROTECTION_DANGEROUS) {
2636 continue;
2637 }
2638
Stanislav Zholnindbcf85e2020-02-24 18:17:55 +00002639 if (permName.startsWith(COMMON_PERMISSION_PREFIX)) {
2640 permName = permName.substring(COMMON_PERMISSION_PREFIX.length());
2641 }
2642
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08002643 StatsEvent.Builder e = StatsEvent.newBuilder();
2644 e.setAtomId(atomTag);
2645 e.writeString(permName);
2646 e.writeInt(pkg.applicationInfo.uid);
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07002647 e.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002648 if (atomTag == FrameworkStatsLog.DANGEROUS_PERMISSION_STATE) {
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08002649 e.writeString("");
2650 }
2651 e.writeBoolean((pkg.requestedPermissionsFlags[permNum]
2652 & REQUESTED_PERMISSION_GRANTED) != 0);
2653 e.writeInt(permissionFlags);
2654
2655 pulledData.add(e.build());
2656 }
2657 }
2658 }
2659 } catch (Throwable t) {
2660 Log.e(TAG, "Could not read permissions", t);
2661 return StatsManager.PULL_SKIP;
2662 } finally {
2663 Binder.restoreCallingIdentity(token);
2664 }
2665 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002666 }
2667
2668 private void registerTimeZoneDataInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002669 int tagId = FrameworkStatsLog.TIME_ZONE_DATA_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08002670 mStatsManager.setPullAtomCallback(
Ruchir Rastogibd2c4ba2020-01-15 14:48:36 -08002671 tagId,
2672 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002673 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002674 mStatsCallbackImpl
Ruchir Rastogibd2c4ba2020-01-15 14:48:36 -08002675 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002676 }
2677
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002678 int pullTimeZoneDataInfo(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogibd2c4ba2020-01-15 14:48:36 -08002679 String tzDbVersion = "Unknown";
2680 try {
2681 tzDbVersion = android.icu.util.TimeZone.getTZDataVersion();
2682 } catch (MissingResourceException e) {
2683 Slog.e(TAG, "Getting tzdb version failed: ", e);
2684 return StatsManager.PULL_SKIP;
2685 }
2686
2687 StatsEvent e = StatsEvent.newBuilder()
2688 .setAtomId(atomTag)
2689 .writeString(tzDbVersion)
2690 .build();
2691 pulledData.add(e);
2692 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002693 }
2694
2695 private void registerExternalStorageInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002696 int tagId = FrameworkStatsLog.EXTERNAL_STORAGE_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08002697 mStatsManager.setPullAtomCallback(
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08002698 tagId,
2699 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002700 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002701 mStatsCallbackImpl
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08002702 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002703 }
2704
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002705 int pullExternalStorageInfo(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08002706 if (mStorageManager == null) {
2707 return StatsManager.PULL_SKIP;
2708 }
2709
2710 List<VolumeInfo> volumes = mStorageManager.getVolumes();
2711 for (VolumeInfo vol : volumes) {
2712 final String envState = VolumeInfo.getEnvironmentForState(vol.getState());
2713 final DiskInfo diskInfo = vol.getDisk();
2714 if (diskInfo != null && envState.equals(Environment.MEDIA_MOUNTED)) {
2715 // Get the type of the volume, if it is adoptable or portable.
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002716 int volumeType = FrameworkStatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__OTHER;
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08002717 if (vol.getType() == TYPE_PUBLIC) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002718 volumeType = FrameworkStatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PUBLIC;
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08002719 } else if (vol.getType() == TYPE_PRIVATE) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002720 volumeType = FrameworkStatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PRIVATE;
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08002721 }
2722
2723 // Get the type of external storage inserted in the device (sd cards, usb, etc.)
2724 int externalStorageType;
2725 if (diskInfo.isSd()) {
2726 externalStorageType = StorageEnums.SD_CARD;
2727 } else if (diskInfo.isUsb()) {
2728 externalStorageType = StorageEnums.USB;
2729 } else {
2730 externalStorageType = StorageEnums.OTHER;
2731 }
2732
2733 StatsEvent e = StatsEvent.newBuilder()
2734 .setAtomId(atomTag)
2735 .writeInt(externalStorageType)
2736 .writeInt(volumeType)
2737 .writeLong(diskInfo.size)
2738 .build();
2739 pulledData.add(e);
2740 }
2741 }
2742 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002743 }
2744
2745 private void registerAppsOnExternalStorageInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002746 int tagId = FrameworkStatsLog.APPS_ON_EXTERNAL_STORAGE_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08002747 mStatsManager.setPullAtomCallback(
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08002748 tagId,
2749 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002750 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002751 mStatsCallbackImpl
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08002752 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002753 }
2754
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002755 int pullAppsOnExternalStorageInfo(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08002756 if (mStorageManager == null) {
2757 return StatsManager.PULL_SKIP;
2758 }
2759
2760 PackageManager pm = mContext.getPackageManager();
2761 List<ApplicationInfo> apps = pm.getInstalledApplications(/*flags=*/ 0);
2762 for (ApplicationInfo appInfo : apps) {
2763 UUID storageUuid = appInfo.storageUuid;
2764 if (storageUuid == null) {
2765 continue;
2766 }
2767
2768 VolumeInfo volumeInfo = mStorageManager.findVolumeByUuid(
2769 appInfo.storageUuid.toString());
2770 if (volumeInfo == null) {
2771 continue;
2772 }
2773
2774 DiskInfo diskInfo = volumeInfo.getDisk();
2775 if (diskInfo == null) {
2776 continue;
2777 }
2778
2779 int externalStorageType = -1;
2780 if (diskInfo.isSd()) {
2781 externalStorageType = StorageEnums.SD_CARD;
2782 } else if (diskInfo.isUsb()) {
2783 externalStorageType = StorageEnums.USB;
2784 } else if (appInfo.isExternal()) {
2785 externalStorageType = StorageEnums.OTHER;
2786 }
2787
2788 // App is installed on external storage.
2789 if (externalStorageType != -1) {
2790 StatsEvent e = StatsEvent.newBuilder()
2791 .setAtomId(atomTag)
2792 .writeInt(externalStorageType)
2793 .writeString(appInfo.packageName)
2794 .build();
2795 pulledData.add(e);
2796 }
2797 }
2798 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002799 }
2800
2801 private void registerFaceSettings() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002802 int tagId = FrameworkStatsLog.FACE_SETTINGS;
Tej Singh72a70a82020-02-26 23:46:29 -08002803 mStatsManager.setPullAtomCallback(
Ruchir Rastogi329c7672020-01-17 15:33:05 -08002804 tagId,
2805 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002806 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002807 mStatsCallbackImpl
Ruchir Rastogi329c7672020-01-17 15:33:05 -08002808 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002809 }
2810
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002811 int pullFaceSettings(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi329c7672020-01-17 15:33:05 -08002812 final long callingToken = Binder.clearCallingIdentity();
2813 try {
2814 List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
2815 int numUsers = users.size();
2816 for (int userNum = 0; userNum < numUsers; userNum++) {
2817 int userId = users.get(userNum).getUserHandle().getIdentifier();
2818
2819 int unlockKeyguardEnabled = Settings.Secure.getIntForUser(
2820 mContext.getContentResolver(),
2821 Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED, 1, userId);
2822 int unlockDismissesKeyguard = Settings.Secure.getIntForUser(
2823 mContext.getContentResolver(),
2824 Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, 0, userId);
2825 int unlockAttentionRequired = Settings.Secure.getIntForUser(
2826 mContext.getContentResolver(),
2827 Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED, 1, userId);
2828 int unlockAppEnabled = Settings.Secure.getIntForUser(
2829 mContext.getContentResolver(),
2830 Settings.Secure.FACE_UNLOCK_APP_ENABLED, 1, userId);
2831 int unlockAlwaysRequireConfirmation = Settings.Secure.getIntForUser(
2832 mContext.getContentResolver(),
2833 Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, 0, userId);
2834 int unlockDiversityRequired = Settings.Secure.getIntForUser(
2835 mContext.getContentResolver(),
2836 Settings.Secure.FACE_UNLOCK_DIVERSITY_REQUIRED, 1, userId);
2837
2838 StatsEvent e = StatsEvent.newBuilder()
2839 .setAtomId(atomTag)
2840 .writeBoolean(unlockKeyguardEnabled != 0)
2841 .writeBoolean(unlockDismissesKeyguard != 0)
2842 .writeBoolean(unlockAttentionRequired != 0)
2843 .writeBoolean(unlockAppEnabled != 0)
2844 .writeBoolean(unlockAlwaysRequireConfirmation != 0)
2845 .writeBoolean(unlockDiversityRequired != 0)
2846 .build();
2847 pulledData.add(e);
2848 }
2849 } finally {
2850 Binder.restoreCallingIdentity(callingToken);
2851 }
2852 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002853 }
2854
2855 private void registerAppOps() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002856 int tagId = FrameworkStatsLog.APP_OPS;
Tej Singh72a70a82020-02-26 23:46:29 -08002857 mStatsManager.setPullAtomCallback(
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08002858 tagId,
2859 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002860 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002861 mStatsCallbackImpl
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08002862 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002863 }
2864
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00002865 private void registerRuntimeAppOpAccessMessage() {
2866 int tagId = FrameworkStatsLog.RUNTIME_APP_OP_ACCESS;
Tej Singh72a70a82020-02-26 23:46:29 -08002867 mStatsManager.setPullAtomCallback(
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00002868 tagId,
2869 null, // use default PullAtomMetadata values
2870 BackgroundThread.getExecutor(),
2871 mStatsCallbackImpl
2872 );
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00002873 }
2874
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002875 int pullAppOps(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002876 final long token = Binder.clearCallingIdentity();
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08002877 try {
2878 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
2879
2880 CompletableFuture<HistoricalOps> ops = new CompletableFuture<>();
Stanislav Zholnin050abc32020-02-17 14:14:52 +00002881 HistoricalOpsRequest histOpsRequest = new HistoricalOpsRequest.Builder(0,
2882 Long.MAX_VALUE).setFlags(OP_FLAGS_PULLED).build();
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08002883 appOps.getHistoricalOps(histOpsRequest, mContext.getMainExecutor(), ops::complete);
2884
2885 HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
2886 TimeUnit.MILLISECONDS);
Stanislav Zholnin59199132020-03-06 14:19:25 +00002887 processHistoricalOps(histOps, atomTag, pulledData);
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08002888 } catch (Throwable t) {
2889 // TODO: catch exceptions at a more granular level
2890 Slog.e(TAG, "Could not read appops", t);
2891 return StatsManager.PULL_SKIP;
2892 } finally {
2893 Binder.restoreCallingIdentity(token);
2894 }
2895 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002896 }
2897
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002898 private void registerAttributedAppOps() {
2899 int tagId = FrameworkStatsLog.ATTRIBUTED_APP_OPS;
Tej Singh72a70a82020-02-26 23:46:29 -08002900 mStatsManager.setPullAtomCallback(
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00002901 tagId,
2902 null, // use default PullAtomMetadata values
2903 BackgroundThread.getExecutor(),
2904 mStatsCallbackImpl
2905 );
2906 }
2907
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002908 int pullAttributedAppOps(int atomTag, List<StatsEvent> pulledData) {
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00002909 final long token = Binder.clearCallingIdentity();
2910 try {
2911 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
2912
2913 CompletableFuture<HistoricalOps> ops = new CompletableFuture<>();
2914 HistoricalOpsRequest histOpsRequest =
2915 new HistoricalOpsRequest.Builder(0, Long.MAX_VALUE).setFlags(
2916 OP_FLAGS_PULLED).build();
2917 appOps.getHistoricalOps(histOpsRequest, mContext.getMainExecutor(), ops::complete);
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00002918 HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
2919 TimeUnit.MILLISECONDS);
Stanislav Zholnin59199132020-03-06 14:19:25 +00002920 if (mAppOpsSamplingRate == 0) {
Stanislav Zholnin2f63e582020-04-19 12:10:05 +01002921 int appOpsTargetCollectionSize = DeviceConfig.getInt(
2922 DeviceConfig.NAMESPACE_PERMISSIONS, APP_OPS_TARGET_COLLECTION_SIZE, 5000);
2923 mAppOpsSamplingRate = constrain(
2924 (appOpsTargetCollectionSize * 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) {
Stanislav Zholnind6cc8852020-04-24 16:41:32 +01002953 int counter = 1;
Stanislav Zholnin59199132020-03-06 14:19:25 +00002954 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);
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07003005 e.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
Stanislav Zholnin59199132020-03-06 14:19:25 +00003006 e.writeString(packageName);
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003007 if (atomTag == FrameworkStatsLog.ATTRIBUTED_APP_OPS) {
3008 e.writeString(attributionTag);
Stanislav Zholnin59199132020-03-06 14:19:25 +00003009 }
Stanislav Zholnind5378e92020-03-15 18:37:12 +00003010 e.writeInt(op.getOpCode());
Stanislav Zholnin59199132020-03-06 14:19:25 +00003011 e.writeLong(op.getForegroundAccessCount(OP_FLAGS_PULLED));
3012 e.writeLong(op.getBackgroundAccessCount(OP_FLAGS_PULLED));
3013 e.writeLong(op.getForegroundRejectCount(OP_FLAGS_PULLED));
3014 e.writeLong(op.getBackgroundRejectCount(OP_FLAGS_PULLED));
3015 e.writeLong(op.getForegroundAccessDuration(OP_FLAGS_PULLED));
3016 e.writeLong(op.getBackgroundAccessDuration(OP_FLAGS_PULLED));
3017
3018 String perm = AppOpsManager.opToPermission(op.getOpCode());
3019 if (perm == null) {
3020 e.writeBoolean(false);
3021 } else {
3022 PermissionInfo permInfo;
3023 try {
3024 permInfo = mContext.getPackageManager().getPermissionInfo(
3025 perm,
3026 0);
3027 e.writeBoolean(
3028 permInfo.getProtection() == PROTECTION_DANGEROUS);
3029 } catch (PackageManager.NameNotFoundException exception) {
3030 e.writeBoolean(false);
3031 }
3032 }
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003033 if (atomTag == FrameworkStatsLog.ATTRIBUTED_APP_OPS) {
Stanislav Zholnin59199132020-03-06 14:19:25 +00003034 e.writeInt(mAppOpsSamplingRate);
3035 }
3036 pulledData.add(e.build());
3037 return 0;
3038 }
3039
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003040 int pullRuntimeAppOpAccessMessage(int atomTag, List<StatsEvent> pulledData) {
3041 final long token = Binder.clearCallingIdentity();
3042 try {
3043 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
3044
3045 RuntimeAppOpAccessMessage message = appOps.collectRuntimeAppOpAccessMessage();
3046 if (message == null) {
3047 Slog.i(TAG, "No runtime appop access message collected");
3048 return StatsManager.PULL_SUCCESS;
3049 }
3050
3051 StatsEvent.Builder e = StatsEvent.newBuilder();
3052 e.setAtomId(atomTag);
3053 e.writeInt(message.getUid());
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07003054 e.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003055 e.writeString(message.getPackageName());
Stanislav Zholnin3a2a6e42020-03-30 10:44:51 +01003056 e.writeString("");
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003057 if (message.getAttributionTag() == null) {
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003058 e.writeString("");
3059 } else {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003060 e.writeString(message.getAttributionTag());
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003061 }
3062 e.writeString(message.getMessage());
3063 e.writeInt(message.getSamplingStrategy());
Stanislav Zholnin3a2a6e42020-03-30 10:44:51 +01003064 e.writeInt(AppOpsManager.strOpToOp(message.getOp()));
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003065
3066 pulledData.add(e.build());
3067 } catch (Throwable t) {
3068 // TODO: catch exceptions at a more granular level
3069 Slog.e(TAG, "Could not read runtime appop access message", t);
3070 return StatsManager.PULL_SKIP;
3071 } finally {
3072 Binder.restoreCallingIdentity(token);
3073 }
3074 return StatsManager.PULL_SUCCESS;
3075 }
3076
Jeffrey Huang730bf962020-01-16 15:59:52 -08003077 static void unpackStreamedData(int atomTag, List<StatsEvent> pulledData,
3078 List<ParcelFileDescriptor> statsFiles) throws IOException {
3079 InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(statsFiles.get(0));
3080 int[] len = new int[1];
3081 byte[] stats = readFully(stream, len);
3082 StatsEvent e = StatsEvent.newBuilder()
3083 .setAtomId(atomTag)
3084 .writeByteArray(Arrays.copyOf(stats, len[0]))
3085 .build();
3086 pulledData.add(e);
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003087 }
3088
Jeffrey Huang730bf962020-01-16 15:59:52 -08003089 static byte[] readFully(InputStream stream, int[] outLen) throws IOException {
3090 int pos = 0;
3091 final int initialAvail = stream.available();
3092 byte[] data = new byte[initialAvail > 0 ? (initialAvail + 1) : 16384];
3093 while (true) {
3094 int amt = stream.read(data, pos, data.length - pos);
3095 if (DEBUG) {
3096 Slog.i(TAG, "Read " + amt + " bytes at " + pos + " of avail " + data.length);
3097 }
3098 if (amt < 0) {
3099 if (DEBUG) {
3100 Slog.i(TAG, "**** FINISHED READING: pos=" + pos + " len=" + data.length);
3101 }
3102 outLen[0] = pos;
3103 return data;
3104 }
3105 pos += amt;
3106 if (pos >= data.length) {
3107 byte[] newData = new byte[pos + 16384];
3108 if (DEBUG) {
3109 Slog.i(TAG, "Copying " + pos + " bytes to new array len " + newData.length);
3110 }
3111 System.arraycopy(data, 0, newData, 0, pos);
3112 data = newData;
3113 }
3114 }
3115 }
3116
3117 private void registerNotificationRemoteViews() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003118 int tagId = FrameworkStatsLog.NOTIFICATION_REMOTE_VIEWS;
Tej Singh72a70a82020-02-26 23:46:29 -08003119 mStatsManager.setPullAtomCallback(
Jeffrey Huang730bf962020-01-16 15:59:52 -08003120 tagId,
3121 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08003122 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003123 mStatsCallbackImpl
Jeffrey Huang730bf962020-01-16 15:59:52 -08003124 );
3125 }
3126
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003127 int pullNotificationRemoteViews(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang730bf962020-01-16 15:59:52 -08003128 INotificationManager notificationManagerService = getINotificationManagerService();
3129 if (notificationManagerService == null) {
3130 return StatsManager.PULL_SKIP;
3131 }
3132 final long callingToken = Binder.clearCallingIdentity();
3133 try {
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08003134 // determine last pull tine. Copy file trick from pullProcStats?
Jeffrey Huang730bf962020-01-16 15:59:52 -08003135 long wallClockNanos = SystemClock.currentTimeMicro() * 1000L;
3136 long lastNotificationStatsNs = wallClockNanos -
3137 TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS);
3138
3139 List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
3140 notificationManagerService.pullStats(lastNotificationStatsNs,
3141 NotificationManagerService.REPORT_REMOTE_VIEWS, true, statsFiles);
3142 if (statsFiles.size() != 1) {
3143 return StatsManager.PULL_SKIP;
3144 }
3145 unpackStreamedData(atomTag, pulledData, statsFiles);
3146 } catch (IOException e) {
3147 Slog.e(TAG, "Getting notistats failed: ", e);
3148 return StatsManager.PULL_SKIP;
3149 } catch (RemoteException e) {
3150 Slog.e(TAG, "Getting notistats failed: ", e);
3151 return StatsManager.PULL_SKIP;
3152 } catch (SecurityException e) {
3153 Slog.e(TAG, "Getting notistats failed: ", e);
3154 return StatsManager.PULL_SKIP;
3155 } finally {
3156 Binder.restoreCallingIdentity(callingToken);
3157 }
3158 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003159 }
3160
3161 private void registerDangerousPermissionStateSampled() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003162 int tagId = FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED;
Tej Singh72a70a82020-02-26 23:46:29 -08003163 mStatsManager.setPullAtomCallback(
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003164 tagId,
3165 null, // use default PullAtomMetadata values
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08003166 BackgroundThread.getExecutor(),
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003167 mStatsCallbackImpl
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003168 );
Tej Singh953ad862020-01-03 12:47:07 -08003169 }
Jeffrey Huangbf130832020-01-22 15:48:26 -08003170
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003171 private void registerBatteryLevel() {
3172 int tagId = FrameworkStatsLog.BATTERY_LEVEL;
Tej Singh72a70a82020-02-26 23:46:29 -08003173 mStatsManager.setPullAtomCallback(
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003174 tagId,
3175 null, // use default PullAtomMetadata values
3176 BackgroundThread.getExecutor(),
3177 mStatsCallbackImpl
3178 );
3179 }
3180
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003181 private void registerRemainingBatteryCapacity() {
3182 int tagId = FrameworkStatsLog.REMAINING_BATTERY_CAPACITY;
Tej Singh72a70a82020-02-26 23:46:29 -08003183 mStatsManager.setPullAtomCallback(
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003184 tagId,
3185 null, // use default PullAtomMetadata values
3186 BackgroundThread.getExecutor(),
3187 mStatsCallbackImpl
3188 );
3189 }
3190
3191 private void registerFullBatteryCapacity() {
3192 int tagId = FrameworkStatsLog.FULL_BATTERY_CAPACITY;
Tej Singh72a70a82020-02-26 23:46:29 -08003193 mStatsManager.setPullAtomCallback(
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003194 tagId,
3195 null, // use default PullAtomMetadata values
3196 BackgroundThread.getExecutor(),
3197 mStatsCallbackImpl
3198 );
3199 }
3200
3201 private void registerBatteryVoltage() {
3202 int tagId = FrameworkStatsLog.BATTERY_VOLTAGE;
Tej Singh72a70a82020-02-26 23:46:29 -08003203 mStatsManager.setPullAtomCallback(
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003204 tagId,
3205 null, // use default PullAtomMetadata values
3206 BackgroundThread.getExecutor(),
3207 mStatsCallbackImpl
3208 );
3209 }
3210
3211 private void registerBatteryCycleCount() {
3212 int tagId = FrameworkStatsLog.BATTERY_CYCLE_COUNT;
Tej Singh72a70a82020-02-26 23:46:29 -08003213 mStatsManager.setPullAtomCallback(
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003214 tagId,
3215 null, // use default PullAtomMetadata values
3216 BackgroundThread.getExecutor(),
3217 mStatsCallbackImpl
3218 );
3219 }
3220
3221 int pullHealthHal(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003222 IHealth healthService = mHealthService.getLastService();
3223 if (healthService == null) {
3224 return StatsManager.PULL_SKIP;
3225 }
3226 try {
3227 healthService.getHealthInfo((result, value) -> {
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003228 int pulledValue;
3229 switch(atomTag) {
3230 case FrameworkStatsLog.BATTERY_LEVEL:
3231 pulledValue = value.legacy.batteryLevel;
3232 break;
3233 case FrameworkStatsLog.REMAINING_BATTERY_CAPACITY:
3234 pulledValue = value.legacy.batteryChargeCounter;
3235 break;
3236 case FrameworkStatsLog.FULL_BATTERY_CAPACITY:
3237 pulledValue = value.legacy.batteryFullCharge;
3238 break;
3239 case FrameworkStatsLog.BATTERY_VOLTAGE:
3240 pulledValue = value.legacy.batteryVoltage;
3241 break;
3242 case FrameworkStatsLog.BATTERY_CYCLE_COUNT:
3243 pulledValue = value.legacy.batteryCycleCount;
3244 break;
3245 default:
3246 throw new IllegalStateException("Invalid atomTag in healthHal puller: "
3247 + atomTag);
3248 }
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003249 StatsEvent e = StatsEvent.newBuilder()
3250 .setAtomId(atomTag)
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003251 .writeInt(pulledValue)
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003252 .build();
3253 pulledData.add(e);
3254 });
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003255 } catch (RemoteException | IllegalStateException e) {
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003256 return StatsManager.PULL_SKIP;
3257 }
3258 return StatsManager.PULL_SUCCESS;
3259 }
Jeffrey Huangbf130832020-01-22 15:48:26 -08003260
Raff Tsai87cefd42020-04-07 14:25:02 +08003261 private void registerSettingsStats() {
3262 int tagId = FrameworkStatsLog.SETTING_SNAPSHOT;
3263 mStatsManager.setPullAtomCallback(
3264 tagId,
3265 null, // use default PullAtomMetadata values
3266 BackgroundThread.getExecutor(),
3267 mStatsCallbackImpl
3268 );
3269 }
3270
3271 int pullSettingsStats(int atomTag, List<StatsEvent> pulledData) {
3272 UserManager userManager = mContext.getSystemService(UserManager.class);
3273 if (userManager == null) {
3274 return StatsManager.PULL_SKIP;
3275 }
3276
3277 final long token = Binder.clearCallingIdentity();
3278 try {
3279 for (UserInfo user : userManager.getUsers()) {
3280 final int userId = user.getUserHandle().getIdentifier();
3281
3282 if (userId == UserHandle.USER_SYSTEM) {
3283 pulledData.addAll(SettingsStatsUtil.logGlobalSettings(mContext, atomTag,
3284 UserHandle.USER_SYSTEM));
3285 }
3286 pulledData.addAll(SettingsStatsUtil.logSystemSettings(mContext, atomTag, userId));
3287 pulledData.addAll(SettingsStatsUtil.logSecureSettings(mContext, atomTag, userId));
3288 }
3289 } catch (Exception e) {
3290 Slog.e(TAG, "failed to pullSettingsStats", e);
3291 return StatsManager.PULL_SKIP;
3292 } finally {
3293 Binder.restoreCallingIdentity(token);
3294 }
3295 return StatsManager.PULL_SUCCESS;
3296 }
3297
Jeffrey Huangbf130832020-01-22 15:48:26 -08003298 // Thermal event received from vendor thermal management subsystem
3299 private static final class ThermalEventListener extends IThermalEventListener.Stub {
3300 @Override
3301 public void notifyThrottling(Temperature temp) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003302 FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_THROTTLING_SEVERITY_STATE_CHANGED,
3303 temp.getType(), temp.getName(), (int) (temp.getValue() * 10), temp.getStatus());
Jeffrey Huangbf130832020-01-22 15:48:26 -08003304 }
3305 }
3306
3307 private static final class ConnectivityStatsCallback extends
3308 ConnectivityManager.NetworkCallback {
3309 @Override
3310 public void onAvailable(Network network) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003311 FrameworkStatsLog.write(FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED, network.netId,
3312 FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED__STATE__CONNECTED);
Jeffrey Huangbf130832020-01-22 15:48:26 -08003313 }
3314
3315 @Override
3316 public void onLost(Network network) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003317 FrameworkStatsLog.write(FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED, network.netId,
3318 FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED__STATE__DISCONNECTED);
Jeffrey Huangbf130832020-01-22 15:48:26 -08003319 }
3320 }
Tej Singh953ad862020-01-03 12:47:07 -08003321}