blob: dbdef2368c7c1c780e476c62d4f181572ef15c5e [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 Zholnin73a8bbb2020-05-21 19:26:44 +000020import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXIED;
junyulai212a5f0e2020-02-07 17:42:39 +080021import static android.app.usage.NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN;
junyulai17941572020-05-27 14:44:13 +080022import static android.app.usage.NetworkStatsManager.FLAG_POLL_FORCE;
23import static android.app.usage.NetworkStatsManager.FLAG_POLL_ON_OPEN;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080024import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
25import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS;
junyulai39f15c82020-04-17 10:48:36 +080026import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
27import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
junyulai592c6052020-04-29 16:09:01 +080028import static android.net.NetworkTemplate.NETWORK_TYPE_ALL;
junyulaiee3ea792020-05-15 18:26:25 +080029import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
30import static android.net.NetworkTemplate.buildTemplateMobileWithRatType;
31import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
32import static android.net.NetworkTemplate.getAllCollapsedRatTypes;
Rafal Slawikbdd5a502020-01-14 14:14:29 +000033import static android.os.Debug.getIonHeapsSizeKb;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080034import static android.os.Process.getUidForPid;
35import static android.os.storage.VolumeInfo.TYPE_PRIVATE;
36import static android.os.storage.VolumeInfo.TYPE_PUBLIC;
junyulai39f15c82020-04-17 10:48:36 +080037import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION;
junyulaiaa31d3c2020-04-10 15:11:54 +080038import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID;
Stanislav Zholnin59199132020-03-06 14:19:25 +000039import static android.util.MathUtils.constrain;
Tej Singh953ad862020-01-03 12:47:07 -080040
Tej Singhe19799f2020-05-20 19:14:26 -070041import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
Muhammad Qureshi22e52da2020-03-30 21:14:21 -070042import static com.android.internal.util.FrameworkStatsLog.ANNOTATION_ID_IS_UID;
Muhammad Qureshi09fc8c42020-05-06 14:50:54 -070043import static com.android.internal.util.FrameworkStatsLog.ANNOTATION_ID_TRUNCATE_TIMESTAMP;
junyulaiaa31d3c2020-04-10 15:11:54 +080044import static com.android.internal.util.FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER__OPPORTUNISTIC_DATA_SUB__NOT_OPPORTUNISTIC;
45import static com.android.internal.util.FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER__OPPORTUNISTIC_DATA_SUB__OPPORTUNISTIC;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080046import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
Tej Singh250e7aa2020-01-16 13:16:21 -080047import static com.android.server.stats.pull.IonMemoryUtil.readProcessSystemIonHeapSizesFromDebugfs;
48import static com.android.server.stats.pull.IonMemoryUtil.readSystemIonHeapSizeFromDebugfs;
Ioannis Ilkos754eb072020-01-27 16:42:24 +000049import static com.android.server.stats.pull.ProcfsMemoryUtil.getProcessCmdlines;
Tej Singh250e7aa2020-01-16 13:16:21 -080050import static com.android.server.stats.pull.ProcfsMemoryUtil.readCmdlineFromProcfs;
51import static com.android.server.stats.pull.ProcfsMemoryUtil.readMemorySnapshotFromProcfs;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080052
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +010053import static java.lang.Math.min;
junyulai39f15c82020-04-17 10:48:36 +080054import static java.util.concurrent.TimeUnit.HOURS;
junyulai212a5f0e2020-02-07 17:42:39 +080055import static java.util.concurrent.TimeUnit.MICROSECONDS;
56
57import android.annotation.NonNull;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080058import android.annotation.Nullable;
59import android.app.ActivityManagerInternal;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080060import android.app.AppOpsManager;
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +010061import android.app.AppOpsManager.HistoricalOp;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080062import android.app.AppOpsManager.HistoricalOps;
63import android.app.AppOpsManager.HistoricalOpsRequest;
64import android.app.AppOpsManager.HistoricalPackageOps;
65import android.app.AppOpsManager.HistoricalUidOps;
66import android.app.INotificationManager;
67import android.app.ProcessMemoryState;
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +000068import android.app.RuntimeAppOpAccessMessage;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080069import android.app.StatsManager;
70import android.app.StatsManager.PullAtomMetadata;
71import android.bluetooth.BluetoothActivityEnergyInfo;
72import android.bluetooth.BluetoothAdapter;
73import android.bluetooth.UidTraffic;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080074import android.content.Context;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080075import android.content.pm.ApplicationInfo;
76import android.content.pm.PackageInfo;
77import android.content.pm.PackageManager;
78import android.content.pm.PermissionInfo;
79import android.content.pm.UserInfo;
80import android.hardware.biometrics.BiometricsProtoEnums;
81import android.hardware.face.FaceManager;
82import android.hardware.fingerprint.FingerprintManager;
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -080083import android.hardware.health.V2_0.IHealth;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080084import android.net.ConnectivityManager;
85import android.net.INetworkStatsService;
junyulai212a5f0e2020-02-07 17:42:39 +080086import android.net.INetworkStatsSession;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080087import android.net.Network;
88import android.net.NetworkRequest;
89import android.net.NetworkStats;
junyulai212a5f0e2020-02-07 17:42:39 +080090import android.net.NetworkTemplate;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080091import android.net.wifi.WifiManager;
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +010092import android.os.AsyncTask;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080093import android.os.BatteryStats;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080094import android.os.Binder;
95import android.os.Build;
96import android.os.Bundle;
97import android.os.CoolingDevice;
98import android.os.Environment;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -080099import android.os.IStoraged;
100import android.os.IThermalEventListener;
101import android.os.IThermalService;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800102import android.os.ParcelFileDescriptor;
103import android.os.Parcelable;
104import android.os.RemoteException;
105import android.os.ServiceManager;
106import android.os.StatFs;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800107import android.os.SynchronousResultReceiver;
108import android.os.SystemClock;
109import android.os.SystemProperties;
110import android.os.Temperature;
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000111import android.os.Trace;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800112import android.os.UserHandle;
113import android.os.UserManager;
114import android.os.connectivity.WifiActivityEnergyInfo;
115import android.os.storage.DiskInfo;
116import android.os.storage.StorageManager;
117import android.os.storage.VolumeInfo;
Stanislav Zholnin2f63e582020-04-19 12:10:05 +0100118import android.provider.DeviceConfig;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800119import android.provider.Settings;
120import android.stats.storage.StorageEnums;
121import android.telephony.ModemActivityInfo;
junyulaiaa31d3c2020-04-10 15:11:54 +0800122import android.telephony.SubscriptionInfo;
123import android.telephony.SubscriptionManager;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800124import android.telephony.TelephonyManager;
junyulaiaa31d3c2020-04-10 15:11:54 +0800125import android.text.TextUtils;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800126import android.util.ArrayMap;
127import android.util.ArraySet;
128import android.util.Log;
129import android.util.Slog;
Ioannis Ilkos754eb072020-01-27 16:42:24 +0000130import android.util.SparseArray;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800131import android.util.StatsEvent;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800132import android.util.proto.ProtoOutputStream;
133
134import com.android.internal.annotations.GuardedBy;
135import com.android.internal.app.procstats.IProcessStats;
136import com.android.internal.app.procstats.ProcessStats;
Tej Singh953ad862020-01-03 12:47:07 -0800137import com.android.internal.os.BackgroundThread;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800138import com.android.internal.os.BatterySipper;
139import com.android.internal.os.BatteryStatsHelper;
140import com.android.internal.os.BinderCallsStats.ExportedCallStat;
141import com.android.internal.os.KernelCpuSpeedReader;
142import com.android.internal.os.KernelCpuThreadReader;
143import com.android.internal.os.KernelCpuThreadReaderDiff;
144import com.android.internal.os.KernelCpuThreadReaderSettingsObserver;
145import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader;
146import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader;
147import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader;
148import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader;
149import com.android.internal.os.KernelWakelockReader;
150import com.android.internal.os.KernelWakelockStats;
151import com.android.internal.os.LooperStats;
152import com.android.internal.os.PowerProfile;
153import com.android.internal.os.ProcessCpuTracker;
154import com.android.internal.os.StoragedUidIoStatsReader;
junyulai39f15c82020-04-17 10:48:36 +0800155import com.android.internal.util.CollectionUtils;
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -0800156import com.android.internal.util.FrameworkStatsLog;
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -0800157import com.android.server.BatteryService;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800158import com.android.server.BinderCallsStatsService;
159import com.android.server.LocalServices;
Tej Singh953ad862020-01-03 12:47:07 -0800160import com.android.server.SystemService;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800161import com.android.server.SystemServiceManager;
162import com.android.server.am.MemoryStatUtil.MemoryStat;
163import com.android.server.notification.NotificationManagerService;
164import com.android.server.role.RoleManagerInternal;
Tej Singh250e7aa2020-01-16 13:16:21 -0800165import com.android.server.stats.pull.IonMemoryUtil.IonAllocations;
166import com.android.server.stats.pull.ProcfsMemoryUtil.MemorySnapshot;
junyulaic2d3a682020-05-22 11:44:03 +0800167import com.android.server.stats.pull.netstats.NetworkStatsExt;
junyulaiaa31d3c2020-04-10 15:11:54 +0800168import com.android.server.stats.pull.netstats.SubInfo;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800169import com.android.server.storage.DiskStatsFileLogger;
170import com.android.server.storage.DiskStatsLoggingService;
171
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800172import libcore.io.IoUtils;
173
174import org.json.JSONArray;
175import org.json.JSONException;
176import org.json.JSONObject;
177
178import java.io.File;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800179import java.io.FileOutputStream;
180import java.io.IOException;
181import java.io.InputStream;
Stanislav Zholnin59199132020-03-06 14:19:25 +0000182import java.time.Instant;
183import java.time.temporal.ChronoUnit;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800184import java.util.ArrayList;
185import java.util.Arrays;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800186import java.util.HashSet;
187import java.util.List;
188import java.util.Map;
Ruchir Rastogibd2c4ba2020-01-15 14:48:36 -0800189import java.util.MissingResourceException;
Stanislav Zholnin59199132020-03-06 14:19:25 +0000190import java.util.Random;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800191import java.util.Set;
192import java.util.UUID;
193import java.util.concurrent.CompletableFuture;
194import java.util.concurrent.Executor;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800195import java.util.concurrent.ThreadLocalRandom;
196import java.util.concurrent.TimeUnit;
197import java.util.concurrent.TimeoutException;
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -0700198import java.util.function.BiConsumer;
Tej Singh953ad862020-01-03 12:47:07 -0800199
200/**
201 * SystemService containing PullAtomCallbacks that are registered with statsd.
202 *
203 * @hide
204 */
205public class StatsPullAtomService extends SystemService {
206 private static final String TAG = "StatsPullAtomService";
207 private static final boolean DEBUG = true;
208
Stanislav Zholnin59199132020-03-06 14:19:25 +0000209 // Random seed stable for StatsPullAtomService life cycle - can be used for stable sampling
210 private static final int RANDOM_SEED = new Random().nextInt();
211
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +0100212 private static final int DIMENSION_KEY_SIZE_HARD_LIMIT = 800;
213 private static final int DIMENSION_KEY_SIZE_SOFT_LIMIT = 500;
214 private static final long APP_OPS_SAMPLING_INITIALIZATION_DELAY_MILLIS = 45000;
Stanislav Zholninba94e3b2020-06-19 16:43:47 +0100215 private static final int APP_OPS_SIZE_ESTIMATE = 2000;
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +0100216
Jeffrey Huangfa917892020-01-10 16:58:03 -0800217 private static final String RESULT_RECEIVER_CONTROLLER_KEY = "controller_activity";
218 /**
219 * How long to wait on an individual subsystem to return its stats.
220 */
221 private static final long EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS = 2000;
Tej Singh72a70a82020-02-26 23:46:29 -0800222 private static final long MILLIS_PER_SEC = 1000;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800223 private static final long MILLI_AMP_HR_TO_NANO_AMP_SECS = 1_000_000L * 3600L;
224
junyulai39f15c82020-04-17 10:48:36 +0800225 /**
226 * The default bucket duration used when query a snapshot from NetworkStatsService.
227 * The value should be sync with NetworkStatsService#DefaultNetworkStatsSettings#getUidConfig.
228 */
229 private static final long NETSTATS_UID_DEFAULT_BUCKET_DURATION_MS = HOURS.toMillis(2);
230
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800231 private static final int MAX_BATTERY_STATS_HELPER_FREQUENCY_MS = 1000;
232 private static final int CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES = 8;
Stanislav Zholnin73a8bbb2020-05-21 19:26:44 +0000233 private static final int OP_FLAGS_PULLED = OP_FLAG_SELF | OP_FLAG_TRUSTED_PROXIED;
Stanislav Zholnindbcf85e2020-02-24 18:17:55 +0000234 private static final String COMMON_PERMISSION_PREFIX = "android.permission.";
Stanislav Zholnin2f63e582020-04-19 12:10:05 +0100235 private static final String APP_OPS_TARGET_COLLECTION_SIZE = "app_ops_target_collection_size";
Stanislav Zholnina093ae72020-04-18 19:14:17 +0100236 private static final String DANGEROUS_PERMISSION_STATE_SAMPLE_RATE =
237 "dangerous_permission_state_sample_rate";
Jeffrey Huangfa917892020-01-10 16:58:03 -0800238
Richard Gaywood52a2edf2020-06-14 17:39:15 +0100239 /** Parameters relating to ProcStats data upload. */
240 // Maximum shards to use when generating StatsEvent objects from ProcStats.
241 private static final int MAX_PROCSTATS_SHARDS = 5;
242 // Should match MAX_PAYLOAD_SIZE in StatsEvent, minus a small amount for overhead/metadata.
243 private static final int MAX_PROCSTATS_SHARD_SIZE = 48 * 1024; // 48 KB
244 // In ProcessStats, we measure the size of a raw ProtoOutputStream, before compaction. This
245 // typically runs 35-45% larger than the compacted size that will be written to StatsEvent.
246 // Hence, we can allow a little more room in each shard before moving to the next. Make this
247 // 20% as a conservative estimate.
248 private static final int MAX_PROCSTATS_RAW_SHARD_SIZE = (int) (MAX_PROCSTATS_SHARD_SIZE * 1.20);
249
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800250 private final Object mThermalLock = new Object();
251 @GuardedBy("mThermalLock")
252 private IThermalService mThermalService;
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800253
Jeffrey Huang95765f02020-01-16 11:33:58 -0800254 private final Object mStoragedLock = new Object();
255 @GuardedBy("mStoragedLock")
256 private IStoraged mStorageService;
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800257
Jeffrey Huang730bf962020-01-16 15:59:52 -0800258 private final Object mNotificationStatsLock = new Object();
259 @GuardedBy("mNotificationStatsLock")
260 private INotificationManager mNotificationManagerService;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800261
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700262 @GuardedBy("mProcStatsLock")
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800263 private IProcessStats mProcessStatsService;
264
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700265 @GuardedBy("mProcessCpuTimeLock")
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800266 private ProcessCpuTracker mProcessCpuTracker;
267
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800268 @GuardedBy("mDebugElapsedClockLock")
269 private long mDebugElapsedClockPreviousValue = 0;
270 @GuardedBy("mDebugElapsedClockLock")
271 private long mDebugElapsedClockPullCount = 0;
272
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800273 @GuardedBy("mDebugFailingElapsedClockLock")
274 private long mDebugFailingElapsedClockPreviousValue = 0;
275 @GuardedBy("mDebugFailingElapsedClockLock")
276 private long mDebugFailingElapsedClockPullCount = 0;
277
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800278 private final Context mContext;
279 private StatsManager mStatsManager;
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -0800280 private StorageManager mStorageManager;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800281 private WifiManager mWifiManager;
282 private TelephonyManager mTelephony;
junyulaiaa31d3c2020-04-10 15:11:54 +0800283 private SubscriptionManager mSubscriptionManager;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800284
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700285 @GuardedBy("mKernelWakelockLock")
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800286 private KernelWakelockReader mKernelWakelockReader;
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700287 @GuardedBy("mKernelWakelockLock")
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800288 private KernelWakelockStats mTmpWakelockStats;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800289
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700290 @GuardedBy("mDiskIoLock")
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800291 private StoragedUidIoStatsReader mStoragedUidIoStatsReader;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800292
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700293 @GuardedBy("mCpuTimePerFreqLock")
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800294 private KernelCpuSpeedReader[] mKernelCpuSpeedReaders;
295 // Disables throttler on CPU time readers.
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700296 @GuardedBy("mCpuTimePerUidLock")
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800297 private KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader;
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700298 @GuardedBy("mCpuTimePerUidFreqLock")
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800299 private KernelCpuUidFreqTimeReader mCpuUidFreqTimeReader;
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700300 @GuardedBy("mCpuActiveTimeLock")
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800301 private KernelCpuUidActiveTimeReader mCpuUidActiveTimeReader;
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700302 @GuardedBy("mClusterTimeLock")
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800303 private KernelCpuUidClusterTimeReader mCpuUidClusterTimeReader;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800304
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700305 @GuardedBy("mProcStatsLock")
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800306 private File mBaseDir;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800307
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700308 @GuardedBy("mHealthHalLock")
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -0800309 private BatteryService.HealthServiceWrapper mHealthService;
310
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800311 @Nullable
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700312 @GuardedBy("mCpuTimePerThreadFreqLock")
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800313 private KernelCpuThreadReaderDiff mKernelCpuThreadReader;
314
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700315 private final Object mBatteryStatsHelperLock = new Object();
316 @GuardedBy("mBatteryStatsHelperLock")
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800317 private BatteryStatsHelper mBatteryStatsHelper = null;
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700318 @GuardedBy("mBatteryStatsHelperLock")
Jeffrey Huanga85d8f92020-01-24 13:28:45 -0800319 private long mBatteryStatsHelperTimestampMs = -MAX_BATTERY_STATS_HELPER_FREQUENCY_MS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800320
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800321 private StatsPullAtomCallbackImpl mStatsCallbackImpl;
322
Stanislav Zholninba94e3b2020-06-19 16:43:47 +0100323 @GuardedBy("mAttributedAppOpsLock")
Stanislav Zholnin59199132020-03-06 14:19:25 +0000324 private int mAppOpsSamplingRate = 0;
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700325 private final Object mDangerousAppOpsListLock = new Object();
326 @GuardedBy("mDangerousAppOpsListLock")
Stanislav Zholnine08a2bb2020-05-17 17:51:31 +0100327 private final ArraySet<Integer> mDangerousAppOpsList = new ArraySet<>();
Stanislav Zholnin59199132020-03-06 14:19:25 +0000328
junyulai39f15c82020-04-17 10:48:36 +0800329 // Baselines that stores list of NetworkStats right after initializing, with associated
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700330 // information. This is used to calculate difference when pulling BytesTransfer atoms.
junyulai39f15c82020-04-17 10:48:36 +0800331 @NonNull
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700332 @GuardedBy("mDataBytesTransferLock")
333 private final ArrayList<NetworkStatsExt> mNetworkStatsBaselines = new ArrayList<>();
junyulai39f15c82020-04-17 10:48:36 +0800334
junyulaiaa31d3c2020-04-10 15:11:54 +0800335 // Listener for monitoring subscriptions changed event.
336 private StatsSubscriptionsListener mStatsSubscriptionsListener;
junyulai66e735e2020-05-29 11:24:58 +0800337 // List that stores SubInfo of subscriptions that ever appeared since boot.
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700338 @GuardedBy("mDataBytesTransferLock")
339 private final ArrayList<SubInfo> mHistoricalSubs = new ArrayList<>();
340
341 // Puller locks
342 private final Object mDataBytesTransferLock = new Object();
343 private final Object mBluetoothBytesTransferLock = new Object();
344 private final Object mKernelWakelockLock = new Object();
345 private final Object mCpuTimePerFreqLock = new Object();
346 private final Object mCpuTimePerUidLock = new Object();
347 private final Object mCpuTimePerUidFreqLock = new Object();
348 private final Object mCpuActiveTimeLock = new Object();
349 private final Object mCpuClusterTimeLock = new Object();
350 private final Object mWifiActivityInfoLock = new Object();
351 private final Object mModemActivityInfoLock = new Object();
352 private final Object mBluetoothActivityInfoLock = new Object();
353 private final Object mSystemElapsedRealtimeLock = new Object();
354 private final Object mSystemUptimeLock = new Object();
355 private final Object mProcessMemoryStateLock = new Object();
356 private final Object mProcessMemoryHighWaterMarkLock = new Object();
357 private final Object mProcessMemorySnapshotLock = new Object();
358 private final Object mSystemIonHeapSizeLock = new Object();
359 private final Object mIonHeapSizeLock = new Object();
360 private final Object mProcessSystemIonHeapSizeLock = new Object();
361 private final Object mTemperatureLock = new Object();
362 private final Object mCooldownDeviceLock = new Object();
363 private final Object mBinderCallsStatsLock = new Object();
364 private final Object mBinderCallsStatsExceptionsLock = new Object();
365 private final Object mLooperStatsLock = new Object();
366 private final Object mDiskStatsLock = new Object();
367 private final Object mDirectoryUsageLock = new Object();
368 private final Object mAppSizeLock = new Object();
369 private final Object mCategorySizeLock = new Object();
370 private final Object mNumBiometricsEnrolledLock = new Object();
371 private final Object mProcStatsLock = new Object();
372 private final Object mDiskIoLock = new Object();
373 private final Object mPowerProfileLock = new Object();
374 private final Object mProcessCpuTimeLock = new Object();
375 private final Object mCpuTimePerThreadFreqLock = new Object();
376 private final Object mDeviceCalculatedPowerUseLock = new Object();
377 private final Object mDeviceCalculatedPowerBlameUidLock = new Object();
378 private final Object mDeviceCalculatedPowerBlameOtherLock = new Object();
379 private final Object mDebugElapsedClockLock = new Object();
380 private final Object mDebugFailingElapsedClockLock = new Object();
381 private final Object mBuildInformationLock = new Object();
382 private final Object mRoleHolderLock = new Object();
383 private final Object mTimeZoneDataInfoLock = new Object();
384 private final Object mExternalStorageInfoLock = new Object();
385 private final Object mAppsOnExternalStorageInfoLock = new Object();
386 private final Object mFaceSettingsLock = new Object();
387 private final Object mAppOpsLock = new Object();
388 private final Object mRuntimeAppOpAccessMessageLock = new Object();
389 private final Object mNotificationRemoteViewsLock = new Object();
390 private final Object mDangerousPermissionStateLock = new Object();
391 private final Object mHealthHalLock = new Object();
392 private final Object mAttributedAppOpsLock = new Object();
393 private final Object mSettingsStatsLock = new Object();
junyulaiaa31d3c2020-04-10 15:11:54 +0800394
Tej Singh953ad862020-01-03 12:47:07 -0800395 public StatsPullAtomService(Context context) {
396 super(context);
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800397 mContext = context;
Tej Singh953ad862020-01-03 12:47:07 -0800398 }
399
Jeffrey Huang4c527162020-01-30 17:53:13 -0800400 private native void nativeInit();
401
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800402 /**
403 * Use of this StatsPullAtomCallbackImpl means we avoid one class per tagId, which we would
404 * get if we used lambdas.
405 *
406 * The pull methods are intentionally left to be package private to avoid the creation
407 * of synthetic methods to save unnecessary bytecode.
408 */
409 private class StatsPullAtomCallbackImpl implements StatsManager.StatsPullAtomCallback {
410 @Override
411 public int onPullAtom(int atomTag, List<StatsEvent> data) {
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000412 if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
413 Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StatsPull-" + atomTag);
414 }
415 try {
416 switch (atomTag) {
417 case FrameworkStatsLog.WIFI_BYTES_TRANSFER:
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000418 case FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG:
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000419 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER:
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000420 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG:
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -0700421 case FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED:
junyulaiee3ea792020-05-15 18:26:25 +0800422 case FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700423 synchronized (mDataBytesTransferLock) {
424 return pullDataBytesTransferLocked(atomTag, data);
425 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000426 case FrameworkStatsLog.BLUETOOTH_BYTES_TRANSFER:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700427 synchronized (mBluetoothBytesTransferLock) {
428 return pullBluetoothBytesTransferLocked(atomTag, data);
429 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000430 case FrameworkStatsLog.KERNEL_WAKELOCK:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700431 synchronized (mKernelWakelockLock) {
432 return pullKernelWakelockLocked(atomTag, data);
433 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000434 case FrameworkStatsLog.CPU_TIME_PER_FREQ:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700435 synchronized (mCpuTimePerFreqLock) {
436 return pullCpuTimePerFreqLocked(atomTag, data);
437 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000438 case FrameworkStatsLog.CPU_TIME_PER_UID:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700439 synchronized (mCpuTimePerUidLock) {
440 return pullCpuTimePerUidLocked(atomTag, data);
441 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000442 case FrameworkStatsLog.CPU_TIME_PER_UID_FREQ:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700443 synchronized (mCpuTimePerUidFreqLock) {
444 return pullCpuTimePerUidFreqLocked(atomTag, data);
445 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000446 case FrameworkStatsLog.CPU_ACTIVE_TIME:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700447 synchronized (mCpuActiveTimeLock) {
448 return pullCpuActiveTimeLocked(atomTag, data);
449 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000450 case FrameworkStatsLog.CPU_CLUSTER_TIME:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700451 synchronized (mCpuClusterTimeLock) {
452 return pullCpuClusterTimeLocked(atomTag, data);
453 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000454 case FrameworkStatsLog.WIFI_ACTIVITY_INFO:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700455 synchronized (mWifiActivityInfoLock) {
456 return pullWifiActivityInfoLocked(atomTag, data);
457 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000458 case FrameworkStatsLog.MODEM_ACTIVITY_INFO:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700459 synchronized (mModemActivityInfoLock) {
460 return pullModemActivityInfoLocked(atomTag, data);
461 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000462 case FrameworkStatsLog.BLUETOOTH_ACTIVITY_INFO:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700463 synchronized (mBluetoothActivityInfoLock) {
464 return pullBluetoothActivityInfoLocked(atomTag, data);
465 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000466 case FrameworkStatsLog.SYSTEM_ELAPSED_REALTIME:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700467 synchronized (mSystemElapsedRealtimeLock) {
468 return pullSystemElapsedRealtimeLocked(atomTag, data);
469 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000470 case FrameworkStatsLog.SYSTEM_UPTIME:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700471 synchronized (mSystemUptimeLock) {
472 return pullSystemUptimeLocked(atomTag, data);
473 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000474 case FrameworkStatsLog.PROCESS_MEMORY_STATE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700475 synchronized (mProcessMemoryStateLock) {
476 return pullProcessMemoryStateLocked(atomTag, data);
477 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000478 case FrameworkStatsLog.PROCESS_MEMORY_HIGH_WATER_MARK:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700479 synchronized (mProcessMemoryHighWaterMarkLock) {
480 return pullProcessMemoryHighWaterMarkLocked(atomTag, data);
481 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000482 case FrameworkStatsLog.PROCESS_MEMORY_SNAPSHOT:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700483 synchronized (mProcessMemorySnapshotLock) {
484 return pullProcessMemorySnapshotLocked(atomTag, data);
485 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000486 case FrameworkStatsLog.SYSTEM_ION_HEAP_SIZE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700487 synchronized (mSystemIonHeapSizeLock) {
488 return pullSystemIonHeapSizeLocked(atomTag, data);
489 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000490 case FrameworkStatsLog.ION_HEAP_SIZE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700491 synchronized (mIonHeapSizeLock) {
492 return pullIonHeapSizeLocked(atomTag, data);
493 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000494 case FrameworkStatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700495 synchronized (mProcessSystemIonHeapSizeLock) {
496 return pullProcessSystemIonHeapSizeLocked(atomTag, data);
497 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000498 case FrameworkStatsLog.TEMPERATURE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700499 synchronized (mTemperatureLock) {
500 return pullTemperatureLocked(atomTag, data);
501 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000502 case FrameworkStatsLog.COOLING_DEVICE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700503 synchronized (mCooldownDeviceLock) {
504 return pullCooldownDeviceLocked(atomTag, data);
505 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000506 case FrameworkStatsLog.BINDER_CALLS:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700507 synchronized (mBinderCallsStatsLock) {
508 return pullBinderCallsStatsLocked(atomTag, data);
509 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000510 case FrameworkStatsLog.BINDER_CALLS_EXCEPTIONS:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700511 synchronized (mBinderCallsStatsExceptionsLock) {
512 return pullBinderCallsStatsExceptionsLocked(atomTag, data);
513 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000514 case FrameworkStatsLog.LOOPER_STATS:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700515 synchronized (mLooperStatsLock) {
516 return pullLooperStatsLocked(atomTag, data);
517 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000518 case FrameworkStatsLog.DISK_STATS:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700519 synchronized (mDiskStatsLock) {
520 return pullDiskStatsLocked(atomTag, data);
521 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000522 case FrameworkStatsLog.DIRECTORY_USAGE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700523 synchronized (mDirectoryUsageLock) {
524 return pullDirectoryUsageLocked(atomTag, data);
525 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000526 case FrameworkStatsLog.APP_SIZE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700527 synchronized (mAppSizeLock) {
528 return pullAppSizeLocked(atomTag, data);
529 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000530 case FrameworkStatsLog.CATEGORY_SIZE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700531 synchronized (mCategorySizeLock) {
532 return pullCategorySizeLocked(atomTag, data);
533 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000534 case FrameworkStatsLog.NUM_FINGERPRINTS_ENROLLED:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700535 synchronized (mNumBiometricsEnrolledLock) {
536 return pullNumBiometricsEnrolledLocked(
537 BiometricsProtoEnums.MODALITY_FINGERPRINT, atomTag, data);
538 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000539 case FrameworkStatsLog.NUM_FACES_ENROLLED:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700540 synchronized (mNumBiometricsEnrolledLock) {
541 return pullNumBiometricsEnrolledLocked(
542 BiometricsProtoEnums.MODALITY_FACE, atomTag, data);
543 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000544 case FrameworkStatsLog.PROC_STATS:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700545 synchronized (mProcStatsLock) {
546 return pullProcStatsLocked(ProcessStats.REPORT_ALL, atomTag, data);
547 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000548 case FrameworkStatsLog.PROC_STATS_PKG_PROC:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700549 synchronized (mProcStatsLock) {
550 return pullProcStatsLocked(ProcessStats.REPORT_PKG_PROC_STATS, atomTag,
551 data);
552 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000553 case FrameworkStatsLog.DISK_IO:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700554 synchronized (mDiskIoLock) {
555 return pullDiskIOLocked(atomTag, data);
556 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000557 case FrameworkStatsLog.POWER_PROFILE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700558 synchronized (mPowerProfileLock) {
559 return pullPowerProfileLocked(atomTag, data);
560 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000561 case FrameworkStatsLog.PROCESS_CPU_TIME:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700562 synchronized (mProcessCpuTimeLock) {
563 return pullProcessCpuTimeLocked(atomTag, data);
564 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000565 case FrameworkStatsLog.CPU_TIME_PER_THREAD_FREQ:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700566 synchronized (mCpuTimePerThreadFreqLock) {
567 return pullCpuTimePerThreadFreqLocked(atomTag, data);
568 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000569 case FrameworkStatsLog.DEVICE_CALCULATED_POWER_USE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700570 synchronized (mDeviceCalculatedPowerUseLock) {
571 return pullDeviceCalculatedPowerUseLocked(atomTag, data);
572 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000573 case FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_UID:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700574 synchronized (mDeviceCalculatedPowerBlameUidLock) {
575 return pullDeviceCalculatedPowerBlameUidLocked(atomTag, data);
576 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000577 case FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_OTHER:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700578 synchronized (mDeviceCalculatedPowerBlameOtherLock) {
579 return pullDeviceCalculatedPowerBlameOtherLocked(atomTag, data);
580 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000581 case FrameworkStatsLog.DEBUG_ELAPSED_CLOCK:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700582 synchronized (mDebugElapsedClockLock) {
583 return pullDebugElapsedClockLocked(atomTag, data);
584 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000585 case FrameworkStatsLog.DEBUG_FAILING_ELAPSED_CLOCK:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700586 synchronized (mDebugFailingElapsedClockLock) {
587 return pullDebugFailingElapsedClockLocked(atomTag, data);
588 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000589 case FrameworkStatsLog.BUILD_INFORMATION:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700590 synchronized (mBuildInformationLock) {
591 return pullBuildInformationLocked(atomTag, data);
592 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000593 case FrameworkStatsLog.ROLE_HOLDER:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700594 synchronized (mRoleHolderLock) {
595 return pullRoleHolderLocked(atomTag, data);
596 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000597 case FrameworkStatsLog.DANGEROUS_PERMISSION_STATE:
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000598 case FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700599 synchronized (mDangerousPermissionStateLock) {
600 return pullDangerousPermissionStateLocked(atomTag, data);
601 }
602 case FrameworkStatsLog.TIME_ZONE_DATA_INFO:
603 synchronized (mTimeZoneDataInfoLock) {
604 return pullTimeZoneDataInfoLocked(atomTag, data);
605 }
606 case FrameworkStatsLog.EXTERNAL_STORAGE_INFO:
607 synchronized (mExternalStorageInfoLock) {
608 return pullExternalStorageInfoLocked(atomTag, data);
609 }
610 case FrameworkStatsLog.APPS_ON_EXTERNAL_STORAGE_INFO:
611 synchronized (mAppsOnExternalStorageInfoLock) {
612 return pullAppsOnExternalStorageInfoLocked(atomTag, data);
613 }
614 case FrameworkStatsLog.FACE_SETTINGS:
615 synchronized (mFaceSettingsLock) {
616 return pullFaceSettingsLocked(atomTag, data);
617 }
618 case FrameworkStatsLog.APP_OPS:
619 synchronized (mAppOpsLock) {
620 return pullAppOpsLocked(atomTag, data);
621 }
622 case FrameworkStatsLog.RUNTIME_APP_OP_ACCESS:
623 synchronized (mRuntimeAppOpAccessMessageLock) {
624 return pullRuntimeAppOpAccessMessageLocked(atomTag, data);
625 }
626 case FrameworkStatsLog.NOTIFICATION_REMOTE_VIEWS:
627 synchronized (mNotificationRemoteViewsLock) {
628 return pullNotificationRemoteViewsLocked(atomTag, data);
629 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000630 case FrameworkStatsLog.BATTERY_LEVEL:
631 case FrameworkStatsLog.REMAINING_BATTERY_CAPACITY:
632 case FrameworkStatsLog.FULL_BATTERY_CAPACITY:
633 case FrameworkStatsLog.BATTERY_VOLTAGE:
634 case FrameworkStatsLog.BATTERY_CYCLE_COUNT:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700635 synchronized (mHealthHalLock) {
636 return pullHealthHalLocked(atomTag, data);
637 }
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -0800638 case FrameworkStatsLog.ATTRIBUTED_APP_OPS:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700639 synchronized (mAttributedAppOpsLock) {
640 return pullAttributedAppOpsLocked(atomTag, data);
641 }
Raff Tsai87cefd42020-04-07 14:25:02 +0800642 case FrameworkStatsLog.SETTING_SNAPSHOT:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700643 synchronized (mSettingsStatsLock) {
644 return pullSettingsStatsLocked(atomTag, data);
645 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000646 default:
647 throw new UnsupportedOperationException("Unknown tagId=" + atomTag);
648 }
649 } finally {
650 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800651 }
652 }
653 }
654
Tej Singh953ad862020-01-03 12:47:07 -0800655 @Override
656 public void onStart() {
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800657 // no op
658 }
659
660 @Override
661 public void onBootPhase(int phase) {
662 super.onBootPhase(phase);
663 if (phase == PHASE_SYSTEM_SERVICES_READY) {
664 BackgroundThread.getHandler().post(() -> {
Jeffrey Huang4c527162020-01-30 17:53:13 -0800665 nativeInit();
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800666 initializePullersState();
junyulai39f15c82020-04-17 10:48:36 +0800667 registerPullers();
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800668 registerEventListeners();
669 });
junyulai39f15c82020-04-17 10:48:36 +0800670 } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
671 // Network stats related pullers can only be initialized after service is ready.
672 BackgroundThread.getHandler().post(() -> initAndRegisterNetworkStatsPullers());
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800673 }
674 }
675
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700676 // We do not hold locks within this function because it is guaranteed to be called before the
677 // pullers are ever run, as the pullers are not yet registered with statsd.
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800678 void initializePullersState() {
679 // Get Context Managers
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800680 mStatsManager = (StatsManager) mContext.getSystemService(Context.STATS_MANAGER);
Jeffrey Huang4df57402020-01-14 11:57:22 -0800681 mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
Jeffrey Huang1f818892020-01-14 12:05:05 -0800682 mTelephony = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
junyulaiaa31d3c2020-04-10 15:11:54 +0800683 mSubscriptionManager = (SubscriptionManager)
684 mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
685 mStatsSubscriptionsListener = new StatsSubscriptionsListener(mSubscriptionManager);
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -0800686 mStorageManager = (StorageManager) mContext.getSystemService(StorageManager.class);
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -0800687
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800688 // Initialize DiskIO
689 mStoragedUidIoStatsReader = new StoragedUidIoStatsReader();
Jeffrey Huangbf130832020-01-22 15:48:26 -0800690
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800691 // Initialize PROC_STATS
Jeffrey Huangb2cdb1a52020-02-24 15:26:13 -0800692 mBaseDir = new File(SystemServiceManager.ensureSystemDir(), "stats_pull");
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700693 mBaseDir.mkdirs();
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800694
695 // Disables throttler on CPU time readers.
696 mCpuUidUserSysTimeReader = new KernelCpuUidUserSysTimeReader(false);
697 mCpuUidFreqTimeReader = new KernelCpuUidFreqTimeReader(false);
698 mCpuUidActiveTimeReader = new KernelCpuUidActiveTimeReader(false);
699 mCpuUidClusterTimeReader = new KernelCpuUidClusterTimeReader(false);
700
701 // Initialize state for KERNEL_WAKELOCK
702 mKernelWakelockReader = new KernelWakelockReader();
703 mTmpWakelockStats = new KernelWakelockStats();
Jeffrey Huangbf130832020-01-22 15:48:26 -0800704
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800705 // Initialize state for CPU_TIME_PER_FREQ atom
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -0800706 PowerProfile powerProfile = new PowerProfile(mContext);
707 final int numClusters = powerProfile.getNumCpuClusters();
708 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters];
709 int firstCpuOfCluster = 0;
710 for (int i = 0; i < numClusters; i++) {
711 final int numSpeedSteps = powerProfile.getNumSpeedStepsInCpuCluster(i);
712 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster,
713 numSpeedSteps);
714 firstCpuOfCluster += powerProfile.getNumCoresInCpuCluster(i);
715 }
Jeffrey Huangbf4eef82020-01-16 15:38:58 -0800716
717 // Used for CPU_TIME_PER_THREAD_FREQ
718 mKernelCpuThreadReader =
719 KernelCpuThreadReaderSettingsObserver.getSettingsModifiedReader(mContext);
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800720
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -0800721 // Initialize HealthService
722 mHealthService = new BatteryService.HealthServiceWrapper();
723 try {
724 mHealthService.init();
725 } catch (RemoteException e) {
726 Slog.e(TAG, "failed to initialize healthHalWrapper");
727 }
Stanislav Zholnine08a2bb2020-05-17 17:51:31 +0100728
729 // Initialize list of AppOps related to DangerousPermissions
730 PackageManager pm = mContext.getPackageManager();
731 for (int op = 0; op < AppOpsManager._NUM_OP; op++) {
732 String perm = AppOpsManager.opToPermission(op);
733 if (perm == null) {
734 continue;
735 } else {
736 PermissionInfo permInfo;
737 try {
738 permInfo = pm.getPermissionInfo(perm, 0);
739 if (permInfo.getProtection() == PROTECTION_DANGEROUS) {
740 mDangerousAppOpsList.add(op);
741 }
742 } catch (PackageManager.NameNotFoundException exception) {
743 continue;
744 }
745 }
746 }
Tej Singh953ad862020-01-03 12:47:07 -0800747 }
748
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800749 void registerEventListeners() {
750 final ConnectivityManager connectivityManager =
751 (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
752 // Default NetworkRequest should cover all transport types.
753 final NetworkRequest request = new NetworkRequest.Builder().build();
754 connectivityManager.registerNetworkCallback(request, new ConnectivityStatsCallback());
755
756 // Enable push notifications of throttling from vendor thermal
757 // management subsystem via thermalservice.
758 IThermalService thermalService = getIThermalService();
759 if (thermalService != null) {
760 try {
761 thermalService.registerThermalEventListener(new ThermalEventListener());
762 Slog.i(TAG, "register thermal listener successfully");
763 } catch (RemoteException e) {
764 Slog.i(TAG, "failed to register thermal listener");
765 }
Tej Singh953ad862020-01-03 12:47:07 -0800766 }
767 }
768
junyulai39f15c82020-04-17 10:48:36 +0800769 void registerPullers() {
Tej Singh953ad862020-01-03 12:47:07 -0800770 if (DEBUG) {
junyulai39f15c82020-04-17 10:48:36 +0800771 Slog.d(TAG, "Registering pullers with statsd");
Tej Singh953ad862020-01-03 12:47:07 -0800772 }
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800773 mStatsCallbackImpl = new StatsPullAtomCallbackImpl();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800774 registerBluetoothBytesTransfer();
775 registerKernelWakelock();
776 registerCpuTimePerFreq();
777 registerCpuTimePerUid();
778 registerCpuTimePerUidFreq();
779 registerCpuActiveTime();
780 registerCpuClusterTime();
781 registerWifiActivityInfo();
782 registerModemActivityInfo();
783 registerBluetoothActivityInfo();
784 registerSystemElapsedRealtime();
785 registerSystemUptime();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800786 registerProcessMemoryState();
787 registerProcessMemoryHighWaterMark();
788 registerProcessMemorySnapshot();
789 registerSystemIonHeapSize();
Rafal Slawikbdd5a502020-01-14 14:14:29 +0000790 registerIonHeapSize();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800791 registerProcessSystemIonHeapSize();
792 registerTemperature();
793 registerCoolingDevice();
Jeffrey Huang877adfe2020-01-15 17:16:43 -0800794 registerBinderCallsStats();
795 registerBinderCallsStatsExceptions();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800796 registerLooperStats();
797 registerDiskStats();
798 registerDirectoryUsage();
799 registerAppSize();
800 registerCategorySize();
801 registerNumFingerprintsEnrolled();
802 registerNumFacesEnrolled();
803 registerProcStats();
804 registerProcStatsPkgProc();
805 registerDiskIO();
806 registerPowerProfile();
807 registerProcessCpuTime();
808 registerCpuTimePerThreadFreq();
809 registerDeviceCalculatedPowerUse();
810 registerDeviceCalculatedPowerBlameUid();
811 registerDeviceCalculatedPowerBlameOther();
812 registerDebugElapsedClock();
813 registerDebugFailingElapsedClock();
814 registerBuildInformation();
815 registerRoleHolder();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800816 registerTimeZoneDataInfo();
817 registerExternalStorageInfo();
818 registerAppsOnExternalStorageInfo();
819 registerFaceSettings();
820 registerAppOps();
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -0800821 registerAttributedAppOps();
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +0000822 registerRuntimeAppOpAccessMessage();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800823 registerNotificationRemoteViews();
824 registerDangerousPermissionState();
825 registerDangerousPermissionStateSampled();
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -0800826 registerBatteryLevel();
Jeffrey Huang43f4d262020-01-30 14:03:31 -0800827 registerRemainingBatteryCapacity();
828 registerFullBatteryCapacity();
829 registerBatteryVoltage();
830 registerBatteryCycleCount();
Raff Tsai87cefd42020-04-07 14:25:02 +0800831 registerSettingsStats();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800832 }
833
junyulai39f15c82020-04-17 10:48:36 +0800834 private void initAndRegisterNetworkStatsPullers() {
835 if (DEBUG) {
836 Slog.d(TAG, "Registering NetworkStats pullers with statsd");
837 }
838 // Initialize NetworkStats baselines.
junyulai9f0146a2020-05-14 15:07:21 +0800839 mNetworkStatsBaselines.addAll(
840 collectNetworkStatsSnapshotForAtom(FrameworkStatsLog.WIFI_BYTES_TRANSFER));
841 mNetworkStatsBaselines.addAll(
842 collectNetworkStatsSnapshotForAtom(FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG));
843 mNetworkStatsBaselines.addAll(
844 collectNetworkStatsSnapshotForAtom(FrameworkStatsLog.MOBILE_BYTES_TRANSFER));
845 mNetworkStatsBaselines.addAll(collectNetworkStatsSnapshotForAtom(
846 FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG));
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -0700847 mNetworkStatsBaselines.addAll(collectNetworkStatsSnapshotForAtom(
848 FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED));
junyulaiee3ea792020-05-15 18:26:25 +0800849 mNetworkStatsBaselines.addAll(
850 collectNetworkStatsSnapshotForAtom(FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER));
junyulai39f15c82020-04-17 10:48:36 +0800851
junyulaiaa31d3c2020-04-10 15:11:54 +0800852 // Listen to subscription changes to record historical subscriptions that activated before
junyulai66e735e2020-05-29 11:24:58 +0800853 // pulling, this is used by {@code DATA_USAGE_BYTES_TRANSFER}.
junyulaiaa31d3c2020-04-10 15:11:54 +0800854 mSubscriptionManager.addOnSubscriptionsChangedListener(
855 BackgroundThread.getExecutor(), mStatsSubscriptionsListener);
856
junyulai39f15c82020-04-17 10:48:36 +0800857 registerWifiBytesTransfer();
858 registerWifiBytesTransferBackground();
859 registerMobileBytesTransfer();
860 registerMobileBytesTransferBackground();
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -0700861 registerBytesTransferByTagAndMetered();
junyulaiee3ea792020-05-15 18:26:25 +0800862 registerDataUsageBytesTransfer();
junyulai39f15c82020-04-17 10:48:36 +0800863 }
864
junyulai212a5f0e2020-02-07 17:42:39 +0800865 /**
866 * Return the {@code INetworkStatsSession} object that holds the necessary properties needed
867 * for the subsequent queries to {@link com.android.server.net.NetworkStatsService}. Or
junyulaiea76fb82020-05-29 14:32:21 +0800868 * null if the service or binder cannot be obtained. Calling this method will trigger poll
869 * in NetworkStatsService with once per 15 seconds rate-limit, unless {@code bypassRateLimit}
870 * is set to true. This is needed in {@link #getUidNetworkStatsSnapshotForTemplate}, where
871 * bypassing the limit is necessary for perfd to supply realtime stats to developers looking at
872 * the network usage of their app.
junyulai212a5f0e2020-02-07 17:42:39 +0800873 */
874 @Nullable
junyulaiea76fb82020-05-29 14:32:21 +0800875 private INetworkStatsSession getNetworkStatsSession(boolean bypassRateLimit) {
junyulai17941572020-05-27 14:44:13 +0800876 final INetworkStatsService networkStatsService =
877 INetworkStatsService.Stub.asInterface(
878 ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
879 if (networkStatsService == null) return null;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800880
junyulai17941572020-05-27 14:44:13 +0800881 try {
882 return networkStatsService.openSessionForUsageStats(
junyulaiea76fb82020-05-29 14:32:21 +0800883 FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN | (bypassRateLimit ? FLAG_POLL_FORCE
junyulai17941572020-05-27 14:44:13 +0800884 : FLAG_POLL_ON_OPEN), mContext.getOpPackageName());
885 } catch (RemoteException e) {
886 Slog.e(TAG, "Cannot get NetworkStats session", e);
887 return null;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800888 }
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800889 }
890
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800891 private IThermalService getIThermalService() {
892 synchronized (mThermalLock) {
893 if (mThermalService == null) {
894 mThermalService = IThermalService.Stub.asInterface(
895 ServiceManager.getService(Context.THERMAL_SERVICE));
896 if (mThermalService != null) {
897 try {
898 mThermalService.asBinder().linkToDeath(() -> {
899 synchronized (mThermalLock) {
900 mThermalService = null;
901 }
902 }, /* flags */ 0);
903 } catch (RemoteException e) {
904 Slog.e(TAG, "linkToDeath with thermalService failed", e);
905 mThermalService = null;
906 }
907 }
908 }
909 return mThermalService;
910 }
911 }
Jeffrey Huang95765f02020-01-16 11:33:58 -0800912
913 private IStoraged getIStoragedService() {
914 synchronized (mStoragedLock) {
915 if (mStorageService == null) {
916 mStorageService = IStoraged.Stub.asInterface(
917 ServiceManager.getService("storaged"));
918 }
919 if (mStorageService != null) {
920 try {
921 mStorageService.asBinder().linkToDeath(() -> {
922 synchronized (mStoragedLock) {
923 mStorageService = null;
924 }
925 }, /* flags */ 0);
926 } catch (RemoteException e) {
927 Slog.e(TAG, "linkToDeath with storagedService failed", e);
928 mStorageService = null;
929 }
930 }
931 }
932 return mStorageService;
933 }
934
Jeffrey Huang730bf962020-01-16 15:59:52 -0800935 private INotificationManager getINotificationManagerService() {
936 synchronized (mNotificationStatsLock) {
937 if (mNotificationManagerService == null) {
938 mNotificationManagerService = INotificationManager.Stub.asInterface(
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800939 ServiceManager.getService(Context.NOTIFICATION_SERVICE));
Jeffrey Huang730bf962020-01-16 15:59:52 -0800940 }
941 if (mNotificationManagerService != null) {
942 try {
943 mNotificationManagerService.asBinder().linkToDeath(() -> {
944 synchronized (mNotificationStatsLock) {
945 mNotificationManagerService = null;
946 }
947 }, /* flags */ 0);
948 } catch (RemoteException e) {
949 Slog.e(TAG, "linkToDeath with notificationManager failed", e);
950 mNotificationManagerService = null;
951 }
952 }
953 }
954 return mNotificationManagerService;
955 }
956
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800957 private IProcessStats getIProcessStatsService() {
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700958 synchronized (mProcStatsLock) {
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800959 if (mProcessStatsService == null) {
960 mProcessStatsService = IProcessStats.Stub.asInterface(
961 ServiceManager.getService(ProcessStats.SERVICE_NAME));
962 }
963 if (mProcessStatsService != null) {
964 try {
965 mProcessStatsService.asBinder().linkToDeath(() -> {
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700966 synchronized (mProcStatsLock) {
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800967 mProcessStatsService = null;
968 }
969 }, /* flags */ 0);
970 } catch (RemoteException e) {
971 Slog.e(TAG, "linkToDeath with ProcessStats failed", e);
972 mProcessStatsService = null;
973 }
974 }
975 }
976 return mProcessStatsService;
977 }
978
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800979 private void registerWifiBytesTransfer() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -0800980 int tagId = FrameworkStatsLog.WIFI_BYTES_TRANSFER;
Tej Singh6b979832020-01-02 15:23:02 -0800981 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800982 .setAdditiveFields(new int[] {2, 3, 4, 5})
983 .build();
Tej Singh72a70a82020-02-26 23:46:29 -0800984 mStatsManager.setPullAtomCallback(
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800985 tagId,
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800986 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -0700987 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800988 mStatsCallbackImpl
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800989 );
990 }
991
junyulai39f15c82020-04-17 10:48:36 +0800992 @NonNull
junyulai9f0146a2020-05-14 15:07:21 +0800993 private List<NetworkStatsExt> collectNetworkStatsSnapshotForAtom(int atomTag) {
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -0700994 List<NetworkStatsExt> ret = new ArrayList<>();
junyulai9f0146a2020-05-14 15:07:21 +0800995 switch(atomTag) {
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -0700996 case FrameworkStatsLog.WIFI_BYTES_TRANSFER: {
junyulaiee3ea792020-05-15 18:26:25 +0800997 final NetworkStats stats = getUidNetworkStatsSnapshotForTransport(TRANSPORT_WIFI);
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -0700998 if (stats != null) {
999 ret.add(new NetworkStatsExt(stats.groupedByUid(), new int[] {TRANSPORT_WIFI},
1000 /*slicedByFgbg=*/false));
1001 }
1002 break;
1003 }
1004 case FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG: {
junyulaiee3ea792020-05-15 18:26:25 +08001005 final NetworkStats stats = getUidNetworkStatsSnapshotForTransport(TRANSPORT_WIFI);
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001006 if (stats != null) {
1007 ret.add(new NetworkStatsExt(sliceNetworkStatsByUidAndFgbg(stats),
1008 new int[] {TRANSPORT_WIFI}, /*slicedByFgbg=*/true));
1009 }
1010 break;
1011 }
1012 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER: {
junyulaiee3ea792020-05-15 18:26:25 +08001013 final NetworkStats stats =
1014 getUidNetworkStatsSnapshotForTransport(TRANSPORT_CELLULAR);
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001015 if (stats != null) {
1016 ret.add(new NetworkStatsExt(stats.groupedByUid(),
1017 new int[] {TRANSPORT_CELLULAR}, /*slicedByFgbg=*/false));
1018 }
1019 break;
1020 }
1021 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG: {
junyulaiee3ea792020-05-15 18:26:25 +08001022 final NetworkStats stats =
1023 getUidNetworkStatsSnapshotForTransport(TRANSPORT_CELLULAR);
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001024 if (stats != null) {
1025 ret.add(new NetworkStatsExt(sliceNetworkStatsByUidAndFgbg(stats),
1026 new int[] {TRANSPORT_CELLULAR}, /*slicedByFgbg=*/true));
1027 }
1028 break;
1029 }
1030 case FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED: {
junyulaiee3ea792020-05-15 18:26:25 +08001031 final NetworkStats wifiStats = getUidNetworkStatsSnapshotForTemplate(
1032 buildTemplateWifiWildcard(), /*includeTags=*/true);
1033 final NetworkStats cellularStats = getUidNetworkStatsSnapshotForTemplate(
1034 buildTemplateMobileWildcard(), /*includeTags=*/true);
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001035 if (wifiStats != null && cellularStats != null) {
1036 final NetworkStats stats = wifiStats.add(cellularStats);
1037 ret.add(new NetworkStatsExt(sliceNetworkStatsByUidTagAndMetered(stats),
junyulaiee3ea792020-05-15 18:26:25 +08001038 new int[] {TRANSPORT_WIFI, TRANSPORT_CELLULAR},
1039 /*slicedByFgbg=*/false, /*slicedByTag=*/true,
junyulaiaa31d3c2020-04-10 15:11:54 +08001040 /*slicedByMetered=*/true, TelephonyManager.NETWORK_TYPE_UNKNOWN,
1041 /*subInfo=*/null));
junyulaiee3ea792020-05-15 18:26:25 +08001042 }
1043 break;
1044 }
1045 case FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER: {
junyulaiaa31d3c2020-04-10 15:11:54 +08001046 for (final SubInfo subInfo : mHistoricalSubs) {
1047 ret.addAll(getDataUsageBytesTransferSnapshotForSub(subInfo));
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001048 }
1049 break;
1050 }
junyulai9f0146a2020-05-14 15:07:21 +08001051 default:
1052 throw new IllegalArgumentException("Unknown atomTag " + atomTag);
1053 }
junyulai39f15c82020-04-17 10:48:36 +08001054 return ret;
1055 }
1056
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001057 private int pullDataBytesTransferLocked(int atomTag, @NonNull List<StatsEvent> pulledData) {
junyulai9f0146a2020-05-14 15:07:21 +08001058 final List<NetworkStatsExt> current = collectNetworkStatsSnapshotForAtom(atomTag);
junyulai592c6052020-04-29 16:09:01 +08001059
junyulai39f15c82020-04-17 10:48:36 +08001060 if (current == null) {
1061 Slog.e(TAG, "current snapshot is null for " + atomTag + ", return.");
1062 return StatsManager.PULL_SKIP;
1063 }
1064
1065 for (final NetworkStatsExt item : current) {
1066 final NetworkStatsExt baseline = CollectionUtils.find(mNetworkStatsBaselines,
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001067 it -> it.hasSameSlicing(item));
junyulai39f15c82020-04-17 10:48:36 +08001068
1069 // No matched baseline indicates error has occurred during initialization stage,
1070 // skip reporting anything since the snapshot is invalid.
1071 if (baseline == null) {
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001072 Slog.e(TAG, "baseline is null for " + atomTag + ", return.");
junyulai39f15c82020-04-17 10:48:36 +08001073 return StatsManager.PULL_SKIP;
1074 }
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001075 final NetworkStatsExt diff = new NetworkStatsExt(
1076 item.stats.subtract(baseline.stats).removeEmptyEntries(), item.transports,
junyulaiaa31d3c2020-04-10 15:11:54 +08001077 item.slicedByFgbg, item.slicedByTag, item.slicedByMetered, item.ratType,
1078 item.subInfo);
junyulai39f15c82020-04-17 10:48:36 +08001079
1080 // If no diff, skip.
1081 if (diff.stats.size() == 0) continue;
1082
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001083 switch (atomTag) {
1084 case FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED:
1085 addBytesTransferByTagAndMeteredAtoms(diff, pulledData);
1086 break;
junyulaiee3ea792020-05-15 18:26:25 +08001087 case FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER:
1088 addDataUsageBytesTransferAtoms(diff, pulledData);
1089 break;
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001090 default:
1091 addNetworkStats(atomTag, pulledData, diff);
1092 }
junyulai39f15c82020-04-17 10:48:36 +08001093 }
junyulai592c6052020-04-29 16:09:01 +08001094 return StatsManager.PULL_SUCCESS;
junyulai212a5f0e2020-02-07 17:42:39 +08001095 }
1096
1097 private void addNetworkStats(int atomTag, @NonNull List<StatsEvent> ret,
junyulai39f15c82020-04-17 10:48:36 +08001098 @NonNull NetworkStatsExt statsExt) {
1099 int size = statsExt.stats.size();
junyulai212a5f0e2020-02-07 17:42:39 +08001100 final NetworkStats.Entry entry = new NetworkStats.Entry(); // For recycling
Jeffrey Huang3ee8e202020-01-09 15:31:16 -08001101 for (int j = 0; j < size; j++) {
junyulai39f15c82020-04-17 10:48:36 +08001102 statsExt.stats.getValues(j, entry);
Jeffrey Huang3ee8e202020-01-09 15:31:16 -08001103 StatsEvent.Builder e = StatsEvent.newBuilder();
junyulai212a5f0e2020-02-07 17:42:39 +08001104 e.setAtomId(atomTag);
Muhammad Qureshi09fc8c42020-05-06 14:50:54 -07001105 switch (atomTag) {
1106 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER:
1107 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG:
1108 e.addBooleanAnnotation(ANNOTATION_ID_TRUNCATE_TIMESTAMP, true);
1109 break;
1110 default:
1111 }
Jeffrey Huang3ee8e202020-01-09 15:31:16 -08001112 e.writeInt(entry.uid);
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001113 e.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001114 if (statsExt.slicedByFgbg) {
Jeffrey Huang3ee8e202020-01-09 15:31:16 -08001115 e.writeInt(entry.set);
1116 }
1117 e.writeLong(entry.rxBytes);
1118 e.writeLong(entry.rxPackets);
1119 e.writeLong(entry.txBytes);
1120 e.writeLong(entry.txPackets);
1121 ret.add(e.build());
1122 }
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001123 }
1124
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001125 private void addBytesTransferByTagAndMeteredAtoms(@NonNull NetworkStatsExt statsExt,
1126 @NonNull List<StatsEvent> pulledData) {
1127 final NetworkStats.Entry entry = new NetworkStats.Entry(); // for recycling
1128 for (int i = 0; i < statsExt.stats.size(); i++) {
1129 statsExt.stats.getValues(i, entry);
1130 StatsEvent e = StatsEvent.newBuilder()
1131 .setAtomId(FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED)
1132 .addBooleanAnnotation(ANNOTATION_ID_TRUNCATE_TIMESTAMP, true)
1133 .writeInt(entry.uid)
1134 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
1135 .writeBoolean(entry.metered == NetworkStats.METERED_YES)
1136 .writeInt(entry.tag)
1137 .writeLong(entry.rxBytes)
1138 .writeLong(entry.rxPackets)
1139 .writeLong(entry.txBytes)
1140 .writeLong(entry.txPackets)
1141 .build();
1142 pulledData.add(e);
1143 }
1144 }
1145
junyulaiee3ea792020-05-15 18:26:25 +08001146 private void addDataUsageBytesTransferAtoms(@NonNull NetworkStatsExt statsExt,
1147 @NonNull List<StatsEvent> pulledData) {
1148 final NetworkStats.Entry entry = new NetworkStats.Entry(); // for recycling
1149 for (int i = 0; i < statsExt.stats.size(); i++) {
1150 statsExt.stats.getValues(i, entry);
1151 StatsEvent e = StatsEvent.newBuilder()
1152 .setAtomId(FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER)
1153 .addBooleanAnnotation(ANNOTATION_ID_TRUNCATE_TIMESTAMP, true)
1154 .writeInt(entry.set)
1155 .writeLong(entry.rxBytes)
1156 .writeLong(entry.rxPackets)
1157 .writeLong(entry.txBytes)
1158 .writeLong(entry.txPackets)
1159 .writeInt(statsExt.ratType)
junyulaiaa31d3c2020-04-10 15:11:54 +08001160 // Fill information about subscription, these cannot be null since invalid data
1161 // would be filtered when adding into subInfo list.
1162 .writeString(statsExt.subInfo.mcc)
1163 .writeString(statsExt.subInfo.mnc)
1164 .writeInt(statsExt.subInfo.carrierId)
1165 .writeInt(statsExt.subInfo.isOpportunistic
1166 ? DATA_USAGE_BYTES_TRANSFER__OPPORTUNISTIC_DATA_SUB__OPPORTUNISTIC
1167 : DATA_USAGE_BYTES_TRANSFER__OPPORTUNISTIC_DATA_SUB__NOT_OPPORTUNISTIC)
junyulaiee3ea792020-05-15 18:26:25 +08001168 .build();
1169 pulledData.add(e);
1170 }
1171 }
1172
junyulai39f15c82020-04-17 10:48:36 +08001173 /**
junyulaiee3ea792020-05-15 18:26:25 +08001174 * Create a snapshot of NetworkStats for a given transport.
1175 */
1176 @Nullable private NetworkStats getUidNetworkStatsSnapshotForTransport(int transport) {
1177 final NetworkTemplate template = (transport == TRANSPORT_CELLULAR)
1178 ? NetworkTemplate.buildTemplateMobileWithRatType(
1179 /*subscriptionId=*/null, NETWORK_TYPE_ALL)
1180 : NetworkTemplate.buildTemplateWifiWildcard();
1181 return getUidNetworkStatsSnapshotForTemplate(template, /*includeTags=*/false);
1182 }
1183
1184 /**
1185 * Create a snapshot of NetworkStats since boot for the given template, but add 1 bucket
1186 * duration before boot as a buffer to ensure at least one full bucket will be included.
junyulai39f15c82020-04-17 10:48:36 +08001187 * Note that this should be only used to calculate diff since the snapshot might contains
1188 * some traffic before boot.
1189 */
junyulaiee3ea792020-05-15 18:26:25 +08001190 @Nullable private NetworkStats getUidNetworkStatsSnapshotForTemplate(
1191 @NonNull NetworkTemplate template, boolean includeTags) {
junyulai212a5f0e2020-02-07 17:42:39 +08001192 final long elapsedMillisSinceBoot = SystemClock.elapsedRealtime();
1193 final long currentTimeInMillis = MICROSECONDS.toMillis(SystemClock.currentTimeMicro());
junyulai39f15c82020-04-17 10:48:36 +08001194 final long bucketDuration = Settings.Global.getLong(mContext.getContentResolver(),
1195 NETSTATS_UID_BUCKET_DURATION, NETSTATS_UID_DEFAULT_BUCKET_DURATION_MS);
junyulai212a5f0e2020-02-07 17:42:39 +08001196 try {
junyulai17941572020-05-27 14:44:13 +08001197 // TODO (b/156313635): This is short-term hack to allow perfd gets updated networkStats
1198 // history when query in every second in order to show realtime statistics. However,
1199 // this is not a good long-term solution since NetworkStatsService will make frequent
1200 // I/O and also block main thread when polling.
1201 // Consider making perfd queries NetworkStatsService directly.
1202 final NetworkStats stats = getNetworkStatsSession(template.getMatchRule()
1203 == NetworkTemplate.MATCH_WIFI_WILDCARD).getSummaryForAllUid(template,
junyulai39f15c82020-04-17 10:48:36 +08001204 currentTimeInMillis - elapsedMillisSinceBoot - bucketDuration,
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001205 currentTimeInMillis, includeTags);
1206 return stats;
junyulai212a5f0e2020-02-07 17:42:39 +08001207 } catch (RemoteException | NullPointerException e) {
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001208 Slog.e(TAG, "Pulling netstats for template=" + template + " and includeTags="
1209 + includeTags + " causes error", e);
junyulai212a5f0e2020-02-07 17:42:39 +08001210 }
1211 return null;
1212 }
1213
junyulaiaa31d3c2020-04-10 15:11:54 +08001214 @NonNull private List<NetworkStatsExt> getDataUsageBytesTransferSnapshotForSub(
1215 @NonNull SubInfo subInfo) {
1216 final List<NetworkStatsExt> ret = new ArrayList<>();
1217 for (final int ratType : getAllCollapsedRatTypes()) {
1218 final NetworkTemplate template =
1219 buildTemplateMobileWithRatType(subInfo.subscriberId, ratType);
1220 final NetworkStats stats =
1221 getUidNetworkStatsSnapshotForTemplate(template, /*includeTags=*/false);
1222 if (stats != null) {
1223 ret.add(new NetworkStatsExt(sliceNetworkStatsByFgbg(stats),
1224 new int[] {TRANSPORT_CELLULAR}, /*slicedByFgbg=*/true,
1225 /*slicedByTag=*/false, /*slicedByMetered=*/false, ratType, subInfo));
1226 }
1227 }
1228 return ret;
1229 }
1230
junyulaiee3ea792020-05-15 18:26:25 +08001231 @NonNull private NetworkStats sliceNetworkStatsByFgbg(@NonNull NetworkStats stats) {
1232 return sliceNetworkStats(stats,
1233 (newEntry, oldEntry) -> {
1234 newEntry.set = oldEntry.set;
1235 });
1236 }
1237
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001238 @NonNull private NetworkStats sliceNetworkStatsByUidAndFgbg(@NonNull NetworkStats stats) {
1239 return sliceNetworkStats(stats,
1240 (newEntry, oldEntry) -> {
1241 newEntry.uid = oldEntry.uid;
1242 newEntry.set = oldEntry.set;
1243 });
1244 }
1245
1246 @NonNull private NetworkStats sliceNetworkStatsByUidTagAndMetered(@NonNull NetworkStats stats) {
1247 return sliceNetworkStats(stats,
1248 (newEntry, oldEntry) -> {
1249 newEntry.uid = oldEntry.uid;
1250 newEntry.tag = oldEntry.tag;
1251 newEntry.metered = oldEntry.metered;
1252 });
1253 }
1254
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001255 /**
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001256 * Slices NetworkStats along the dimensions specified in the slicer lambda and aggregates over
1257 * non-sliced dimensions.
1258 *
1259 * This function iterates through each NetworkStats.Entry, sets its dimensions equal to the
1260 * default state (with the presumption that we don't want to slice on anything), and then
1261 * applies the slicer lambda to allow users to control which dimensions to slice on. This is
1262 * adapted from groupedByUid within NetworkStats.java
1263 *
1264 * @param slicer An operation taking into two parameters, new NetworkStats.Entry and old
1265 * NetworkStats.Entry, that should be used to copy state from the old to the new.
1266 * This is useful for slicing by particular dimensions. For example, if we wished
1267 * to slice by uid and tag, we could write the following lambda:
1268 * (new, old) -> {
1269 * new.uid = old.uid;
1270 * new.tag = old.tag;
1271 * }
1272 * If no slicer is provided, the data is not sliced by any dimensions.
1273 * @return new NeworkStats object appropriately sliced
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001274 */
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001275 @NonNull private NetworkStats sliceNetworkStats(@NonNull NetworkStats stats,
1276 @Nullable BiConsumer<NetworkStats.Entry, NetworkStats.Entry> slicer) {
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001277 final NetworkStats ret = new NetworkStats(stats.getElapsedRealtime(), 1);
1278
1279 final NetworkStats.Entry entry = new NetworkStats.Entry();
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001280 entry.uid = NetworkStats.UID_ALL;
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001281 entry.iface = NetworkStats.IFACE_ALL;
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001282 entry.set = NetworkStats.SET_ALL;
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001283 entry.tag = NetworkStats.TAG_NONE;
1284 entry.metered = NetworkStats.METERED_ALL;
1285 entry.roaming = NetworkStats.ROAMING_ALL;
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001286 entry.defaultNetwork = NetworkStats.DEFAULT_NETWORK_ALL;
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001287
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001288 final NetworkStats.Entry recycle = new NetworkStats.Entry(); // used for retrieving values
1289 for (int i = 0; i < stats.size(); i++) {
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001290 stats.getValues(i, recycle);
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001291 if (slicer != null) {
1292 slicer.accept(entry, recycle);
1293 }
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001294
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001295 entry.rxBytes = recycle.rxBytes;
1296 entry.rxPackets = recycle.rxPackets;
1297 entry.txBytes = recycle.txBytes;
1298 entry.txPackets = recycle.txPackets;
1299 // Operations purposefully omitted since we don't use them for statsd.
1300 ret.combineValues(entry);
1301 }
1302 return ret;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001303 }
1304
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001305 private void registerWifiBytesTransferBackground() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001306 int tagId = FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG;
Tej Singh6b979832020-01-02 15:23:02 -08001307 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001308 .setAdditiveFields(new int[] {3, 4, 5, 6})
1309 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001310 mStatsManager.setPullAtomCallback(
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001311 tagId,
1312 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001313 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001314 mStatsCallbackImpl
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001315 );
1316 }
1317
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001318 private void registerMobileBytesTransfer() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001319 int tagId = FrameworkStatsLog.MOBILE_BYTES_TRANSFER;
Tej Singh6b979832020-01-02 15:23:02 -08001320 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangc8785422020-01-10 15:54:53 -08001321 .setAdditiveFields(new int[] {2, 3, 4, 5})
1322 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001323 mStatsManager.setPullAtomCallback(
Jeffrey Huangc8785422020-01-10 15:54:53 -08001324 tagId,
1325 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001326 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001327 mStatsCallbackImpl
Jeffrey Huangc8785422020-01-10 15:54:53 -08001328 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001329 }
1330
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001331 private void registerMobileBytesTransferBackground() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001332 int tagId = FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG;
Tej Singh6b979832020-01-02 15:23:02 -08001333 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huang89864442020-01-10 16:35:51 -08001334 .setAdditiveFields(new int[] {3, 4, 5, 6})
1335 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001336 mStatsManager.setPullAtomCallback(
Jeffrey Huang89864442020-01-10 16:35:51 -08001337 tagId,
1338 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001339 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001340 mStatsCallbackImpl
Jeffrey Huang89864442020-01-10 16:35:51 -08001341 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001342 }
1343
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001344 private void registerBytesTransferByTagAndMetered() {
1345 int tagId = FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED;
1346 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
1347 .setAdditiveFields(new int[] {4, 5, 6, 7})
1348 .build();
1349 mStatsManager.setPullAtomCallback(
1350 tagId,
1351 metadata,
1352 BackgroundThread.getExecutor(),
1353 mStatsCallbackImpl
1354 );
1355 }
1356
junyulaiee3ea792020-05-15 18:26:25 +08001357 private void registerDataUsageBytesTransfer() {
1358 int tagId = FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER;
1359 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
1360 .setAdditiveFields(new int[] {2, 3, 4, 5})
1361 .build();
1362 mStatsManager.setPullAtomCallback(
1363 tagId,
1364 metadata,
1365 BackgroundThread.getExecutor(),
1366 mStatsCallbackImpl
1367 );
1368 }
1369
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001370 private void registerBluetoothBytesTransfer() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001371 int tagId = FrameworkStatsLog.BLUETOOTH_BYTES_TRANSFER;
Tej Singh6b979832020-01-02 15:23:02 -08001372 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangfa917892020-01-10 16:58:03 -08001373 .setAdditiveFields(new int[] {2, 3})
1374 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001375 mStatsManager.setPullAtomCallback(
Jeffrey Huangfa917892020-01-10 16:58:03 -08001376 tagId,
1377 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001378 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001379 mStatsCallbackImpl
Jeffrey Huangfa917892020-01-10 16:58:03 -08001380 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001381 }
1382
Jeffrey Huangfa917892020-01-10 16:58:03 -08001383 /**
1384 * Helper method to extract the Parcelable controller info from a
1385 * SynchronousResultReceiver.
1386 */
1387 private static <T extends Parcelable> T awaitControllerInfo(
1388 @Nullable SynchronousResultReceiver receiver) {
1389 if (receiver == null) {
1390 return null;
1391 }
1392
1393 try {
1394 final SynchronousResultReceiver.Result result =
1395 receiver.awaitResult(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS);
1396 if (result.bundle != null) {
1397 // This is the final destination for the Bundle.
1398 result.bundle.setDefusable(true);
1399
1400 final T data = result.bundle.getParcelable(RESULT_RECEIVER_CONTROLLER_KEY);
1401 if (data != null) {
1402 return data;
1403 }
1404 }
Jeffrey Huangfa917892020-01-10 16:58:03 -08001405 } catch (TimeoutException e) {
1406 Slog.w(TAG, "timeout reading " + receiver.getName() + " stats");
1407 }
1408 return null;
1409 }
1410
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001411 private BluetoothActivityEnergyInfo fetchBluetoothData() {
Jeffrey Huangfa917892020-01-10 16:58:03 -08001412 final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
1413 if (adapter != null) {
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001414 SynchronousResultReceiver bluetoothReceiver =
1415 new SynchronousResultReceiver("bluetooth");
Jeffrey Huangfa917892020-01-10 16:58:03 -08001416 adapter.requestControllerActivityEnergyInfo(bluetoothReceiver);
1417 return awaitControllerInfo(bluetoothReceiver);
1418 } else {
1419 Slog.e(TAG, "Failed to get bluetooth adapter!");
1420 return null;
1421 }
1422 }
1423
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001424 int pullBluetoothBytesTransferLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangfa917892020-01-10 16:58:03 -08001425 BluetoothActivityEnergyInfo info = fetchBluetoothData();
1426 if (info == null || info.getUidTraffic() == null) {
1427 return StatsManager.PULL_SKIP;
1428 }
1429 for (UidTraffic traffic : info.getUidTraffic()) {
1430 StatsEvent e = StatsEvent.newBuilder()
1431 .setAtomId(atomTag)
1432 .writeInt(traffic.getUid())
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001433 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangfa917892020-01-10 16:58:03 -08001434 .writeLong(traffic.getRxBytes())
1435 .writeLong(traffic.getTxBytes())
1436 .build();
1437 pulledData.add(e);
1438 }
1439 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001440 }
1441
1442 private void registerKernelWakelock() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001443 int tagId = FrameworkStatsLog.KERNEL_WAKELOCK;
Tej Singh72a70a82020-02-26 23:46:29 -08001444 mStatsManager.setPullAtomCallback(
Jeffrey Huanga6e5a9b2020-01-13 15:59:16 -08001445 tagId,
1446 /* PullAtomMetadata */ null,
Tej Singhe19799f2020-05-20 19:14:26 -07001447 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001448 mStatsCallbackImpl
Jeffrey Huanga6e5a9b2020-01-13 15:59:16 -08001449 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001450 }
1451
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001452 int pullKernelWakelockLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huanga6e5a9b2020-01-13 15:59:16 -08001453 final KernelWakelockStats wakelockStats =
1454 mKernelWakelockReader.readKernelWakelockStats(mTmpWakelockStats);
1455 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) {
1456 String name = ent.getKey();
1457 KernelWakelockStats.Entry kws = ent.getValue();
1458 StatsEvent e = StatsEvent.newBuilder()
1459 .setAtomId(atomTag)
1460 .writeString(name)
1461 .writeInt(kws.mCount)
1462 .writeInt(kws.mVersion)
1463 .writeLong(kws.mTotalTime)
1464 .build();
1465 pulledData.add(e);
1466 }
1467 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001468 }
1469
1470 private void registerCpuTimePerFreq() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001471 int tagId = FrameworkStatsLog.CPU_TIME_PER_FREQ;
Tej Singh6b979832020-01-02 15:23:02 -08001472 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -08001473 .setAdditiveFields(new int[] {3})
1474 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001475 mStatsManager.setPullAtomCallback(
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -08001476 tagId,
1477 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001478 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001479 mStatsCallbackImpl
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -08001480 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001481 }
1482
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001483 int pullCpuTimePerFreqLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -08001484 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) {
1485 long[] clusterTimeMs = mKernelCpuSpeedReaders[cluster].readAbsolute();
1486 if (clusterTimeMs != null) {
1487 for (int speed = clusterTimeMs.length - 1; speed >= 0; --speed) {
1488 StatsEvent e = StatsEvent.newBuilder()
1489 .setAtomId(atomTag)
1490 .writeInt(cluster)
1491 .writeInt(speed)
1492 .writeLong(clusterTimeMs[speed])
1493 .build();
1494 pulledData.add(e);
1495 }
1496 }
1497 }
1498 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001499 }
1500
1501 private void registerCpuTimePerUid() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001502 int tagId = FrameworkStatsLog.CPU_TIME_PER_UID;
Tej Singh6b979832020-01-02 15:23:02 -08001503 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangd5f053e2020-01-13 16:27:53 -08001504 .setAdditiveFields(new int[] {2, 3})
1505 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001506 mStatsManager.setPullAtomCallback(
Jeffrey Huangd5f053e2020-01-13 16:27:53 -08001507 tagId,
1508 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001509 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001510 mStatsCallbackImpl
Jeffrey Huangd5f053e2020-01-13 16:27:53 -08001511 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001512 }
1513
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001514 int pullCpuTimePerUidLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangd5f053e2020-01-13 16:27:53 -08001515 mCpuUidUserSysTimeReader.readAbsolute((uid, timesUs) -> {
1516 long userTimeUs = timesUs[0], systemTimeUs = timesUs[1];
1517 StatsEvent e = StatsEvent.newBuilder()
1518 .setAtomId(atomTag)
1519 .writeInt(uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001520 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangd5f053e2020-01-13 16:27:53 -08001521 .writeLong(userTimeUs)
1522 .writeLong(systemTimeUs)
1523 .build();
1524 pulledData.add(e);
1525 });
1526 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001527 }
1528
1529 private void registerCpuTimePerUidFreq() {
Jeffrey Huanga9899302020-01-13 16:34:03 -08001530 // the throttling is 3sec, handled in
1531 // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001532 int tagId = FrameworkStatsLog.CPU_TIME_PER_UID_FREQ;
Tej Singh6b979832020-01-02 15:23:02 -08001533 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Tej Singh137aa832020-05-28 18:21:52 -07001534 .setAdditiveFields(new int[] {3})
Jeffrey Huanga9899302020-01-13 16:34:03 -08001535 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001536 mStatsManager.setPullAtomCallback(
Jeffrey Huanga9899302020-01-13 16:34:03 -08001537 tagId,
1538 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001539 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001540 mStatsCallbackImpl
Jeffrey Huanga9899302020-01-13 16:34:03 -08001541 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001542 }
1543
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001544 int pullCpuTimePerUidFreqLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huanga9899302020-01-13 16:34:03 -08001545 mCpuUidFreqTimeReader.readAbsolute((uid, cpuFreqTimeMs) -> {
1546 for (int freqIndex = 0; freqIndex < cpuFreqTimeMs.length; ++freqIndex) {
1547 if (cpuFreqTimeMs[freqIndex] != 0) {
1548 StatsEvent e = StatsEvent.newBuilder()
1549 .setAtomId(atomTag)
1550 .writeInt(uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001551 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huanga9899302020-01-13 16:34:03 -08001552 .writeInt(freqIndex)
1553 .writeLong(cpuFreqTimeMs[freqIndex])
1554 .build();
1555 pulledData.add(e);
1556 }
1557 }
1558 });
1559 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001560 }
1561
1562 private void registerCpuActiveTime() {
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001563 // the throttling is 3sec, handled in
1564 // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001565 int tagId = FrameworkStatsLog.CPU_ACTIVE_TIME;
Tej Singh6b979832020-01-02 15:23:02 -08001566 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001567 .setAdditiveFields(new int[] {2})
1568 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001569 mStatsManager.setPullAtomCallback(
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001570 tagId,
1571 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001572 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001573 mStatsCallbackImpl
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001574 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001575 }
1576
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001577 int pullCpuActiveTimeLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001578 mCpuUidActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> {
1579 StatsEvent e = StatsEvent.newBuilder()
1580 .setAtomId(atomTag)
1581 .writeInt(uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001582 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001583 .writeLong(cpuActiveTimesMs)
1584 .build();
1585 pulledData.add(e);
1586 });
1587 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001588 }
1589
1590 private void registerCpuClusterTime() {
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001591 // the throttling is 3sec, handled in
1592 // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001593 int tagId = FrameworkStatsLog.CPU_CLUSTER_TIME;
Tej Singh6b979832020-01-02 15:23:02 -08001594 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001595 .setAdditiveFields(new int[] {3})
1596 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001597 mStatsManager.setPullAtomCallback(
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001598 tagId,
1599 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001600 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001601 mStatsCallbackImpl
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001602 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001603 }
1604
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001605 int pullCpuClusterTimeLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001606 mCpuUidClusterTimeReader.readAbsolute((uid, cpuClusterTimesMs) -> {
1607 for (int i = 0; i < cpuClusterTimesMs.length; i++) {
1608 StatsEvent e = StatsEvent.newBuilder()
1609 .setAtomId(atomTag)
1610 .writeInt(uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001611 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001612 .writeInt(i)
1613 .writeLong(cpuClusterTimesMs[i])
1614 .build();
1615 pulledData.add(e);
1616 }
1617 });
1618 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001619 }
1620
1621 private void registerWifiActivityInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001622 int tagId = FrameworkStatsLog.WIFI_ACTIVITY_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08001623 mStatsManager.setPullAtomCallback(
Jeffrey Huang4df57402020-01-14 11:57:22 -08001624 tagId,
1625 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07001626 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001627 mStatsCallbackImpl
Jeffrey Huang4df57402020-01-14 11:57:22 -08001628 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001629 }
1630
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001631 int pullWifiActivityInfoLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang4df57402020-01-14 11:57:22 -08001632 long token = Binder.clearCallingIdentity();
1633 try {
1634 SynchronousResultReceiver wifiReceiver = new SynchronousResultReceiver("wifi");
1635 mWifiManager.getWifiActivityEnergyInfoAsync(
1636 new Executor() {
1637 @Override
1638 public void execute(Runnable runnable) {
1639 // run the listener on the binder thread, if it was run on the main
1640 // thread it would deadlock since we would be waiting on ourselves
1641 runnable.run();
1642 }
1643 },
1644 info -> {
1645 Bundle bundle = new Bundle();
1646 bundle.putParcelable(BatteryStats.RESULT_RECEIVER_CONTROLLER_KEY, info);
1647 wifiReceiver.send(0, bundle);
1648 }
1649 );
1650 final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver);
1651 if (wifiInfo == null) {
1652 return StatsManager.PULL_SKIP;
1653 }
1654 StatsEvent e = StatsEvent.newBuilder()
1655 .setAtomId(atomTag)
1656 .writeLong(wifiInfo.getTimeSinceBootMillis())
1657 .writeInt(wifiInfo.getStackState())
1658 .writeLong(wifiInfo.getControllerTxDurationMillis())
1659 .writeLong(wifiInfo.getControllerRxDurationMillis())
1660 .writeLong(wifiInfo.getControllerIdleDurationMillis())
1661 .writeLong(wifiInfo.getControllerEnergyUsedMicroJoules())
1662 .build();
1663 pulledData.add(e);
1664 } catch (RuntimeException e) {
1665 Slog.e(TAG, "failed to getWifiActivityEnergyInfoAsync", e);
1666 return StatsManager.PULL_SKIP;
1667 } finally {
1668 Binder.restoreCallingIdentity(token);
1669 }
1670 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001671 }
1672
1673 private void registerModemActivityInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001674 int tagId = FrameworkStatsLog.MODEM_ACTIVITY_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08001675 mStatsManager.setPullAtomCallback(
Jeffrey Huang1f818892020-01-14 12:05:05 -08001676 tagId,
1677 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07001678 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001679 mStatsCallbackImpl
Jeffrey Huang1f818892020-01-14 12:05:05 -08001680 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001681 }
1682
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001683 int pullModemActivityInfoLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang1f818892020-01-14 12:05:05 -08001684 long token = Binder.clearCallingIdentity();
1685 try {
1686 SynchronousResultReceiver modemReceiver = new SynchronousResultReceiver("telephony");
1687 mTelephony.requestModemActivityInfo(modemReceiver);
1688 final ModemActivityInfo modemInfo = awaitControllerInfo(modemReceiver);
1689 if (modemInfo == null) {
1690 return StatsManager.PULL_SKIP;
1691 }
1692 StatsEvent e = StatsEvent.newBuilder()
1693 .setAtomId(atomTag)
1694 .writeLong(modemInfo.getTimestamp())
1695 .writeLong(modemInfo.getSleepTimeMillis())
1696 .writeLong(modemInfo.getIdleTimeMillis())
1697 .writeLong(modemInfo.getTransmitPowerInfo().get(0).getTimeInMillis())
1698 .writeLong(modemInfo.getTransmitPowerInfo().get(1).getTimeInMillis())
1699 .writeLong(modemInfo.getTransmitPowerInfo().get(2).getTimeInMillis())
1700 .writeLong(modemInfo.getTransmitPowerInfo().get(3).getTimeInMillis())
1701 .writeLong(modemInfo.getTransmitPowerInfo().get(4).getTimeInMillis())
1702 .writeLong(modemInfo.getReceiveTimeMillis())
1703 .build();
1704 pulledData.add(e);
1705 } finally {
1706 Binder.restoreCallingIdentity(token);
1707 }
1708 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001709 }
1710
1711 private void registerBluetoothActivityInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001712 int tagId = FrameworkStatsLog.BLUETOOTH_ACTIVITY_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08001713 mStatsManager.setPullAtomCallback(
Jeffrey Huangaafccb32020-01-13 10:16:58 -08001714 tagId,
1715 /* metadata */ null,
Tej Singhe19799f2020-05-20 19:14:26 -07001716 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001717 mStatsCallbackImpl
Jeffrey Huangaafccb32020-01-13 10:16:58 -08001718 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001719 }
1720
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001721 int pullBluetoothActivityInfoLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangaafccb32020-01-13 10:16:58 -08001722 BluetoothActivityEnergyInfo info = fetchBluetoothData();
1723 if (info == null) {
1724 return StatsManager.PULL_SKIP;
1725 }
1726 StatsEvent e = StatsEvent.newBuilder()
1727 .setAtomId(atomTag)
1728 .writeLong(info.getTimeStamp())
1729 .writeInt(info.getBluetoothStackState())
1730 .writeLong(info.getControllerTxTimeMillis())
1731 .writeLong(info.getControllerRxTimeMillis())
1732 .writeLong(info.getControllerIdleTimeMillis())
1733 .writeLong(info.getControllerEnergyUsed())
1734 .build();
1735 pulledData.add(e);
1736 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001737 }
1738
1739 private void registerSystemElapsedRealtime() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001740 int tagId = FrameworkStatsLog.SYSTEM_ELAPSED_REALTIME;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001741 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Tej Singh72a70a82020-02-26 23:46:29 -08001742 .setCoolDownMillis(MILLIS_PER_SEC)
1743 .setTimeoutMillis(MILLIS_PER_SEC / 2)
Jeffrey Huang882f99a2020-01-14 14:33:52 -08001744 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001745 mStatsManager.setPullAtomCallback(
Jeffrey Huang882f99a2020-01-14 14:33:52 -08001746 tagId,
1747 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001748 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001749 mStatsCallbackImpl
Jeffrey Huang882f99a2020-01-14 14:33:52 -08001750 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001751 }
1752
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001753 int pullSystemElapsedRealtimeLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang882f99a2020-01-14 14:33:52 -08001754 StatsEvent e = StatsEvent.newBuilder()
1755 .setAtomId(atomTag)
1756 .writeLong(SystemClock.elapsedRealtime())
1757 .build();
1758 pulledData.add(e);
1759 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001760 }
1761
1762 private void registerSystemUptime() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001763 int tagId = FrameworkStatsLog.SYSTEM_UPTIME;
Tej Singh72a70a82020-02-26 23:46:29 -08001764 mStatsManager.setPullAtomCallback(
Ruchir Rastogice29fc12020-01-09 17:08:20 -08001765 tagId,
1766 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07001767 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001768 mStatsCallbackImpl
Ruchir Rastogice29fc12020-01-09 17:08:20 -08001769 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001770 }
1771
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001772 int pullSystemUptimeLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogice29fc12020-01-09 17:08:20 -08001773 StatsEvent e = StatsEvent.newBuilder()
1774 .setAtomId(atomTag)
tsaichristinedc1c34a2020-03-18 14:43:06 -07001775 .writeLong(SystemClock.uptimeMillis())
Ruchir Rastogice29fc12020-01-09 17:08:20 -08001776 .build();
1777 pulledData.add(e);
1778 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001779 }
1780
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001781 private void registerProcessMemoryState() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001782 int tagId = FrameworkStatsLog.PROCESS_MEMORY_STATE;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001783 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001784 .setAdditiveFields(new int[] {4, 5, 6, 7, 8})
1785 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001786 mStatsManager.setPullAtomCallback(
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001787 tagId,
1788 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001789 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001790 mStatsCallbackImpl
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001791 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001792 }
1793
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001794 int pullProcessMemoryStateLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001795 List<ProcessMemoryState> processMemoryStates =
1796 LocalServices.getService(ActivityManagerInternal.class)
1797 .getMemoryStateForProcesses();
1798 for (ProcessMemoryState processMemoryState : processMemoryStates) {
1799 final MemoryStat memoryStat = readMemoryStatFromFilesystem(processMemoryState.uid,
1800 processMemoryState.pid);
1801 if (memoryStat == null) {
1802 continue;
1803 }
1804 StatsEvent e = StatsEvent.newBuilder()
1805 .setAtomId(atomTag)
1806 .writeInt(processMemoryState.uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001807 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001808 .writeString(processMemoryState.processName)
1809 .writeInt(processMemoryState.oomScore)
1810 .writeLong(memoryStat.pgfault)
1811 .writeLong(memoryStat.pgmajfault)
1812 .writeLong(memoryStat.rssInBytes)
1813 .writeLong(memoryStat.cacheInBytes)
1814 .writeLong(memoryStat.swapInBytes)
1815 .writeLong(-1) // unused
1816 .writeLong(-1) // unused
1817 .writeInt(-1) // unused
1818 .build();
1819 pulledData.add(e);
1820 }
1821 return StatsManager.PULL_SUCCESS;
1822 }
1823
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001824 private void registerProcessMemoryHighWaterMark() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001825 int tagId = FrameworkStatsLog.PROCESS_MEMORY_HIGH_WATER_MARK;
Tej Singh72a70a82020-02-26 23:46:29 -08001826 mStatsManager.setPullAtomCallback(
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001827 tagId,
1828 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07001829 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001830 mStatsCallbackImpl
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001831 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001832 }
1833
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001834 int pullProcessMemoryHighWaterMarkLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001835 List<ProcessMemoryState> managedProcessList =
1836 LocalServices.getService(ActivityManagerInternal.class)
1837 .getMemoryStateForProcesses();
1838 for (ProcessMemoryState managedProcess : managedProcessList) {
1839 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(managedProcess.pid);
1840 if (snapshot == null) {
1841 continue;
1842 }
1843 StatsEvent e = StatsEvent.newBuilder()
1844 .setAtomId(atomTag)
1845 .writeInt(managedProcess.uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001846 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001847 .writeString(managedProcess.processName)
1848 // RSS high-water mark in bytes.
1849 .writeLong(snapshot.rssHighWaterMarkInKilobytes * 1024L)
1850 .writeInt(snapshot.rssHighWaterMarkInKilobytes)
1851 .build();
1852 pulledData.add(e);
1853 }
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001854 // Complement the data with native system processes
1855 SparseArray<String> processCmdlines = getProcessCmdlines();
1856 managedProcessList.forEach(managedProcess -> processCmdlines.delete(managedProcess.pid));
1857 int size = processCmdlines.size();
1858 for (int i = 0; i < size; ++i) {
1859 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(processCmdlines.keyAt(i));
Ioannis Ilkose0ec1f32020-06-11 14:56:13 +01001860 if (snapshot == null) {
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001861 continue;
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001862 }
1863 StatsEvent e = StatsEvent.newBuilder()
1864 .setAtomId(atomTag)
1865 .writeInt(snapshot.uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001866 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001867 .writeString(processCmdlines.valueAt(i))
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001868 // RSS high-water mark in bytes.
1869 .writeLong(snapshot.rssHighWaterMarkInKilobytes * 1024L)
1870 .writeInt(snapshot.rssHighWaterMarkInKilobytes)
1871 .build();
1872 pulledData.add(e);
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001873 }
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001874 // Invoke rss_hwm_reset binary to reset RSS HWM counters for all processes.
1875 SystemProperties.set("sys.rss_hwm_reset.on", "1");
1876 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001877 }
1878
1879 private void registerProcessMemorySnapshot() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001880 int tagId = FrameworkStatsLog.PROCESS_MEMORY_SNAPSHOT;
Tej Singh72a70a82020-02-26 23:46:29 -08001881 mStatsManager.setPullAtomCallback(
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001882 tagId,
1883 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07001884 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001885 mStatsCallbackImpl
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001886 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001887 }
1888
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001889 int pullProcessMemorySnapshotLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001890 List<ProcessMemoryState> managedProcessList =
1891 LocalServices.getService(ActivityManagerInternal.class)
1892 .getMemoryStateForProcesses();
1893 for (ProcessMemoryState managedProcess : managedProcessList) {
1894 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(managedProcess.pid);
1895 if (snapshot == null) {
1896 continue;
1897 }
1898 StatsEvent e = StatsEvent.newBuilder()
Ioannis Ilkosda5d8812020-01-27 16:04:10 +00001899 .setAtomId(atomTag)
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001900 .writeInt(managedProcess.uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001901 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001902 .writeString(managedProcess.processName)
1903 .writeInt(managedProcess.pid)
1904 .writeInt(managedProcess.oomScore)
1905 .writeInt(snapshot.rssInKilobytes)
1906 .writeInt(snapshot.anonRssInKilobytes)
1907 .writeInt(snapshot.swapInKilobytes)
1908 .writeInt(snapshot.anonRssInKilobytes + snapshot.swapInKilobytes)
1909 .build();
1910 pulledData.add(e);
1911 }
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001912 // Complement the data with native system processes. Given these measurements can be taken
1913 // in response to LMKs happening, we want to first collect the managed app stats (to
1914 // maximize the probability that a heavyweight process will be sampled before it dies).
1915 SparseArray<String> processCmdlines = getProcessCmdlines();
1916 managedProcessList.forEach(managedProcess -> processCmdlines.delete(managedProcess.pid));
1917 int size = processCmdlines.size();
1918 for (int i = 0; i < size; ++i) {
1919 int pid = processCmdlines.keyAt(i);
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001920 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(pid);
Ioannis Ilkose0ec1f32020-06-11 14:56:13 +01001921 if (snapshot == null) {
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001922 continue;
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001923 }
1924 StatsEvent e = StatsEvent.newBuilder()
1925 .setAtomId(atomTag)
1926 .writeInt(snapshot.uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001927 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001928 .writeString(processCmdlines.valueAt(i))
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001929 .writeInt(pid)
1930 .writeInt(-1001) // Placeholder for native processes, OOM_SCORE_ADJ_MIN - 1.
1931 .writeInt(snapshot.rssInKilobytes)
1932 .writeInt(snapshot.anonRssInKilobytes)
1933 .writeInt(snapshot.swapInKilobytes)
1934 .writeInt(snapshot.anonRssInKilobytes + snapshot.swapInKilobytes)
1935 .build();
1936 pulledData.add(e);
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001937 }
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001938 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001939 }
1940
1941 private void registerSystemIonHeapSize() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001942 int tagId = FrameworkStatsLog.SYSTEM_ION_HEAP_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08001943 mStatsManager.setPullAtomCallback(
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001944 tagId,
1945 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07001946 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001947 mStatsCallbackImpl
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001948 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001949 }
1950
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001951 int pullSystemIonHeapSizeLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001952 final long systemIonHeapSizeInBytes = readSystemIonHeapSizeFromDebugfs();
1953 StatsEvent e = StatsEvent.newBuilder()
1954 .setAtomId(atomTag)
1955 .writeLong(systemIonHeapSizeInBytes)
1956 .build();
1957 pulledData.add(e);
1958 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001959 }
1960
Rafal Slawikbdd5a502020-01-14 14:14:29 +00001961 private void registerIonHeapSize() {
Rafal Slawikded83052020-02-28 13:20:13 +00001962 if (!new File("/sys/kernel/ion/total_heaps_kb").exists()) {
1963 return;
1964 }
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001965 int tagId = FrameworkStatsLog.ION_HEAP_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08001966 mStatsManager.setPullAtomCallback(
Rafal Slawikbdd5a502020-01-14 14:14:29 +00001967 tagId,
1968 /* PullAtomMetadata */ null,
Tej Singhe19799f2020-05-20 19:14:26 -07001969 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001970 mStatsCallbackImpl
Rafal Slawikbdd5a502020-01-14 14:14:29 +00001971 );
1972 }
1973
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001974 int pullIonHeapSizeLocked(int atomTag, List<StatsEvent> pulledData) {
Rafal Slawikbdd5a502020-01-14 14:14:29 +00001975 int ionHeapSizeInKilobytes = (int) getIonHeapsSizeKb();
1976 StatsEvent e = StatsEvent.newBuilder()
1977 .setAtomId(atomTag)
1978 .writeInt(ionHeapSizeInKilobytes)
1979 .build();
1980 pulledData.add(e);
1981 return StatsManager.PULL_SUCCESS;
1982 }
1983
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001984 private void registerProcessSystemIonHeapSize() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001985 int tagId = FrameworkStatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08001986 mStatsManager.setPullAtomCallback(
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001987 tagId,
1988 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07001989 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001990 mStatsCallbackImpl
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001991 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001992 }
1993
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001994 int pullProcessSystemIonHeapSizeLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001995 List<IonAllocations> result = readProcessSystemIonHeapSizesFromDebugfs();
1996 for (IonAllocations allocations : result) {
1997 StatsEvent e = StatsEvent.newBuilder()
1998 .setAtomId(atomTag)
1999 .writeInt(getUidForPid(allocations.pid))
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07002000 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08002001 .writeString(readCmdlineFromProcfs(allocations.pid))
2002 .writeInt((int) (allocations.totalSizeInBytes / 1024))
2003 .writeInt(allocations.count)
2004 .writeInt((int) (allocations.maxSizeInBytes / 1024))
2005 .build();
2006 pulledData.add(e);
2007 }
2008 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002009 }
2010
2011 private void registerTemperature() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002012 int tagId = FrameworkStatsLog.TEMPERATURE;
Tej Singh72a70a82020-02-26 23:46:29 -08002013 mStatsManager.setPullAtomCallback(
Jeffrey Huangb92de552020-01-15 16:50:07 -08002014 tagId,
2015 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002016 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002017 mStatsCallbackImpl
Jeffrey Huangb92de552020-01-15 16:50:07 -08002018 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002019 }
2020
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002021 int pullTemperatureLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb92de552020-01-15 16:50:07 -08002022 IThermalService thermalService = getIThermalService();
2023 if (thermalService == null) {
2024 return StatsManager.PULL_SKIP;
2025 }
2026 final long callingToken = Binder.clearCallingIdentity();
2027 try {
Chris Ye48dbcaa2020-02-10 13:29:01 -08002028 Temperature temperatures[] = thermalService.getCurrentTemperatures();
Jeffrey Huangb92de552020-01-15 16:50:07 -08002029 for (Temperature temp : temperatures) {
2030 StatsEvent e = StatsEvent.newBuilder()
2031 .setAtomId(atomTag)
2032 .writeInt(temp.getType())
2033 .writeString(temp.getName())
2034 .writeInt((int) (temp.getValue() * 10))
2035 .writeInt(temp.getStatus())
2036 .build();
2037 pulledData.add(e);
2038 }
2039 } catch (RemoteException e) {
2040 // Should not happen.
2041 Slog.e(TAG, "Disconnected from thermal service. Cannot pull temperatures.");
2042 return StatsManager.PULL_SKIP;
2043 } finally {
2044 Binder.restoreCallingIdentity(callingToken);
2045 }
2046 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002047 }
2048
2049 private void registerCoolingDevice() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002050 int tagId = FrameworkStatsLog.COOLING_DEVICE;
Tej Singh72a70a82020-02-26 23:46:29 -08002051 mStatsManager.setPullAtomCallback(
Jeffrey Huangb92de552020-01-15 16:50:07 -08002052 tagId,
2053 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002054 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002055 mStatsCallbackImpl
Jeffrey Huangb92de552020-01-15 16:50:07 -08002056 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002057 }
2058
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002059 int pullCooldownDeviceLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb92de552020-01-15 16:50:07 -08002060 IThermalService thermalService = getIThermalService();
2061 if (thermalService == null) {
2062 return StatsManager.PULL_SKIP;
2063 }
2064 final long callingToken = Binder.clearCallingIdentity();
2065 try {
Chris Ye48dbcaa2020-02-10 13:29:01 -08002066 CoolingDevice devices[] = thermalService.getCurrentCoolingDevices();
Jeffrey Huangb92de552020-01-15 16:50:07 -08002067 for (CoolingDevice device : devices) {
2068 StatsEvent e = StatsEvent.newBuilder()
2069 .setAtomId(atomTag)
2070 .writeInt(device.getType())
2071 .writeString(device.getName())
2072 .writeInt((int) (device.getValue()))
2073 .build();
2074 pulledData.add(e);
2075 }
2076 } catch (RemoteException e) {
2077 // Should not happen.
2078 Slog.e(TAG, "Disconnected from thermal service. Cannot pull temperatures.");
2079 return StatsManager.PULL_SKIP;
2080 } finally {
2081 Binder.restoreCallingIdentity(callingToken);
2082 }
2083 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002084 }
2085
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002086 private void registerBinderCallsStats() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002087 int tagId = FrameworkStatsLog.BINDER_CALLS;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002088 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002089 .setAdditiveFields(new int[] {4, 5, 6, 8, 12})
2090 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002091 mStatsManager.setPullAtomCallback(
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002092 tagId,
2093 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07002094 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002095 mStatsCallbackImpl
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002096 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002097 }
2098
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002099 int pullBinderCallsStatsLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002100 BinderCallsStatsService.Internal binderStats =
2101 LocalServices.getService(BinderCallsStatsService.Internal.class);
2102 if (binderStats == null) {
2103 Slog.e(TAG, "failed to get binderStats");
2104 return StatsManager.PULL_SKIP;
2105 }
2106
2107 List<ExportedCallStat> callStats = binderStats.getExportedCallStats();
2108 binderStats.reset();
2109 for (ExportedCallStat callStat : callStats) {
2110 StatsEvent e = StatsEvent.newBuilder()
2111 .setAtomId(atomTag)
2112 .writeInt(callStat.workSourceUid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07002113 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002114 .writeString(callStat.className)
2115 .writeString(callStat.methodName)
2116 .writeLong(callStat.callCount)
2117 .writeLong(callStat.exceptionCount)
2118 .writeLong(callStat.latencyMicros)
2119 .writeLong(callStat.maxLatencyMicros)
2120 .writeLong(callStat.cpuTimeMicros)
2121 .writeLong(callStat.maxCpuTimeMicros)
2122 .writeLong(callStat.maxReplySizeBytes)
2123 .writeLong(callStat.maxRequestSizeBytes)
2124 .writeLong(callStat.recordedCallCount)
2125 .writeInt(callStat.screenInteractive ? 1 : 0)
2126 .writeInt(callStat.callingUid)
2127 .build();
2128 pulledData.add(e);
2129 }
2130 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002131 }
2132
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002133 private void registerBinderCallsStatsExceptions() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002134 int tagId = FrameworkStatsLog.BINDER_CALLS_EXCEPTIONS;
Tej Singh72a70a82020-02-26 23:46:29 -08002135 mStatsManager.setPullAtomCallback(
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002136 tagId,
2137 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002138 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002139 mStatsCallbackImpl
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002140 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002141 }
2142
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002143 int pullBinderCallsStatsExceptionsLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002144 BinderCallsStatsService.Internal binderStats =
2145 LocalServices.getService(BinderCallsStatsService.Internal.class);
2146 if (binderStats == null) {
2147 Slog.e(TAG, "failed to get binderStats");
2148 return StatsManager.PULL_SKIP;
2149 }
2150
2151 ArrayMap<String, Integer> exceptionStats = binderStats.getExportedExceptionStats();
2152 // TODO: decouple binder calls exceptions with the rest of the binder calls data so that we
2153 // can reset the exception stats.
2154 for (Map.Entry<String, Integer> entry : exceptionStats.entrySet()) {
2155 StatsEvent e = StatsEvent.newBuilder()
2156 .setAtomId(atomTag)
2157 .writeString(entry.getKey())
2158 .writeInt(entry.getValue())
2159 .build();
2160 pulledData.add(e);
2161 }
2162 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002163 }
2164
2165 private void registerLooperStats() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002166 int tagId = FrameworkStatsLog.LOOPER_STATS;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002167 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangfd037c52020-01-16 10:42:59 -08002168 .setAdditiveFields(new int[] {5, 6, 7, 8, 9})
2169 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002170 mStatsManager.setPullAtomCallback(
Jeffrey Huangfd037c52020-01-16 10:42:59 -08002171 tagId,
2172 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07002173 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002174 mStatsCallbackImpl
Jeffrey Huangfd037c52020-01-16 10:42:59 -08002175 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002176 }
2177
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002178 int pullLooperStatsLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangfd037c52020-01-16 10:42:59 -08002179 LooperStats looperStats = LocalServices.getService(LooperStats.class);
2180 if (looperStats == null) {
2181 return StatsManager.PULL_SKIP;
2182 }
2183
2184 List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
2185 looperStats.reset();
2186 for (LooperStats.ExportedEntry entry : entries) {
2187 StatsEvent e = StatsEvent.newBuilder()
2188 .setAtomId(atomTag)
2189 .writeInt(entry.workSourceUid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07002190 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangfd037c52020-01-16 10:42:59 -08002191 .writeString(entry.handlerClassName)
2192 .writeString(entry.threadName)
2193 .writeString(entry.messageName)
2194 .writeLong(entry.messageCount)
2195 .writeLong(entry.exceptionCount)
2196 .writeLong(entry.recordedMessageCount)
2197 .writeLong(entry.totalLatencyMicros)
2198 .writeLong(entry.cpuUsageMicros)
2199 .writeBoolean(entry.isInteractive)
2200 .writeLong(entry.maxCpuUsageMicros)
2201 .writeLong(entry.maxLatencyMicros)
2202 .writeLong(entry.recordedDelayMessageCount)
2203 .writeLong(entry.delayMillis)
2204 .writeLong(entry.maxDelayMillis)
2205 .build();
2206 pulledData.add(e);
2207 }
2208 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002209 }
2210
2211 private void registerDiskStats() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002212 int tagId = FrameworkStatsLog.DISK_STATS;
Tej Singh72a70a82020-02-26 23:46:29 -08002213 mStatsManager.setPullAtomCallback(
Jeffrey Huang95765f02020-01-16 11:33:58 -08002214 tagId,
2215 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002216 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002217 mStatsCallbackImpl
Jeffrey Huang95765f02020-01-16 11:33:58 -08002218 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002219 }
2220
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002221 int pullDiskStatsLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang95765f02020-01-16 11:33:58 -08002222 // Run a quick-and-dirty performance test: write 512 bytes
2223 byte[] junk = new byte[512];
2224 for (int i = 0; i < junk.length; i++) junk[i] = (byte) i; // Write nonzero bytes
2225
2226 File tmp = new File(Environment.getDataDirectory(), "system/statsdperftest.tmp");
2227 FileOutputStream fos = null;
2228 IOException error = null;
2229
2230 long before = SystemClock.elapsedRealtime();
2231 try {
2232 fos = new FileOutputStream(tmp);
2233 fos.write(junk);
2234 } catch (IOException e) {
2235 error = e;
2236 } finally {
2237 try {
2238 if (fos != null) fos.close();
2239 } catch (IOException e) {
2240 // Do nothing.
2241 }
2242 }
2243
2244 long latency = SystemClock.elapsedRealtime() - before;
2245 if (tmp.exists()) tmp.delete();
2246
2247 if (error != null) {
2248 Slog.e(TAG, "Error performing diskstats latency test");
2249 latency = -1;
2250 }
2251 // File based encryption.
2252 boolean fileBased = StorageManager.isFileEncryptedNativeOnly();
2253
2254 //Recent disk write speed. Binder call to storaged.
2255 int writeSpeed = -1;
2256 IStoraged storaged = getIStoragedService();
2257 if (storaged == null) {
2258 return StatsManager.PULL_SKIP;
2259 }
2260 try {
2261 writeSpeed = storaged.getRecentPerf();
2262 } catch (RemoteException e) {
2263 Slog.e(TAG, "storaged not found");
2264 }
2265
2266 // Add info pulledData.
2267 StatsEvent e = StatsEvent.newBuilder()
2268 .setAtomId(atomTag)
2269 .writeLong(latency)
2270 .writeBoolean(fileBased)
2271 .writeInt(writeSpeed)
2272 .build();
2273 pulledData.add(e);
2274 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002275 }
2276
2277 private void registerDirectoryUsage() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002278 int tagId = FrameworkStatsLog.DIRECTORY_USAGE;
Tej Singh72a70a82020-02-26 23:46:29 -08002279 mStatsManager.setPullAtomCallback(
Jeffrey Huang95765f02020-01-16 11:33:58 -08002280 tagId,
2281 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002282 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002283 mStatsCallbackImpl
Jeffrey Huang95765f02020-01-16 11:33:58 -08002284 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002285 }
2286
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002287 int pullDirectoryUsageLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang95765f02020-01-16 11:33:58 -08002288 StatFs statFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath());
2289 StatFs statFsSystem = new StatFs(Environment.getRootDirectory().getAbsolutePath());
2290 StatFs statFsCache = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath());
2291
2292 StatsEvent e = StatsEvent.newBuilder()
2293 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002294 .writeInt(FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__DATA)
Jeffrey Huang95765f02020-01-16 11:33:58 -08002295 .writeLong(statFsData.getAvailableBytes())
2296 .writeLong(statFsData.getTotalBytes())
2297 .build();
2298 pulledData.add(e);
2299
2300 e = StatsEvent.newBuilder()
2301 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002302 .writeInt(FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__CACHE)
Jeffrey Huang95765f02020-01-16 11:33:58 -08002303 .writeLong(statFsCache.getAvailableBytes())
2304 .writeLong(statFsCache.getTotalBytes())
2305 .build();
2306 pulledData.add(e);
2307
2308 e = StatsEvent.newBuilder()
2309 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002310 .writeInt(FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__SYSTEM)
Jeffrey Huang95765f02020-01-16 11:33:58 -08002311 .writeLong(statFsSystem.getAvailableBytes())
2312 .writeLong(statFsSystem.getTotalBytes())
2313 .build();
2314 pulledData.add(e);
2315 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002316 }
2317
2318 private void registerAppSize() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002319 int tagId = FrameworkStatsLog.APP_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08002320 mStatsManager.setPullAtomCallback(
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002321 tagId,
2322 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002323 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002324 mStatsCallbackImpl
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002325 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002326 }
2327
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002328 int pullAppSizeLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002329 try {
2330 String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
2331 JSONObject json = new JSONObject(jsonStr);
2332 long cache_time = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L);
2333 JSONArray pkg_names = json.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY);
2334 JSONArray app_sizes = json.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY);
2335 JSONArray app_data_sizes = json.getJSONArray(DiskStatsFileLogger.APP_DATA_KEY);
2336 JSONArray app_cache_sizes = json.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY);
2337 // Sanity check: Ensure all 4 lists have the same length.
2338 int length = pkg_names.length();
2339 if (app_sizes.length() != length || app_data_sizes.length() != length
2340 || app_cache_sizes.length() != length) {
2341 Slog.e(TAG, "formatting error in diskstats cache file!");
2342 return StatsManager.PULL_SKIP;
2343 }
2344 for (int i = 0; i < length; i++) {
2345 StatsEvent e = StatsEvent.newBuilder()
2346 .setAtomId(atomTag)
2347 .writeString(pkg_names.getString(i))
2348 .writeLong(app_sizes.optLong(i, /* fallback */ -1L))
2349 .writeLong(app_data_sizes.optLong(i, /* fallback */ -1L))
2350 .writeLong(app_cache_sizes.optLong(i, /* fallback */ -1L))
2351 .writeLong(cache_time)
2352 .build();
2353 pulledData.add(e);
2354 }
2355 } catch (IOException | JSONException e) {
Ruchir Rastogie965f4a2020-06-05 08:32:05 -07002356 Slog.w(TAG, "Unable to read diskstats cache file within pullAppSize");
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002357 return StatsManager.PULL_SKIP;
2358 }
2359 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002360 }
2361
2362 private void registerCategorySize() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002363 int tagId = FrameworkStatsLog.CATEGORY_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08002364 mStatsManager.setPullAtomCallback(
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002365 tagId,
2366 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002367 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002368 mStatsCallbackImpl
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002369 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002370 }
2371
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002372 int pullCategorySizeLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002373 try {
2374 String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
2375 JSONObject json = new JSONObject(jsonStr);
2376 long cacheTime = json.optLong(
2377 DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, /* fallback */ -1L);
2378
2379 StatsEvent e = StatsEvent.newBuilder()
2380 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002381 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__APP_SIZE)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002382 .writeLong(json.optLong(
2383 DiskStatsFileLogger.APP_SIZE_AGG_KEY, /* fallback */ -1L))
2384 .writeLong(cacheTime)
2385 .build();
2386 pulledData.add(e);
2387
2388 e = StatsEvent.newBuilder()
2389 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002390 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__APP_DATA_SIZE)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002391 .writeLong(json.optLong(
2392 DiskStatsFileLogger.APP_DATA_SIZE_AGG_KEY, /* fallback */ -1L))
2393 .writeLong(cacheTime)
2394 .build();
2395 pulledData.add(e);
2396
2397 e = StatsEvent.newBuilder()
2398 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002399 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__APP_CACHE_SIZE)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002400 .writeLong(json.optLong(
2401 DiskStatsFileLogger.APP_CACHE_AGG_KEY, /* fallback */ -1L))
2402 .writeLong(cacheTime)
2403 .build();
2404 pulledData.add(e);
2405
2406 e = StatsEvent.newBuilder()
2407 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002408 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__PHOTOS)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002409 .writeLong(json.optLong(
2410 DiskStatsFileLogger.PHOTOS_KEY, /* fallback */ -1L))
2411 .writeLong(cacheTime)
2412 .build();
2413 pulledData.add(e);
2414
2415 e = StatsEvent.newBuilder()
2416 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002417 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__VIDEOS)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002418 .writeLong(
2419 json.optLong(DiskStatsFileLogger.VIDEOS_KEY, /* fallback */ -1L))
2420 .writeLong(cacheTime)
2421 .build();
2422 pulledData.add(e);
2423
2424 e = StatsEvent.newBuilder()
2425 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002426 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__AUDIO)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002427 .writeLong(json.optLong(
2428 DiskStatsFileLogger.AUDIO_KEY, /* fallback */ -1L))
2429 .writeLong(cacheTime)
2430 .build();
2431 pulledData.add(e);
2432
2433 e = StatsEvent.newBuilder()
2434 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002435 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__DOWNLOADS)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002436 .writeLong(
2437 json.optLong(DiskStatsFileLogger.DOWNLOADS_KEY, /* fallback */ -1L))
2438 .writeLong(cacheTime)
2439 .build();
2440 pulledData.add(e);
2441
2442 e = StatsEvent.newBuilder()
Tej Singh5dd1dc92020-01-29 20:44:42 -08002443 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002444 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__SYSTEM)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002445 .writeLong(json.optLong(
2446 DiskStatsFileLogger.SYSTEM_KEY, /* fallback */ -1L))
2447 .writeLong(cacheTime)
2448 .build();
2449 pulledData.add(e);
2450
2451 e = StatsEvent.newBuilder()
2452 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002453 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__OTHER)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002454 .writeLong(json.optLong(
2455 DiskStatsFileLogger.MISC_KEY, /* fallback */ -1L))
2456 .writeLong(cacheTime)
2457 .build();
2458 pulledData.add(e);
2459 } catch (IOException | JSONException e) {
Ruchir Rastogie965f4a2020-06-05 08:32:05 -07002460 Slog.w(TAG, "Unable to read diskstats cache file within pullCategorySize");
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002461 return StatsManager.PULL_SKIP;
2462 }
2463 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002464 }
2465
2466 private void registerNumFingerprintsEnrolled() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002467 int tagId = FrameworkStatsLog.NUM_FINGERPRINTS_ENROLLED;
Tej Singh72a70a82020-02-26 23:46:29 -08002468 mStatsManager.setPullAtomCallback(
Jeffrey Huang597a8862020-01-16 14:56:37 -08002469 tagId,
2470 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002471 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002472 mStatsCallbackImpl
Jeffrey Huang597a8862020-01-16 14:56:37 -08002473 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002474 }
2475
2476 private void registerNumFacesEnrolled() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002477 int tagId = FrameworkStatsLog.NUM_FACES_ENROLLED;
Tej Singh72a70a82020-02-26 23:46:29 -08002478 mStatsManager.setPullAtomCallback(
Jeffrey Huang597a8862020-01-16 14:56:37 -08002479 tagId,
2480 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002481 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002482 mStatsCallbackImpl
Jeffrey Huang597a8862020-01-16 14:56:37 -08002483 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002484 }
2485
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002486 private int pullNumBiometricsEnrolledLocked(int modality, int atomTag,
2487 List<StatsEvent> pulledData) {
Jeffrey Huang597a8862020-01-16 14:56:37 -08002488 final PackageManager pm = mContext.getPackageManager();
2489 FingerprintManager fingerprintManager = null;
2490 FaceManager faceManager = null;
2491
2492 if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
2493 fingerprintManager = mContext.getSystemService(FingerprintManager.class);
2494 }
2495 if (pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
2496 faceManager = mContext.getSystemService(FaceManager.class);
2497 }
2498
2499 if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT && fingerprintManager == null) {
2500 return StatsManager.PULL_SKIP;
2501 }
2502 if (modality == BiometricsProtoEnums.MODALITY_FACE && faceManager == null) {
2503 return StatsManager.PULL_SKIP;
2504 }
2505 UserManager userManager = mContext.getSystemService(UserManager.class);
2506 if (userManager == null) {
2507 return StatsManager.PULL_SKIP;
2508 }
2509
2510 final long token = Binder.clearCallingIdentity();
2511 try {
2512 for (UserInfo user : userManager.getUsers()) {
2513 final int userId = user.getUserHandle().getIdentifier();
2514 int numEnrolled = 0;
2515 if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT) {
2516 numEnrolled = fingerprintManager.getEnrolledFingerprints(userId).size();
2517 } else if (modality == BiometricsProtoEnums.MODALITY_FACE) {
2518 numEnrolled = faceManager.getEnrolledFaces(userId).size();
2519 } else {
2520 return StatsManager.PULL_SKIP;
2521 }
2522 StatsEvent e = StatsEvent.newBuilder()
2523 .setAtomId(atomTag)
2524 .writeInt(userId)
2525 .writeInt(numEnrolled)
2526 .build();
2527 pulledData.add(e);
2528 }
2529 } finally {
2530 Binder.restoreCallingIdentity(token);
2531 }
2532 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002533 }
2534
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002535 private void registerProcStats() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002536 int tagId = FrameworkStatsLog.PROC_STATS;
Tej Singh72a70a82020-02-26 23:46:29 -08002537 mStatsManager.setPullAtomCallback(
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002538 tagId,
2539 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002540 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002541 mStatsCallbackImpl
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002542 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002543 }
2544
2545 private void registerProcStatsPkgProc() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002546 int tagId = FrameworkStatsLog.PROC_STATS_PKG_PROC;
Tej Singh72a70a82020-02-26 23:46:29 -08002547 mStatsManager.setPullAtomCallback(
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002548 tagId,
2549 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002550 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002551 mStatsCallbackImpl
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002552 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002553 }
2554
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002555 private int pullProcStatsLocked(int section, int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002556 IProcessStats processStatsService = getIProcessStatsService();
2557 if (processStatsService == null) {
2558 return StatsManager.PULL_SKIP;
2559 }
2560
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002561 final long token = Binder.clearCallingIdentity();
2562 try {
2563 // force procstats to flush & combine old files into one store
2564 long lastHighWaterMark = readProcStatsHighWaterMark(section);
2565 List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
Richard Gaywood863a7212020-03-16 17:49:54 +00002566
Richard Gaywood52a2edf2020-06-14 17:39:15 +01002567 ProtoOutputStream[] protoStreams = new ProtoOutputStream[MAX_PROCSTATS_SHARDS];
2568 for (int i = 0; i < protoStreams.length; i++) {
2569 protoStreams[i] = new ProtoOutputStream();
2570 }
2571
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002572 ProcessStats procStats = new ProcessStats(false);
Richard Gaywood52a2edf2020-06-14 17:39:15 +01002573 // Force processStatsService to aggregate all in-storage and in-memory data.
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002574 long highWaterMark = processStatsService.getCommittedStatsMerged(
2575 lastHighWaterMark, section, true, statsFiles, procStats);
Richard Gaywood52a2edf2020-06-14 17:39:15 +01002576 procStats.dumpAggregatedProtoForStatsd(protoStreams, MAX_PROCSTATS_RAW_SHARD_SIZE);
Richard Gaywood863a7212020-03-16 17:49:54 +00002577
Richard Gaywood78c3f992020-06-23 17:12:49 +01002578 for (int i = 0; i < protoStreams.length; i++) {
2579 byte[] bytes = protoStreams[i].getBytes(); // cache the value
2580 if (bytes.length > 0) {
Richard Gaywood52a2edf2020-06-14 17:39:15 +01002581 StatsEvent e = StatsEvent.newBuilder()
2582 .setAtomId(atomTag)
Richard Gaywood78c3f992020-06-23 17:12:49 +01002583 .writeByteArray(bytes)
2584 // This is a shard ID, and is specified in the metric definition to be
2585 // a dimension. This will result in statsd using RANDOM_ONE_SAMPLE to
2586 // keep all the shards, as it thinks each shard is a different dimension
2587 // of data.
2588 .writeInt(i)
Richard Gaywood52a2edf2020-06-14 17:39:15 +01002589 .build();
2590 pulledData.add(e);
2591 }
2592 }
Richard Gaywood863a7212020-03-16 17:49:54 +00002593
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002594 new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + lastHighWaterMark)
2595 .delete();
2596 new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + highWaterMark)
2597 .createNewFile();
2598 } catch (RemoteException | IOException e) {
2599 Slog.e(TAG, "Getting procstats failed: ", e);
2600 return StatsManager.PULL_SKIP;
2601 } finally {
2602 Binder.restoreCallingIdentity(token);
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002603 }
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002604 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002605 }
2606
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002607 // read high watermark for section
2608 private long readProcStatsHighWaterMark(int section) {
2609 try {
2610 File[] files = mBaseDir.listFiles((d, name) -> {
2611 return name.toLowerCase().startsWith(String.valueOf(section) + '_');
2612 });
2613 if (files == null || files.length == 0) {
2614 return 0;
2615 }
2616 if (files.length > 1) {
2617 Slog.e(TAG, "Only 1 file expected for high water mark. Found " + files.length);
2618 }
2619 return Long.valueOf(files[0].getName().split("_")[1]);
2620 } catch (SecurityException e) {
2621 Slog.e(TAG, "Failed to get procstats high watermark file.", e);
2622 } catch (NumberFormatException e) {
2623 Slog.e(TAG, "Failed to parse file name.", e);
2624 }
2625 return 0;
2626 }
2627
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002628 private void registerDiskIO() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002629 int tagId = FrameworkStatsLog.DISK_IO;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002630 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002631 .setAdditiveFields(new int[] {2, 3, 4, 5, 6, 7, 8, 9, 10, 11})
Tej Singh72a70a82020-02-26 23:46:29 -08002632 .setCoolDownMillis(3 * MILLIS_PER_SEC)
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002633 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002634 mStatsManager.setPullAtomCallback(
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002635 tagId,
2636 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07002637 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002638 mStatsCallbackImpl
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002639 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002640 }
2641
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002642 int pullDiskIOLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002643 mStoragedUidIoStatsReader.readAbsolute((uid, fgCharsRead, fgCharsWrite, fgBytesRead,
2644 fgBytesWrite, bgCharsRead, bgCharsWrite, bgBytesRead, bgBytesWrite,
2645 fgFsync, bgFsync) -> {
2646 StatsEvent e = StatsEvent.newBuilder()
2647 .setAtomId(atomTag)
2648 .writeInt(uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07002649 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002650 .writeLong(fgCharsRead)
2651 .writeLong(fgCharsWrite)
2652 .writeLong(fgBytesRead)
2653 .writeLong(fgBytesWrite)
2654 .writeLong(bgCharsRead)
2655 .writeLong(bgCharsWrite)
2656 .writeLong(bgBytesRead)
2657 .writeLong(bgBytesWrite)
2658 .writeLong(fgFsync)
2659 .writeLong(bgFsync)
2660 .build();
2661 pulledData.add(e);
2662 });
2663 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002664 }
2665
2666 private void registerPowerProfile() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002667 int tagId = FrameworkStatsLog.POWER_PROFILE;
Tej Singh72a70a82020-02-26 23:46:29 -08002668 mStatsManager.setPullAtomCallback(
Jeffrey Huang1a3935c2020-01-13 10:51:17 -08002669 tagId,
2670 /* PullAtomMetadata */ null,
Tej Singhe19799f2020-05-20 19:14:26 -07002671 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002672 mStatsCallbackImpl
Jeffrey Huang1a3935c2020-01-13 10:51:17 -08002673 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002674 }
2675
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002676 int pullPowerProfileLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang1a3935c2020-01-13 10:51:17 -08002677 PowerProfile powerProfile = new PowerProfile(mContext);
2678 ProtoOutputStream proto = new ProtoOutputStream();
2679 powerProfile.dumpDebug(proto);
2680 proto.flush();
2681 StatsEvent e = StatsEvent.newBuilder()
2682 .setAtomId(atomTag)
2683 .writeByteArray(proto.getBytes())
2684 .build();
2685 pulledData.add(e);
2686 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002687 }
2688
2689 private void registerProcessCpuTime() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002690 int tagId = FrameworkStatsLog.PROCESS_CPU_TIME;
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002691 // Min cool-down is 5 sec, in line with what ActivityManagerService uses.
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002692 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Tej Singh72a70a82020-02-26 23:46:29 -08002693 .setCoolDownMillis(5 * MILLIS_PER_SEC)
Jeffrey Huang7a9ae132020-01-14 15:44:58 -08002694 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002695 mStatsManager.setPullAtomCallback(
Jeffrey Huang7a9ae132020-01-14 15:44:58 -08002696 tagId,
2697 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07002698 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002699 mStatsCallbackImpl
Jeffrey Huang7a9ae132020-01-14 15:44:58 -08002700 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002701 }
2702
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002703 int pullProcessCpuTimeLocked(int atomTag, List<StatsEvent> pulledData) {
2704 if (mProcessCpuTracker == null) {
2705 mProcessCpuTracker = new ProcessCpuTracker(false);
2706 mProcessCpuTracker.init();
2707 }
2708 mProcessCpuTracker.update();
2709 for (int i = 0; i < mProcessCpuTracker.countStats(); i++) {
2710 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2711 StatsEvent e = StatsEvent.newBuilder()
2712 .setAtomId(atomTag)
2713 .writeInt(st.uid)
2714 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
2715 .writeString(st.name)
2716 .writeLong(st.base_utime)
2717 .writeLong(st.base_stime)
2718 .build();
2719 pulledData.add(e);
Jeffrey Huang7a9ae132020-01-14 15:44:58 -08002720 }
2721 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002722 }
2723
2724 private void registerCpuTimePerThreadFreq() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002725 int tagId = FrameworkStatsLog.CPU_TIME_PER_THREAD_FREQ;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002726 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangbf4eef82020-01-16 15:38:58 -08002727 .setAdditiveFields(new int[] {7, 9, 11, 13, 15, 17, 19, 21})
2728 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002729 mStatsManager.setPullAtomCallback(
Jeffrey Huangbf4eef82020-01-16 15:38:58 -08002730 tagId,
2731 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07002732 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002733 mStatsCallbackImpl
Jeffrey Huangbf4eef82020-01-16 15:38:58 -08002734 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002735 }
2736
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002737 int pullCpuTimePerThreadFreqLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangbf4eef82020-01-16 15:38:58 -08002738 if (this.mKernelCpuThreadReader == null) {
2739 Slog.e(TAG, "mKernelCpuThreadReader is null");
2740 return StatsManager.PULL_SKIP;
2741 }
2742 ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages =
2743 this.mKernelCpuThreadReader.getProcessCpuUsageDiffed();
2744 if (processCpuUsages == null) {
2745 Slog.e(TAG, "processCpuUsages is null");
2746 return StatsManager.PULL_SKIP;
2747 }
2748 int[] cpuFrequencies = mKernelCpuThreadReader.getCpuFrequenciesKhz();
2749 if (cpuFrequencies.length > CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES) {
2750 String message = "Expected maximum " + CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES
2751 + " frequencies, but got " + cpuFrequencies.length;
2752 Slog.w(TAG, message);
2753 return StatsManager.PULL_SKIP;
2754 }
2755 for (int i = 0; i < processCpuUsages.size(); i++) {
2756 KernelCpuThreadReader.ProcessCpuUsage processCpuUsage = processCpuUsages.get(i);
2757 ArrayList<KernelCpuThreadReader.ThreadCpuUsage> threadCpuUsages =
2758 processCpuUsage.threadCpuUsages;
2759 for (int j = 0; j < threadCpuUsages.size(); j++) {
2760 KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage = threadCpuUsages.get(j);
2761 if (threadCpuUsage.usageTimesMillis.length != cpuFrequencies.length) {
2762 String message = "Unexpected number of usage times,"
2763 + " expected " + cpuFrequencies.length
2764 + " but got " + threadCpuUsage.usageTimesMillis.length;
2765 Slog.w(TAG, message);
2766 return StatsManager.PULL_SKIP;
2767 }
2768
2769 StatsEvent.Builder e = StatsEvent.newBuilder();
2770 e.setAtomId(atomTag);
2771 e.writeInt(processCpuUsage.uid);
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07002772 e.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
Jeffrey Huangbf4eef82020-01-16 15:38:58 -08002773 e.writeInt(processCpuUsage.processId);
2774 e.writeInt(threadCpuUsage.threadId);
2775 e.writeString(processCpuUsage.processName);
2776 e.writeString(threadCpuUsage.threadName);
2777 for (int k = 0; k < CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES; k++) {
2778 if (k < cpuFrequencies.length) {
2779 e.writeInt(cpuFrequencies[k]);
2780 e.writeInt(threadCpuUsage.usageTimesMillis[k]);
2781 } else {
2782 // If we have no more frequencies to write, we still must write empty data.
2783 // We know that this data is empty (and not just zero) because all
2784 // frequencies are expected to be greater than zero
2785 e.writeInt(0);
2786 e.writeInt(0);
2787 }
2788 }
2789 pulledData.add(e.build());
2790 }
2791 }
2792 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002793 }
2794
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002795 private BatteryStatsHelper getBatteryStatsHelper() {
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002796 synchronized (mBatteryStatsHelperLock) {
2797 if (mBatteryStatsHelper == null) {
2798 final long callingToken = Binder.clearCallingIdentity();
2799 try {
2800 // clearCallingIdentity required for BatteryStatsHelper.checkWifiOnly().
2801 mBatteryStatsHelper = new BatteryStatsHelper(mContext, false);
2802 } finally {
2803 Binder.restoreCallingIdentity(callingToken);
2804 }
2805 mBatteryStatsHelper.create((Bundle) null);
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002806 }
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002807 long currentTime = SystemClock.elapsedRealtime();
2808 if (currentTime - mBatteryStatsHelperTimestampMs
2809 >= MAX_BATTERY_STATS_HELPER_FREQUENCY_MS) {
2810 // Load BatteryStats and do all the calculations.
2811 mBatteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED,
2812 UserHandle.USER_ALL);
2813 // Calculations are done so we don't need to save the raw BatteryStats data in RAM.
2814 mBatteryStatsHelper.clearStats();
2815 mBatteryStatsHelperTimestampMs = currentTime;
2816 }
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002817 }
2818 return mBatteryStatsHelper;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002819 }
2820
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002821 private long milliAmpHrsToNanoAmpSecs(double mAh) {
2822 return (long) (mAh * MILLI_AMP_HR_TO_NANO_AMP_SECS + 0.5);
2823 }
2824
2825 private void registerDeviceCalculatedPowerUse() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002826 int tagId = FrameworkStatsLog.DEVICE_CALCULATED_POWER_USE;
Tej Singh72a70a82020-02-26 23:46:29 -08002827 mStatsManager.setPullAtomCallback(
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002828 tagId,
2829 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002830 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002831 mStatsCallbackImpl
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002832 );
2833 }
2834
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002835 int pullDeviceCalculatedPowerUseLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002836 BatteryStatsHelper bsHelper = getBatteryStatsHelper();
2837 StatsEvent e = StatsEvent.newBuilder()
2838 .setAtomId(atomTag)
2839 .writeLong(milliAmpHrsToNanoAmpSecs(bsHelper.getComputedPower()))
2840 .build();
2841 pulledData.add(e);
2842 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002843 }
2844
2845 private void registerDeviceCalculatedPowerBlameUid() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002846 int tagId = FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_UID;
Tej Singh72a70a82020-02-26 23:46:29 -08002847 mStatsManager.setPullAtomCallback(
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002848 tagId,
2849 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002850 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002851 mStatsCallbackImpl
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002852 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002853 }
2854
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002855 int pullDeviceCalculatedPowerBlameUidLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002856 final List<BatterySipper> sippers = getBatteryStatsHelper().getUsageList();
2857 if (sippers == null) {
2858 return StatsManager.PULL_SKIP;
2859 }
2860
2861 for (BatterySipper bs : sippers) {
2862 if (bs.drainType != bs.drainType.APP) {
2863 continue;
2864 }
2865 StatsEvent e = StatsEvent.newBuilder()
2866 .setAtomId(atomTag)
2867 .writeInt(bs.uidObj.getUid())
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07002868 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002869 .writeLong(milliAmpHrsToNanoAmpSecs(bs.totalPowerMah))
2870 .build();
2871 pulledData.add(e);
2872 }
2873 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002874 }
2875
2876 private void registerDeviceCalculatedPowerBlameOther() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002877 int tagId = FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_OTHER;
Tej Singh72a70a82020-02-26 23:46:29 -08002878 mStatsManager.setPullAtomCallback(
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002879 tagId,
2880 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002881 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002882 mStatsCallbackImpl
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002883 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002884 }
2885
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002886 int pullDeviceCalculatedPowerBlameOtherLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002887 final List<BatterySipper> sippers = getBatteryStatsHelper().getUsageList();
2888 if (sippers == null) {
2889 return StatsManager.PULL_SKIP;
2890 }
2891
2892 for (BatterySipper bs : sippers) {
2893 if (bs.drainType == bs.drainType.APP) {
2894 continue; // This is a separate atom; see pullDeviceCalculatedPowerBlameUid().
2895 }
2896 if (bs.drainType == bs.drainType.USER) {
2897 continue; // This is not supported. We purposefully calculate over USER_ALL.
2898 }
2899 StatsEvent e = StatsEvent.newBuilder()
2900 .setAtomId(atomTag)
2901 .writeInt(bs.drainType.ordinal())
2902 .writeLong(milliAmpHrsToNanoAmpSecs(bs.totalPowerMah))
2903 .build();
2904 pulledData.add(e);
2905 }
2906 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002907 }
2908
2909 private void registerDebugElapsedClock() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002910 int tagId = FrameworkStatsLog.DEBUG_ELAPSED_CLOCK;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002911 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002912 .setAdditiveFields(new int[] {1, 2, 3, 4})
2913 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002914 mStatsManager.setPullAtomCallback(
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002915 tagId,
2916 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07002917 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002918 mStatsCallbackImpl
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002919 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002920 }
2921
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002922 int pullDebugElapsedClockLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002923 final long elapsedMillis = SystemClock.elapsedRealtime();
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002924 final long clockDiffMillis = mDebugElapsedClockPreviousValue == 0
2925 ? 0 : elapsedMillis - mDebugElapsedClockPreviousValue;
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002926
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002927 StatsEvent e = StatsEvent.newBuilder()
2928 .setAtomId(atomTag)
2929 .writeLong(mDebugElapsedClockPullCount)
2930 .writeLong(elapsedMillis)
2931 // Log it twice to be able to test multi-value aggregation from ValueMetric.
2932 .writeLong(elapsedMillis)
2933 .writeLong(clockDiffMillis)
2934 .writeInt(1 /* always set */)
2935 .build();
2936 pulledData.add(e);
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002937
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002938 if (mDebugElapsedClockPullCount % 2 == 1) {
2939 StatsEvent e2 = StatsEvent.newBuilder()
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002940 .setAtomId(atomTag)
2941 .writeLong(mDebugElapsedClockPullCount)
2942 .writeLong(elapsedMillis)
2943 // Log it twice to be able to test multi-value aggregation from ValueMetric.
2944 .writeLong(elapsedMillis)
2945 .writeLong(clockDiffMillis)
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002946 .writeInt(2 /* set on odd pulls */)
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002947 .build();
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002948 pulledData.add(e2);
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002949 }
2950
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002951 mDebugElapsedClockPullCount++;
2952 mDebugElapsedClockPreviousValue = elapsedMillis;
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002953 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002954 }
2955
2956 private void registerDebugFailingElapsedClock() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002957 int tagId = FrameworkStatsLog.DEBUG_FAILING_ELAPSED_CLOCK;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002958 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002959 .setAdditiveFields(new int[] {1, 2, 3, 4})
2960 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002961 mStatsManager.setPullAtomCallback(
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002962 tagId,
2963 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07002964 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002965 mStatsCallbackImpl
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002966 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002967 }
2968
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002969 int pullDebugFailingElapsedClockLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002970 final long elapsedMillis = SystemClock.elapsedRealtime();
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002971 // Fails every 5 buckets.
2972 if (mDebugFailingElapsedClockPullCount++ % 5 == 0) {
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002973 mDebugFailingElapsedClockPreviousValue = elapsedMillis;
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002974 Slog.e(TAG, "Failing debug elapsed clock");
2975 return StatsManager.PULL_SKIP;
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002976 }
2977
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002978 StatsEvent e = StatsEvent.newBuilder()
2979 .setAtomId(atomTag)
2980 .writeLong(mDebugFailingElapsedClockPullCount)
2981 .writeLong(elapsedMillis)
2982 // Log it twice to be able to test multi-value aggregation from ValueMetric.
2983 .writeLong(elapsedMillis)
2984 .writeLong(mDebugFailingElapsedClockPreviousValue == 0
2985 ? 0 : elapsedMillis - mDebugFailingElapsedClockPreviousValue)
2986 .build();
2987 pulledData.add(e);
2988
2989 mDebugFailingElapsedClockPreviousValue = elapsedMillis;
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002990 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002991 }
2992
2993 private void registerBuildInformation() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002994 int tagId = FrameworkStatsLog.BUILD_INFORMATION;
Tej Singh72a70a82020-02-26 23:46:29 -08002995 mStatsManager.setPullAtomCallback(
Ruchir Rastogi425d8362020-01-14 23:51:46 -08002996 tagId,
2997 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002998 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002999 mStatsCallbackImpl
Ruchir Rastogi425d8362020-01-14 23:51:46 -08003000 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003001 }
3002
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003003 int pullBuildInformationLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi425d8362020-01-14 23:51:46 -08003004 StatsEvent e = StatsEvent.newBuilder()
3005 .setAtomId(atomTag)
3006 .writeString(Build.FINGERPRINT)
3007 .writeString(Build.BRAND)
3008 .writeString(Build.PRODUCT)
3009 .writeString(Build.DEVICE)
Dianne Hackborndb007452019-10-28 16:34:22 -07003010 .writeString(Build.VERSION.RELEASE_OR_CODENAME)
Ruchir Rastogi425d8362020-01-14 23:51:46 -08003011 .writeString(Build.ID)
3012 .writeString(Build.VERSION.INCREMENTAL)
3013 .writeString(Build.TYPE)
3014 .writeString(Build.TAGS)
3015 .build();
3016 pulledData.add(e);
3017 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003018 }
3019
3020 private void registerRoleHolder() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003021 int tagId = FrameworkStatsLog.ROLE_HOLDER;
Tej Singh72a70a82020-02-26 23:46:29 -08003022 mStatsManager.setPullAtomCallback(
Ruchir Rastogie4fd3212020-01-15 00:39:12 -08003023 tagId,
3024 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003025 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003026 mStatsCallbackImpl
Ruchir Rastogie4fd3212020-01-15 00:39:12 -08003027 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003028 }
3029
Ruchir Rastogie4fd3212020-01-15 00:39:12 -08003030 // Add a RoleHolder atom for each package that holds a role.
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003031 int pullRoleHolderLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogie4fd3212020-01-15 00:39:12 -08003032 long callingToken = Binder.clearCallingIdentity();
3033 try {
3034 PackageManager pm = mContext.getPackageManager();
3035 RoleManagerInternal rmi = LocalServices.getService(RoleManagerInternal.class);
3036
3037 List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
3038
3039 int numUsers = users.size();
3040 for (int userNum = 0; userNum < numUsers; userNum++) {
3041 int userId = users.get(userNum).getUserHandle().getIdentifier();
3042
3043 ArrayMap<String, ArraySet<String>> roles = rmi.getRolesAndHolders(userId);
3044
3045 int numRoles = roles.size();
3046 for (int roleNum = 0; roleNum < numRoles; roleNum++) {
3047 String roleName = roles.keyAt(roleNum);
3048 ArraySet<String> holders = roles.valueAt(roleNum);
3049
3050 int numHolders = holders.size();
3051 for (int holderNum = 0; holderNum < numHolders; holderNum++) {
3052 String holderName = holders.valueAt(holderNum);
3053
3054 PackageInfo pkg;
3055 try {
3056 pkg = pm.getPackageInfoAsUser(holderName, 0, userId);
3057 } catch (PackageManager.NameNotFoundException e) {
3058 Slog.w(TAG, "Role holder " + holderName + " not found");
3059 return StatsManager.PULL_SKIP;
3060 }
3061
3062 StatsEvent e = StatsEvent.newBuilder()
3063 .setAtomId(atomTag)
3064 .writeInt(pkg.applicationInfo.uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07003065 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Ruchir Rastogie4fd3212020-01-15 00:39:12 -08003066 .writeString(holderName)
3067 .writeString(roleName)
3068 .build();
3069 pulledData.add(e);
3070 }
3071 }
3072 }
3073 } finally {
3074 Binder.restoreCallingIdentity(callingToken);
3075 }
3076 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003077 }
3078
3079 private void registerDangerousPermissionState() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003080 int tagId = FrameworkStatsLog.DANGEROUS_PERMISSION_STATE;
Tej Singh72a70a82020-02-26 23:46:29 -08003081 mStatsManager.setPullAtomCallback(
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003082 tagId,
3083 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003084 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003085 mStatsCallbackImpl
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003086 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003087 }
3088
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003089 int pullDangerousPermissionStateLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003090 final long token = Binder.clearCallingIdentity();
Stanislav Zholnina093ae72020-04-18 19:14:17 +01003091 float samplingRate = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_PERMISSIONS,
Stanislav Zholninba94e3b2020-06-19 16:43:47 +01003092 DANGEROUS_PERMISSION_STATE_SAMPLE_RATE, 0.015f);
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003093 Set<Integer> reportedUids = new HashSet<>();
3094 try {
3095 PackageManager pm = mContext.getPackageManager();
3096
3097 List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
3098
3099 int numUsers = users.size();
3100 for (int userNum = 0; userNum < numUsers; userNum++) {
3101 UserHandle user = users.get(userNum).getUserHandle();
3102
3103 List<PackageInfo> pkgs = pm.getInstalledPackagesAsUser(
3104 PackageManager.GET_PERMISSIONS, user.getIdentifier());
3105
3106 int numPkgs = pkgs.size();
3107 for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) {
3108 PackageInfo pkg = pkgs.get(pkgNum);
3109
3110 if (pkg.requestedPermissions == null) {
3111 continue;
3112 }
3113
3114 if (reportedUids.contains(pkg.applicationInfo.uid)) {
3115 // do not report same uid twice
3116 continue;
3117 }
3118 reportedUids.add(pkg.applicationInfo.uid);
3119
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003120 if (atomTag == FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED
Stanislav Zholnina093ae72020-04-18 19:14:17 +01003121 && ThreadLocalRandom.current().nextFloat() > samplingRate) {
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003122 continue;
3123 }
3124
3125 int numPerms = pkg.requestedPermissions.length;
3126 for (int permNum = 0; permNum < numPerms; permNum++) {
3127 String permName = pkg.requestedPermissions[permNum];
3128
3129 PermissionInfo permissionInfo;
3130 int permissionFlags = 0;
3131 try {
3132 permissionInfo = pm.getPermissionInfo(permName, 0);
3133 permissionFlags =
3134 pm.getPermissionFlags(permName, pkg.packageName, user);
3135 } catch (PackageManager.NameNotFoundException ignored) {
3136 continue;
3137 }
3138
3139 if (permissionInfo.getProtection() != PROTECTION_DANGEROUS) {
3140 continue;
3141 }
3142
Stanislav Zholnindbcf85e2020-02-24 18:17:55 +00003143 if (permName.startsWith(COMMON_PERMISSION_PREFIX)) {
3144 permName = permName.substring(COMMON_PERMISSION_PREFIX.length());
3145 }
3146
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003147 StatsEvent.Builder e = StatsEvent.newBuilder();
3148 e.setAtomId(atomTag);
3149 e.writeString(permName);
3150 e.writeInt(pkg.applicationInfo.uid);
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07003151 e.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003152 if (atomTag == FrameworkStatsLog.DANGEROUS_PERMISSION_STATE) {
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003153 e.writeString("");
3154 }
3155 e.writeBoolean((pkg.requestedPermissionsFlags[permNum]
3156 & REQUESTED_PERMISSION_GRANTED) != 0);
3157 e.writeInt(permissionFlags);
3158
3159 pulledData.add(e.build());
3160 }
3161 }
3162 }
3163 } catch (Throwable t) {
3164 Log.e(TAG, "Could not read permissions", t);
3165 return StatsManager.PULL_SKIP;
3166 } finally {
3167 Binder.restoreCallingIdentity(token);
3168 }
3169 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003170 }
3171
3172 private void registerTimeZoneDataInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003173 int tagId = FrameworkStatsLog.TIME_ZONE_DATA_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08003174 mStatsManager.setPullAtomCallback(
Ruchir Rastogibd2c4ba2020-01-15 14:48:36 -08003175 tagId,
3176 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003177 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003178 mStatsCallbackImpl
Ruchir Rastogibd2c4ba2020-01-15 14:48:36 -08003179 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003180 }
3181
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003182 int pullTimeZoneDataInfoLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogibd2c4ba2020-01-15 14:48:36 -08003183 String tzDbVersion = "Unknown";
3184 try {
3185 tzDbVersion = android.icu.util.TimeZone.getTZDataVersion();
3186 } catch (MissingResourceException e) {
3187 Slog.e(TAG, "Getting tzdb version failed: ", e);
3188 return StatsManager.PULL_SKIP;
3189 }
3190
3191 StatsEvent e = StatsEvent.newBuilder()
3192 .setAtomId(atomTag)
3193 .writeString(tzDbVersion)
3194 .build();
3195 pulledData.add(e);
3196 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003197 }
3198
3199 private void registerExternalStorageInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003200 int tagId = FrameworkStatsLog.EXTERNAL_STORAGE_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08003201 mStatsManager.setPullAtomCallback(
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08003202 tagId,
3203 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003204 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003205 mStatsCallbackImpl
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08003206 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003207 }
3208
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003209 int pullExternalStorageInfoLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08003210 if (mStorageManager == null) {
3211 return StatsManager.PULL_SKIP;
3212 }
3213
3214 List<VolumeInfo> volumes = mStorageManager.getVolumes();
3215 for (VolumeInfo vol : volumes) {
3216 final String envState = VolumeInfo.getEnvironmentForState(vol.getState());
3217 final DiskInfo diskInfo = vol.getDisk();
3218 if (diskInfo != null && envState.equals(Environment.MEDIA_MOUNTED)) {
3219 // Get the type of the volume, if it is adoptable or portable.
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003220 int volumeType = FrameworkStatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__OTHER;
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08003221 if (vol.getType() == TYPE_PUBLIC) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003222 volumeType = FrameworkStatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PUBLIC;
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08003223 } else if (vol.getType() == TYPE_PRIVATE) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003224 volumeType = FrameworkStatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PRIVATE;
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08003225 }
3226
3227 // Get the type of external storage inserted in the device (sd cards, usb, etc.)
3228 int externalStorageType;
3229 if (diskInfo.isSd()) {
3230 externalStorageType = StorageEnums.SD_CARD;
3231 } else if (diskInfo.isUsb()) {
3232 externalStorageType = StorageEnums.USB;
3233 } else {
3234 externalStorageType = StorageEnums.OTHER;
3235 }
3236
3237 StatsEvent e = StatsEvent.newBuilder()
3238 .setAtomId(atomTag)
3239 .writeInt(externalStorageType)
3240 .writeInt(volumeType)
3241 .writeLong(diskInfo.size)
3242 .build();
3243 pulledData.add(e);
3244 }
3245 }
3246 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003247 }
3248
3249 private void registerAppsOnExternalStorageInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003250 int tagId = FrameworkStatsLog.APPS_ON_EXTERNAL_STORAGE_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08003251 mStatsManager.setPullAtomCallback(
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08003252 tagId,
3253 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003254 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003255 mStatsCallbackImpl
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08003256 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003257 }
3258
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003259 int pullAppsOnExternalStorageInfoLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08003260 if (mStorageManager == null) {
3261 return StatsManager.PULL_SKIP;
3262 }
3263
3264 PackageManager pm = mContext.getPackageManager();
3265 List<ApplicationInfo> apps = pm.getInstalledApplications(/*flags=*/ 0);
3266 for (ApplicationInfo appInfo : apps) {
3267 UUID storageUuid = appInfo.storageUuid;
3268 if (storageUuid == null) {
3269 continue;
3270 }
3271
3272 VolumeInfo volumeInfo = mStorageManager.findVolumeByUuid(
3273 appInfo.storageUuid.toString());
3274 if (volumeInfo == null) {
3275 continue;
3276 }
3277
3278 DiskInfo diskInfo = volumeInfo.getDisk();
3279 if (diskInfo == null) {
3280 continue;
3281 }
3282
3283 int externalStorageType = -1;
3284 if (diskInfo.isSd()) {
3285 externalStorageType = StorageEnums.SD_CARD;
3286 } else if (diskInfo.isUsb()) {
3287 externalStorageType = StorageEnums.USB;
3288 } else if (appInfo.isExternal()) {
3289 externalStorageType = StorageEnums.OTHER;
3290 }
3291
3292 // App is installed on external storage.
3293 if (externalStorageType != -1) {
3294 StatsEvent e = StatsEvent.newBuilder()
3295 .setAtomId(atomTag)
3296 .writeInt(externalStorageType)
3297 .writeString(appInfo.packageName)
3298 .build();
3299 pulledData.add(e);
3300 }
3301 }
3302 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003303 }
3304
3305 private void registerFaceSettings() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003306 int tagId = FrameworkStatsLog.FACE_SETTINGS;
Tej Singh72a70a82020-02-26 23:46:29 -08003307 mStatsManager.setPullAtomCallback(
Ruchir Rastogi329c7672020-01-17 15:33:05 -08003308 tagId,
3309 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003310 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003311 mStatsCallbackImpl
Ruchir Rastogi329c7672020-01-17 15:33:05 -08003312 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003313 }
3314
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003315 int pullFaceSettingsLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi329c7672020-01-17 15:33:05 -08003316 final long callingToken = Binder.clearCallingIdentity();
3317 try {
3318 List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
3319 int numUsers = users.size();
3320 for (int userNum = 0; userNum < numUsers; userNum++) {
3321 int userId = users.get(userNum).getUserHandle().getIdentifier();
3322
3323 int unlockKeyguardEnabled = Settings.Secure.getIntForUser(
3324 mContext.getContentResolver(),
3325 Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED, 1, userId);
3326 int unlockDismissesKeyguard = Settings.Secure.getIntForUser(
3327 mContext.getContentResolver(),
3328 Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, 0, userId);
3329 int unlockAttentionRequired = Settings.Secure.getIntForUser(
3330 mContext.getContentResolver(),
3331 Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED, 1, userId);
3332 int unlockAppEnabled = Settings.Secure.getIntForUser(
3333 mContext.getContentResolver(),
3334 Settings.Secure.FACE_UNLOCK_APP_ENABLED, 1, userId);
3335 int unlockAlwaysRequireConfirmation = Settings.Secure.getIntForUser(
3336 mContext.getContentResolver(),
3337 Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, 0, userId);
3338 int unlockDiversityRequired = Settings.Secure.getIntForUser(
3339 mContext.getContentResolver(),
3340 Settings.Secure.FACE_UNLOCK_DIVERSITY_REQUIRED, 1, userId);
3341
3342 StatsEvent e = StatsEvent.newBuilder()
3343 .setAtomId(atomTag)
3344 .writeBoolean(unlockKeyguardEnabled != 0)
3345 .writeBoolean(unlockDismissesKeyguard != 0)
3346 .writeBoolean(unlockAttentionRequired != 0)
3347 .writeBoolean(unlockAppEnabled != 0)
3348 .writeBoolean(unlockAlwaysRequireConfirmation != 0)
3349 .writeBoolean(unlockDiversityRequired != 0)
3350 .build();
3351 pulledData.add(e);
3352 }
3353 } finally {
3354 Binder.restoreCallingIdentity(callingToken);
3355 }
3356 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003357 }
3358
3359 private void registerAppOps() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003360 int tagId = FrameworkStatsLog.APP_OPS;
Tej Singh72a70a82020-02-26 23:46:29 -08003361 mStatsManager.setPullAtomCallback(
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08003362 tagId,
3363 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003364 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003365 mStatsCallbackImpl
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08003366 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003367 }
3368
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003369 private void registerRuntimeAppOpAccessMessage() {
3370 int tagId = FrameworkStatsLog.RUNTIME_APP_OP_ACCESS;
Tej Singh72a70a82020-02-26 23:46:29 -08003371 mStatsManager.setPullAtomCallback(
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003372 tagId,
3373 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003374 DIRECT_EXECUTOR,
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003375 mStatsCallbackImpl
3376 );
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003377 }
3378
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003379 private class AppOpEntry {
3380 public final String mPackageName;
3381 public final String mAttributionTag;
3382 public final int mUid;
3383 public final HistoricalOp mOp;
3384 public final int mHash;
3385
3386 AppOpEntry(String packageName, @Nullable String attributionTag, HistoricalOp op, int uid) {
3387 mPackageName = packageName;
3388 mAttributionTag = attributionTag;
3389 mUid = uid;
3390 mOp = op;
3391 mHash = ((op.getOpCode() * 961
3392 + (attributionTag == null ? 0 : attributionTag.hashCode()) * 31
3393 + packageName.hashCode() + RANDOM_SEED) & 0x7fffffff) % 100;
3394 }
3395 }
3396
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003397 int pullAppOpsLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08003398 final long token = Binder.clearCallingIdentity();
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08003399 try {
3400 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
3401
3402 CompletableFuture<HistoricalOps> ops = new CompletableFuture<>();
Stanislav Zholnin050abc32020-02-17 14:14:52 +00003403 HistoricalOpsRequest histOpsRequest = new HistoricalOpsRequest.Builder(0,
3404 Long.MAX_VALUE).setFlags(OP_FLAGS_PULLED).build();
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003405 appOps.getHistoricalOps(histOpsRequest, AsyncTask.THREAD_POOL_EXECUTOR, ops::complete);
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08003406 HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
3407 TimeUnit.MILLISECONDS);
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003408
3409 List<AppOpEntry> opsList = processHistoricalOps(histOps, atomTag, 100);
3410 int samplingRate = sampleAppOps(pulledData, opsList, atomTag, 100);
3411 if (samplingRate != 100) {
3412 Slog.e(TAG, "Atom 10060 downsampled - too many dimensions");
3413 }
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08003414 } catch (Throwable t) {
3415 // TODO: catch exceptions at a more granular level
3416 Slog.e(TAG, "Could not read appops", t);
3417 return StatsManager.PULL_SKIP;
3418 } finally {
3419 Binder.restoreCallingIdentity(token);
3420 }
3421 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003422 }
3423
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003424 private int sampleAppOps(List<StatsEvent> pulledData, List<AppOpEntry> opsList, int atomTag,
3425 int samplingRate) {
3426 int nOps = opsList.size();
3427 for (int i = 0; i < nOps; i++) {
3428 AppOpEntry entry = opsList.get(i);
3429 if (entry.mHash >= samplingRate) {
3430 continue;
3431 }
3432 StatsEvent.Builder e = StatsEvent.newBuilder();
3433 e.setAtomId(atomTag);
3434 e.writeInt(entry.mUid);
3435 e.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
3436 e.writeString(entry.mPackageName);
3437 if (atomTag == FrameworkStatsLog.ATTRIBUTED_APP_OPS) {
3438 e.writeString(entry.mAttributionTag);
3439 }
3440 e.writeInt(entry.mOp.getOpCode());
3441 e.writeLong(entry.mOp.getForegroundAccessCount(OP_FLAGS_PULLED));
3442 e.writeLong(entry.mOp.getBackgroundAccessCount(OP_FLAGS_PULLED));
3443 e.writeLong(entry.mOp.getForegroundRejectCount(OP_FLAGS_PULLED));
3444 e.writeLong(entry.mOp.getBackgroundRejectCount(OP_FLAGS_PULLED));
3445 e.writeLong(entry.mOp.getForegroundAccessDuration(OP_FLAGS_PULLED));
3446 e.writeLong(entry.mOp.getBackgroundAccessDuration(OP_FLAGS_PULLED));
3447 e.writeBoolean(mDangerousAppOpsList.contains(entry.mOp.getOpCode()));
3448
3449 if (atomTag == FrameworkStatsLog.ATTRIBUTED_APP_OPS) {
3450 e.writeInt(samplingRate);
3451 }
3452 pulledData.add(e.build());
3453 }
3454 if (pulledData.size() > DIMENSION_KEY_SIZE_HARD_LIMIT) {
3455 int adjustedSamplingRate = constrain(
3456 samplingRate * DIMENSION_KEY_SIZE_SOFT_LIMIT / pulledData.size(), 0,
3457 samplingRate - 1);
3458 pulledData.clear();
3459 return sampleAppOps(pulledData, opsList, atomTag, adjustedSamplingRate);
3460 }
3461 return samplingRate;
3462 }
3463
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003464 private void registerAttributedAppOps() {
3465 int tagId = FrameworkStatsLog.ATTRIBUTED_APP_OPS;
Tej Singh72a70a82020-02-26 23:46:29 -08003466 mStatsManager.setPullAtomCallback(
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00003467 tagId,
3468 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003469 DIRECT_EXECUTOR,
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00003470 mStatsCallbackImpl
3471 );
3472 }
3473
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003474 int pullAttributedAppOpsLocked(int atomTag, List<StatsEvent> pulledData) {
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00003475 final long token = Binder.clearCallingIdentity();
3476 try {
3477 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00003478 CompletableFuture<HistoricalOps> ops = new CompletableFuture<>();
3479 HistoricalOpsRequest histOpsRequest =
3480 new HistoricalOpsRequest.Builder(0, Long.MAX_VALUE).setFlags(
3481 OP_FLAGS_PULLED).build();
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003482
3483 appOps.getHistoricalOps(histOpsRequest, AsyncTask.THREAD_POOL_EXECUTOR, ops::complete);
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00003484 HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
3485 TimeUnit.MILLISECONDS);
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003486
Stanislav Zholninba94e3b2020-06-19 16:43:47 +01003487 if (mAppOpsSamplingRate == 0) {
3488 mContext.getMainThreadHandler().postDelayed(new Runnable() {
3489 @Override
3490 public void run() {
3491 try {
3492 estimateAppOpsSamplingRate();
3493 } catch (Throwable e) {
3494 Slog.e(TAG, "AppOps sampling ratio estimation failed: ", e);
3495 synchronized (mAttributedAppOpsLock) {
3496 mAppOpsSamplingRate = min(mAppOpsSamplingRate, 10);
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003497 }
3498 }
Stanislav Zholninba94e3b2020-06-19 16:43:47 +01003499 }
3500 }, APP_OPS_SAMPLING_INITIALIZATION_DELAY_MILLIS);
3501 mAppOpsSamplingRate = 100;
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00003502 }
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003503
3504 List<AppOpEntry> opsList =
3505 processHistoricalOps(histOps, atomTag, mAppOpsSamplingRate);
3506
3507 int newSamplingRate = sampleAppOps(pulledData, opsList, atomTag, mAppOpsSamplingRate);
3508
Stanislav Zholninba94e3b2020-06-19 16:43:47 +01003509 mAppOpsSamplingRate = min(mAppOpsSamplingRate, newSamplingRate);
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00003510 } catch (Throwable t) {
3511 // TODO: catch exceptions at a more granular level
3512 Slog.e(TAG, "Could not read appops", t);
3513 return StatsManager.PULL_SKIP;
3514 } finally {
3515 Binder.restoreCallingIdentity(token);
3516 }
3517 return StatsManager.PULL_SUCCESS;
3518 }
3519
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003520 private void estimateAppOpsSamplingRate() throws Exception {
3521 int appOpsTargetCollectionSize = DeviceConfig.getInt(
3522 DeviceConfig.NAMESPACE_PERMISSIONS, APP_OPS_TARGET_COLLECTION_SIZE,
3523 APP_OPS_SIZE_ESTIMATE);
Stanislav Zholnin59199132020-03-06 14:19:25 +00003524 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
3525
3526 CompletableFuture<HistoricalOps> ops = new CompletableFuture<>();
3527 HistoricalOpsRequest histOpsRequest =
3528 new HistoricalOpsRequest.Builder(
Hai Zhang4d0bf0f2020-06-08 16:42:53 -07003529 Math.max(Instant.now().minus(1, ChronoUnit.DAYS).toEpochMilli(), 0),
Stanislav Zholnin59199132020-03-06 14:19:25 +00003530 Long.MAX_VALUE).setFlags(
3531 OP_FLAGS_PULLED).build();
Stanislav Zholnin74b048a2020-05-31 13:17:16 +01003532 appOps.getHistoricalOps(histOpsRequest, AsyncTask.THREAD_POOL_EXECUTOR, ops::complete);
Stanislav Zholnin59199132020-03-06 14:19:25 +00003533 HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
3534 TimeUnit.MILLISECONDS);
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003535 List<AppOpEntry> opsList =
3536 processHistoricalOps(histOps, FrameworkStatsLog.ATTRIBUTED_APP_OPS, 100);
3537
3538 long estimatedSize = 0;
3539 int nOps = opsList.size();
3540 for (int i = 0; i < nOps; i++) {
3541 AppOpEntry entry = opsList.get(i);
3542 estimatedSize += 32 + entry.mPackageName.length() + (entry.mAttributionTag == null ? 1
3543 : entry.mAttributionTag.length());
3544
3545 }
3546 int estimatedSamplingRate = (int) constrain(
3547 appOpsTargetCollectionSize * 100 / estimatedSize, 0, 100);
Stanislav Zholninba94e3b2020-06-19 16:43:47 +01003548 synchronized (mAttributedAppOpsLock) {
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003549 mAppOpsSamplingRate = min(mAppOpsSamplingRate, estimatedSamplingRate);
3550 }
Stanislav Zholnin59199132020-03-06 14:19:25 +00003551 }
3552
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003553 private List<AppOpEntry> processHistoricalOps(
3554 HistoricalOps histOps, int atomTag, int samplingRatio) {
3555 List<AppOpEntry> opsList = new ArrayList<>();
Stanislav Zholnin59199132020-03-06 14:19:25 +00003556 for (int uidIdx = 0; uidIdx < histOps.getUidCount(); uidIdx++) {
3557 final HistoricalUidOps uidOps = histOps.getUidOpsAt(uidIdx);
3558 final int uid = uidOps.getUid();
3559 for (int pkgIdx = 0; pkgIdx < uidOps.getPackageCount(); pkgIdx++) {
3560 final HistoricalPackageOps packageOps = uidOps.getPackageOpsAt(pkgIdx);
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003561 if (atomTag == FrameworkStatsLog.ATTRIBUTED_APP_OPS) {
3562 for (int attributionIdx = 0;
3563 attributionIdx < packageOps.getAttributedOpsCount(); attributionIdx++) {
3564 final AppOpsManager.AttributedHistoricalOps attributedOps =
3565 packageOps.getAttributedOpsAt(attributionIdx);
3566 for (int opIdx = 0; opIdx < attributedOps.getOpCount(); opIdx++) {
3567 final AppOpsManager.HistoricalOp op = attributedOps.getOpAt(opIdx);
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003568 processHistoricalOp(op, opsList, uid, samplingRatio,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003569 packageOps.getPackageName(), attributedOps.getTag());
Stanislav Zholnin59199132020-03-06 14:19:25 +00003570 }
3571 }
3572 } else if (atomTag == FrameworkStatsLog.APP_OPS) {
3573 for (int opIdx = 0; opIdx < packageOps.getOpCount(); opIdx++) {
3574 final AppOpsManager.HistoricalOp op = packageOps.getOpAt(opIdx);
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003575 processHistoricalOp(op, opsList, uid, samplingRatio,
Stanislav Zholnin59199132020-03-06 14:19:25 +00003576 packageOps.getPackageName(), null);
3577 }
3578 }
3579 }
3580 }
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003581 return opsList;
Stanislav Zholnin59199132020-03-06 14:19:25 +00003582 }
3583
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003584 private void processHistoricalOp(AppOpsManager.HistoricalOp op,
3585 List<AppOpEntry> opsList, int uid, int samplingRatio, String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003586 @Nullable String attributionTag) {
Stanislav Zholnin044b1792020-06-03 17:53:53 +01003587 int firstChar = 0;
3588 if (attributionTag != null && attributionTag.startsWith(packageName)) {
3589 firstChar = packageName.length();
3590 if (firstChar < attributionTag.length() && attributionTag.charAt(firstChar) == '.') {
3591 firstChar++;
3592 }
3593 }
3594 AppOpEntry entry = new AppOpEntry(packageName,
3595 attributionTag == null ? null : attributionTag.substring(firstChar), op,
3596 uid);
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003597 if (entry.mHash < samplingRatio) {
3598 opsList.add(entry);
Stanislav Zholnin59199132020-03-06 14:19:25 +00003599 }
Stanislav Zholnin59199132020-03-06 14:19:25 +00003600 }
3601
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003602 int pullRuntimeAppOpAccessMessageLocked(int atomTag, List<StatsEvent> pulledData) {
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003603 final long token = Binder.clearCallingIdentity();
3604 try {
3605 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
3606
3607 RuntimeAppOpAccessMessage message = appOps.collectRuntimeAppOpAccessMessage();
3608 if (message == null) {
3609 Slog.i(TAG, "No runtime appop access message collected");
3610 return StatsManager.PULL_SUCCESS;
3611 }
3612
3613 StatsEvent.Builder e = StatsEvent.newBuilder();
3614 e.setAtomId(atomTag);
3615 e.writeInt(message.getUid());
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07003616 e.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003617 e.writeString(message.getPackageName());
Stanislav Zholnin3a2a6e42020-03-30 10:44:51 +01003618 e.writeString("");
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003619 if (message.getAttributionTag() == null) {
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003620 e.writeString("");
3621 } else {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003622 e.writeString(message.getAttributionTag());
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003623 }
3624 e.writeString(message.getMessage());
3625 e.writeInt(message.getSamplingStrategy());
Stanislav Zholnin3a2a6e42020-03-30 10:44:51 +01003626 e.writeInt(AppOpsManager.strOpToOp(message.getOp()));
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003627
3628 pulledData.add(e.build());
3629 } catch (Throwable t) {
3630 // TODO: catch exceptions at a more granular level
3631 Slog.e(TAG, "Could not read runtime appop access message", t);
3632 return StatsManager.PULL_SKIP;
3633 } finally {
3634 Binder.restoreCallingIdentity(token);
3635 }
3636 return StatsManager.PULL_SUCCESS;
3637 }
3638
Jeffrey Huang730bf962020-01-16 15:59:52 -08003639 static void unpackStreamedData(int atomTag, List<StatsEvent> pulledData,
3640 List<ParcelFileDescriptor> statsFiles) throws IOException {
3641 InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(statsFiles.get(0));
3642 int[] len = new int[1];
3643 byte[] stats = readFully(stream, len);
3644 StatsEvent e = StatsEvent.newBuilder()
3645 .setAtomId(atomTag)
3646 .writeByteArray(Arrays.copyOf(stats, len[0]))
3647 .build();
3648 pulledData.add(e);
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003649 }
3650
Jeffrey Huang730bf962020-01-16 15:59:52 -08003651 static byte[] readFully(InputStream stream, int[] outLen) throws IOException {
3652 int pos = 0;
3653 final int initialAvail = stream.available();
3654 byte[] data = new byte[initialAvail > 0 ? (initialAvail + 1) : 16384];
3655 while (true) {
3656 int amt = stream.read(data, pos, data.length - pos);
3657 if (DEBUG) {
3658 Slog.i(TAG, "Read " + amt + " bytes at " + pos + " of avail " + data.length);
3659 }
3660 if (amt < 0) {
3661 if (DEBUG) {
3662 Slog.i(TAG, "**** FINISHED READING: pos=" + pos + " len=" + data.length);
3663 }
3664 outLen[0] = pos;
3665 return data;
3666 }
3667 pos += amt;
3668 if (pos >= data.length) {
3669 byte[] newData = new byte[pos + 16384];
3670 if (DEBUG) {
3671 Slog.i(TAG, "Copying " + pos + " bytes to new array len " + newData.length);
3672 }
3673 System.arraycopy(data, 0, newData, 0, pos);
3674 data = newData;
3675 }
3676 }
3677 }
3678
3679 private void registerNotificationRemoteViews() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003680 int tagId = FrameworkStatsLog.NOTIFICATION_REMOTE_VIEWS;
Tej Singh72a70a82020-02-26 23:46:29 -08003681 mStatsManager.setPullAtomCallback(
Jeffrey Huang730bf962020-01-16 15:59:52 -08003682 tagId,
3683 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003684 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003685 mStatsCallbackImpl
Jeffrey Huang730bf962020-01-16 15:59:52 -08003686 );
3687 }
3688
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003689 int pullNotificationRemoteViewsLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang730bf962020-01-16 15:59:52 -08003690 INotificationManager notificationManagerService = getINotificationManagerService();
3691 if (notificationManagerService == null) {
3692 return StatsManager.PULL_SKIP;
3693 }
3694 final long callingToken = Binder.clearCallingIdentity();
3695 try {
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08003696 // determine last pull tine. Copy file trick from pullProcStats?
Jeffrey Huang730bf962020-01-16 15:59:52 -08003697 long wallClockNanos = SystemClock.currentTimeMicro() * 1000L;
3698 long lastNotificationStatsNs = wallClockNanos -
3699 TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS);
3700
3701 List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
3702 notificationManagerService.pullStats(lastNotificationStatsNs,
3703 NotificationManagerService.REPORT_REMOTE_VIEWS, true, statsFiles);
3704 if (statsFiles.size() != 1) {
3705 return StatsManager.PULL_SKIP;
3706 }
3707 unpackStreamedData(atomTag, pulledData, statsFiles);
3708 } catch (IOException e) {
3709 Slog.e(TAG, "Getting notistats failed: ", e);
3710 return StatsManager.PULL_SKIP;
3711 } catch (RemoteException e) {
3712 Slog.e(TAG, "Getting notistats failed: ", e);
3713 return StatsManager.PULL_SKIP;
3714 } catch (SecurityException e) {
3715 Slog.e(TAG, "Getting notistats failed: ", e);
3716 return StatsManager.PULL_SKIP;
3717 } finally {
3718 Binder.restoreCallingIdentity(callingToken);
3719 }
3720 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003721 }
3722
3723 private void registerDangerousPermissionStateSampled() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003724 int tagId = FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED;
Tej Singh72a70a82020-02-26 23:46:29 -08003725 mStatsManager.setPullAtomCallback(
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003726 tagId,
3727 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003728 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003729 mStatsCallbackImpl
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003730 );
Tej Singh953ad862020-01-03 12:47:07 -08003731 }
Jeffrey Huangbf130832020-01-22 15:48:26 -08003732
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003733 private void registerBatteryLevel() {
3734 int tagId = FrameworkStatsLog.BATTERY_LEVEL;
Tej Singh72a70a82020-02-26 23:46:29 -08003735 mStatsManager.setPullAtomCallback(
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003736 tagId,
3737 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003738 DIRECT_EXECUTOR,
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003739 mStatsCallbackImpl
3740 );
3741 }
3742
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003743 private void registerRemainingBatteryCapacity() {
3744 int tagId = FrameworkStatsLog.REMAINING_BATTERY_CAPACITY;
Tej Singh72a70a82020-02-26 23:46:29 -08003745 mStatsManager.setPullAtomCallback(
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003746 tagId,
3747 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003748 DIRECT_EXECUTOR,
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003749 mStatsCallbackImpl
3750 );
3751 }
3752
3753 private void registerFullBatteryCapacity() {
3754 int tagId = FrameworkStatsLog.FULL_BATTERY_CAPACITY;
Tej Singh72a70a82020-02-26 23:46:29 -08003755 mStatsManager.setPullAtomCallback(
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003756 tagId,
3757 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003758 DIRECT_EXECUTOR,
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003759 mStatsCallbackImpl
3760 );
3761 }
3762
3763 private void registerBatteryVoltage() {
3764 int tagId = FrameworkStatsLog.BATTERY_VOLTAGE;
Tej Singh72a70a82020-02-26 23:46:29 -08003765 mStatsManager.setPullAtomCallback(
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003766 tagId,
3767 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003768 DIRECT_EXECUTOR,
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003769 mStatsCallbackImpl
3770 );
3771 }
3772
3773 private void registerBatteryCycleCount() {
3774 int tagId = FrameworkStatsLog.BATTERY_CYCLE_COUNT;
Tej Singh72a70a82020-02-26 23:46:29 -08003775 mStatsManager.setPullAtomCallback(
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003776 tagId,
3777 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003778 DIRECT_EXECUTOR,
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003779 mStatsCallbackImpl
3780 );
3781 }
3782
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003783 int pullHealthHalLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003784 IHealth healthService = mHealthService.getLastService();
3785 if (healthService == null) {
3786 return StatsManager.PULL_SKIP;
3787 }
3788 try {
3789 healthService.getHealthInfo((result, value) -> {
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003790 int pulledValue;
3791 switch(atomTag) {
3792 case FrameworkStatsLog.BATTERY_LEVEL:
3793 pulledValue = value.legacy.batteryLevel;
3794 break;
3795 case FrameworkStatsLog.REMAINING_BATTERY_CAPACITY:
3796 pulledValue = value.legacy.batteryChargeCounter;
3797 break;
3798 case FrameworkStatsLog.FULL_BATTERY_CAPACITY:
3799 pulledValue = value.legacy.batteryFullCharge;
3800 break;
3801 case FrameworkStatsLog.BATTERY_VOLTAGE:
3802 pulledValue = value.legacy.batteryVoltage;
3803 break;
3804 case FrameworkStatsLog.BATTERY_CYCLE_COUNT:
3805 pulledValue = value.legacy.batteryCycleCount;
3806 break;
3807 default:
3808 throw new IllegalStateException("Invalid atomTag in healthHal puller: "
3809 + atomTag);
3810 }
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003811 StatsEvent e = StatsEvent.newBuilder()
3812 .setAtomId(atomTag)
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003813 .writeInt(pulledValue)
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003814 .build();
3815 pulledData.add(e);
3816 });
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003817 } catch (RemoteException | IllegalStateException e) {
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003818 return StatsManager.PULL_SKIP;
3819 }
3820 return StatsManager.PULL_SUCCESS;
3821 }
Jeffrey Huangbf130832020-01-22 15:48:26 -08003822
Raff Tsai87cefd42020-04-07 14:25:02 +08003823 private void registerSettingsStats() {
3824 int tagId = FrameworkStatsLog.SETTING_SNAPSHOT;
3825 mStatsManager.setPullAtomCallback(
3826 tagId,
3827 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003828 DIRECT_EXECUTOR,
Raff Tsai87cefd42020-04-07 14:25:02 +08003829 mStatsCallbackImpl
3830 );
3831 }
3832
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003833 int pullSettingsStatsLocked(int atomTag, List<StatsEvent> pulledData) {
Raff Tsai87cefd42020-04-07 14:25:02 +08003834 UserManager userManager = mContext.getSystemService(UserManager.class);
3835 if (userManager == null) {
3836 return StatsManager.PULL_SKIP;
3837 }
3838
3839 final long token = Binder.clearCallingIdentity();
3840 try {
3841 for (UserInfo user : userManager.getUsers()) {
3842 final int userId = user.getUserHandle().getIdentifier();
3843
3844 if (userId == UserHandle.USER_SYSTEM) {
3845 pulledData.addAll(SettingsStatsUtil.logGlobalSettings(mContext, atomTag,
3846 UserHandle.USER_SYSTEM));
3847 }
3848 pulledData.addAll(SettingsStatsUtil.logSystemSettings(mContext, atomTag, userId));
3849 pulledData.addAll(SettingsStatsUtil.logSecureSettings(mContext, atomTag, userId));
3850 }
3851 } catch (Exception e) {
3852 Slog.e(TAG, "failed to pullSettingsStats", e);
3853 return StatsManager.PULL_SKIP;
3854 } finally {
3855 Binder.restoreCallingIdentity(token);
3856 }
3857 return StatsManager.PULL_SUCCESS;
3858 }
3859
Jeffrey Huangbf130832020-01-22 15:48:26 -08003860 // Thermal event received from vendor thermal management subsystem
3861 private static final class ThermalEventListener extends IThermalEventListener.Stub {
3862 @Override
3863 public void notifyThrottling(Temperature temp) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003864 FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_THROTTLING_SEVERITY_STATE_CHANGED,
3865 temp.getType(), temp.getName(), (int) (temp.getValue() * 10), temp.getStatus());
Jeffrey Huangbf130832020-01-22 15:48:26 -08003866 }
3867 }
3868
3869 private static final class ConnectivityStatsCallback extends
3870 ConnectivityManager.NetworkCallback {
3871 @Override
3872 public void onAvailable(Network network) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003873 FrameworkStatsLog.write(FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED, network.netId,
3874 FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED__STATE__CONNECTED);
Jeffrey Huangbf130832020-01-22 15:48:26 -08003875 }
3876
3877 @Override
3878 public void onLost(Network network) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003879 FrameworkStatsLog.write(FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED, network.netId,
3880 FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED__STATE__DISCONNECTED);
Jeffrey Huangbf130832020-01-22 15:48:26 -08003881 }
3882 }
junyulaiaa31d3c2020-04-10 15:11:54 +08003883
3884 private final class StatsSubscriptionsListener
3885 extends SubscriptionManager.OnSubscriptionsChangedListener {
3886 @NonNull
3887 private final SubscriptionManager mSm;
3888
3889 StatsSubscriptionsListener(@NonNull SubscriptionManager sm) {
3890 mSm = sm;
3891 }
3892
3893 @Override
3894 public void onSubscriptionsChanged() {
3895 final List<SubscriptionInfo> currentSubs = mSm.getCompleteActiveSubscriptionInfoList();
3896 for (final SubscriptionInfo sub : currentSubs) {
3897 final SubInfo match = CollectionUtils.find(mHistoricalSubs,
3898 (SubInfo it) -> it.subId == sub.getSubscriptionId());
3899 // SubInfo exists, ignore.
3900 if (match != null) continue;
3901
3902 // Ignore if no valid mcc, mnc, imsi, carrierId.
3903 final int subId = sub.getSubscriptionId();
3904 final String mcc = sub.getMccString();
3905 final String mnc = sub.getMncString();
3906 final String subscriberId = mTelephony.getSubscriberId(subId);
3907 if (TextUtils.isEmpty(subscriberId) || TextUtils.isEmpty(mcc)
3908 || TextUtils.isEmpty(mnc) || sub.getCarrierId() == UNKNOWN_CARRIER_ID) {
3909 Slog.e(TAG, "subInfo of subId " + subId + " is invalid, ignored.");
3910 continue;
3911 }
3912
3913 final SubInfo subInfo = new SubInfo(subId, sub.getCarrierId(), mcc, mnc,
3914 subscriberId, sub.isOpportunistic());
3915 Slog.i(TAG, "subId " + subId + " added into historical sub list");
junyulaiaa31d3c2020-04-10 15:11:54 +08003916
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003917 synchronized (mDataBytesTransferLock) {
3918 mHistoricalSubs.add(subInfo);
3919 // Since getting snapshot when pulling will also include data before boot,
3920 // query stats as baseline to prevent double count is needed.
3921 mNetworkStatsBaselines.addAll(getDataUsageBytesTransferSnapshotForSub(subInfo));
3922 }
junyulaiaa31d3c2020-04-10 15:11:54 +08003923 }
3924 }
3925 }
3926
Tej Singh953ad862020-01-03 12:47:07 -08003927}