blob: 802a35560ba57cfd0176f3e9c9a1f97d7f6813e7 [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;
215 private static final int APP_OPS_SIZE_ESTIMATE = 5000;
216
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 Zholnin841c9ab2020-05-24 04:56:18 +0100323 private final Object mAppOpsSamplingRateLock = new Object();
324 @GuardedBy("mAppOpsSamplingRateLock")
Stanislav Zholnin59199132020-03-06 14:19:25 +0000325 private int mAppOpsSamplingRate = 0;
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700326 private final Object mDangerousAppOpsListLock = new Object();
327 @GuardedBy("mDangerousAppOpsListLock")
Stanislav Zholnine08a2bb2020-05-17 17:51:31 +0100328 private final ArraySet<Integer> mDangerousAppOpsList = new ArraySet<>();
Stanislav Zholnin59199132020-03-06 14:19:25 +0000329
junyulai39f15c82020-04-17 10:48:36 +0800330 // Baselines that stores list of NetworkStats right after initializing, with associated
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700331 // information. This is used to calculate difference when pulling BytesTransfer atoms.
junyulai39f15c82020-04-17 10:48:36 +0800332 @NonNull
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700333 @GuardedBy("mDataBytesTransferLock")
334 private final ArrayList<NetworkStatsExt> mNetworkStatsBaselines = new ArrayList<>();
junyulai39f15c82020-04-17 10:48:36 +0800335
junyulaiaa31d3c2020-04-10 15:11:54 +0800336 // Listener for monitoring subscriptions changed event.
337 private StatsSubscriptionsListener mStatsSubscriptionsListener;
junyulai66e735e2020-05-29 11:24:58 +0800338 // List that stores SubInfo of subscriptions that ever appeared since boot.
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700339 @GuardedBy("mDataBytesTransferLock")
340 private final ArrayList<SubInfo> mHistoricalSubs = new ArrayList<>();
341
342 // Puller locks
343 private final Object mDataBytesTransferLock = new Object();
344 private final Object mBluetoothBytesTransferLock = new Object();
345 private final Object mKernelWakelockLock = new Object();
346 private final Object mCpuTimePerFreqLock = new Object();
347 private final Object mCpuTimePerUidLock = new Object();
348 private final Object mCpuTimePerUidFreqLock = new Object();
349 private final Object mCpuActiveTimeLock = new Object();
350 private final Object mCpuClusterTimeLock = new Object();
351 private final Object mWifiActivityInfoLock = new Object();
352 private final Object mModemActivityInfoLock = new Object();
353 private final Object mBluetoothActivityInfoLock = new Object();
354 private final Object mSystemElapsedRealtimeLock = new Object();
355 private final Object mSystemUptimeLock = new Object();
356 private final Object mProcessMemoryStateLock = new Object();
357 private final Object mProcessMemoryHighWaterMarkLock = new Object();
358 private final Object mProcessMemorySnapshotLock = new Object();
359 private final Object mSystemIonHeapSizeLock = new Object();
360 private final Object mIonHeapSizeLock = new Object();
361 private final Object mProcessSystemIonHeapSizeLock = new Object();
362 private final Object mTemperatureLock = new Object();
363 private final Object mCooldownDeviceLock = new Object();
364 private final Object mBinderCallsStatsLock = new Object();
365 private final Object mBinderCallsStatsExceptionsLock = new Object();
366 private final Object mLooperStatsLock = new Object();
367 private final Object mDiskStatsLock = new Object();
368 private final Object mDirectoryUsageLock = new Object();
369 private final Object mAppSizeLock = new Object();
370 private final Object mCategorySizeLock = new Object();
371 private final Object mNumBiometricsEnrolledLock = new Object();
372 private final Object mProcStatsLock = new Object();
373 private final Object mDiskIoLock = new Object();
374 private final Object mPowerProfileLock = new Object();
375 private final Object mProcessCpuTimeLock = new Object();
376 private final Object mCpuTimePerThreadFreqLock = new Object();
377 private final Object mDeviceCalculatedPowerUseLock = new Object();
378 private final Object mDeviceCalculatedPowerBlameUidLock = new Object();
379 private final Object mDeviceCalculatedPowerBlameOtherLock = new Object();
380 private final Object mDebugElapsedClockLock = new Object();
381 private final Object mDebugFailingElapsedClockLock = new Object();
382 private final Object mBuildInformationLock = new Object();
383 private final Object mRoleHolderLock = new Object();
384 private final Object mTimeZoneDataInfoLock = new Object();
385 private final Object mExternalStorageInfoLock = new Object();
386 private final Object mAppsOnExternalStorageInfoLock = new Object();
387 private final Object mFaceSettingsLock = new Object();
388 private final Object mAppOpsLock = new Object();
389 private final Object mRuntimeAppOpAccessMessageLock = new Object();
390 private final Object mNotificationRemoteViewsLock = new Object();
391 private final Object mDangerousPermissionStateLock = new Object();
392 private final Object mHealthHalLock = new Object();
393 private final Object mAttributedAppOpsLock = new Object();
394 private final Object mSettingsStatsLock = new Object();
junyulaiaa31d3c2020-04-10 15:11:54 +0800395
Tej Singh953ad862020-01-03 12:47:07 -0800396 public StatsPullAtomService(Context context) {
397 super(context);
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800398 mContext = context;
Tej Singh953ad862020-01-03 12:47:07 -0800399 }
400
Jeffrey Huang4c527162020-01-30 17:53:13 -0800401 private native void nativeInit();
402
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800403 /**
404 * Use of this StatsPullAtomCallbackImpl means we avoid one class per tagId, which we would
405 * get if we used lambdas.
406 *
407 * The pull methods are intentionally left to be package private to avoid the creation
408 * of synthetic methods to save unnecessary bytecode.
409 */
410 private class StatsPullAtomCallbackImpl implements StatsManager.StatsPullAtomCallback {
411 @Override
412 public int onPullAtom(int atomTag, List<StatsEvent> data) {
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000413 if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
414 Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StatsPull-" + atomTag);
415 }
416 try {
417 switch (atomTag) {
418 case FrameworkStatsLog.WIFI_BYTES_TRANSFER:
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000419 case FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG:
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000420 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER:
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000421 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG:
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -0700422 case FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED:
junyulaiee3ea792020-05-15 18:26:25 +0800423 case FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700424 synchronized (mDataBytesTransferLock) {
425 return pullDataBytesTransferLocked(atomTag, data);
426 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000427 case FrameworkStatsLog.BLUETOOTH_BYTES_TRANSFER:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700428 synchronized (mBluetoothBytesTransferLock) {
429 return pullBluetoothBytesTransferLocked(atomTag, data);
430 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000431 case FrameworkStatsLog.KERNEL_WAKELOCK:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700432 synchronized (mKernelWakelockLock) {
433 return pullKernelWakelockLocked(atomTag, data);
434 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000435 case FrameworkStatsLog.CPU_TIME_PER_FREQ:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700436 synchronized (mCpuTimePerFreqLock) {
437 return pullCpuTimePerFreqLocked(atomTag, data);
438 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000439 case FrameworkStatsLog.CPU_TIME_PER_UID:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700440 synchronized (mCpuTimePerUidLock) {
441 return pullCpuTimePerUidLocked(atomTag, data);
442 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000443 case FrameworkStatsLog.CPU_TIME_PER_UID_FREQ:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700444 synchronized (mCpuTimePerUidFreqLock) {
445 return pullCpuTimePerUidFreqLocked(atomTag, data);
446 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000447 case FrameworkStatsLog.CPU_ACTIVE_TIME:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700448 synchronized (mCpuActiveTimeLock) {
449 return pullCpuActiveTimeLocked(atomTag, data);
450 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000451 case FrameworkStatsLog.CPU_CLUSTER_TIME:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700452 synchronized (mCpuClusterTimeLock) {
453 return pullCpuClusterTimeLocked(atomTag, data);
454 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000455 case FrameworkStatsLog.WIFI_ACTIVITY_INFO:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700456 synchronized (mWifiActivityInfoLock) {
457 return pullWifiActivityInfoLocked(atomTag, data);
458 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000459 case FrameworkStatsLog.MODEM_ACTIVITY_INFO:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700460 synchronized (mModemActivityInfoLock) {
461 return pullModemActivityInfoLocked(atomTag, data);
462 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000463 case FrameworkStatsLog.BLUETOOTH_ACTIVITY_INFO:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700464 synchronized (mBluetoothActivityInfoLock) {
465 return pullBluetoothActivityInfoLocked(atomTag, data);
466 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000467 case FrameworkStatsLog.SYSTEM_ELAPSED_REALTIME:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700468 synchronized (mSystemElapsedRealtimeLock) {
469 return pullSystemElapsedRealtimeLocked(atomTag, data);
470 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000471 case FrameworkStatsLog.SYSTEM_UPTIME:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700472 synchronized (mSystemUptimeLock) {
473 return pullSystemUptimeLocked(atomTag, data);
474 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000475 case FrameworkStatsLog.PROCESS_MEMORY_STATE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700476 synchronized (mProcessMemoryStateLock) {
477 return pullProcessMemoryStateLocked(atomTag, data);
478 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000479 case FrameworkStatsLog.PROCESS_MEMORY_HIGH_WATER_MARK:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700480 synchronized (mProcessMemoryHighWaterMarkLock) {
481 return pullProcessMemoryHighWaterMarkLocked(atomTag, data);
482 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000483 case FrameworkStatsLog.PROCESS_MEMORY_SNAPSHOT:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700484 synchronized (mProcessMemorySnapshotLock) {
485 return pullProcessMemorySnapshotLocked(atomTag, data);
486 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000487 case FrameworkStatsLog.SYSTEM_ION_HEAP_SIZE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700488 synchronized (mSystemIonHeapSizeLock) {
489 return pullSystemIonHeapSizeLocked(atomTag, data);
490 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000491 case FrameworkStatsLog.ION_HEAP_SIZE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700492 synchronized (mIonHeapSizeLock) {
493 return pullIonHeapSizeLocked(atomTag, data);
494 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000495 case FrameworkStatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700496 synchronized (mProcessSystemIonHeapSizeLock) {
497 return pullProcessSystemIonHeapSizeLocked(atomTag, data);
498 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000499 case FrameworkStatsLog.TEMPERATURE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700500 synchronized (mTemperatureLock) {
501 return pullTemperatureLocked(atomTag, data);
502 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000503 case FrameworkStatsLog.COOLING_DEVICE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700504 synchronized (mCooldownDeviceLock) {
505 return pullCooldownDeviceLocked(atomTag, data);
506 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000507 case FrameworkStatsLog.BINDER_CALLS:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700508 synchronized (mBinderCallsStatsLock) {
509 return pullBinderCallsStatsLocked(atomTag, data);
510 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000511 case FrameworkStatsLog.BINDER_CALLS_EXCEPTIONS:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700512 synchronized (mBinderCallsStatsExceptionsLock) {
513 return pullBinderCallsStatsExceptionsLocked(atomTag, data);
514 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000515 case FrameworkStatsLog.LOOPER_STATS:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700516 synchronized (mLooperStatsLock) {
517 return pullLooperStatsLocked(atomTag, data);
518 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000519 case FrameworkStatsLog.DISK_STATS:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700520 synchronized (mDiskStatsLock) {
521 return pullDiskStatsLocked(atomTag, data);
522 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000523 case FrameworkStatsLog.DIRECTORY_USAGE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700524 synchronized (mDirectoryUsageLock) {
525 return pullDirectoryUsageLocked(atomTag, data);
526 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000527 case FrameworkStatsLog.APP_SIZE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700528 synchronized (mAppSizeLock) {
529 return pullAppSizeLocked(atomTag, data);
530 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000531 case FrameworkStatsLog.CATEGORY_SIZE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700532 synchronized (mCategorySizeLock) {
533 return pullCategorySizeLocked(atomTag, data);
534 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000535 case FrameworkStatsLog.NUM_FINGERPRINTS_ENROLLED:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700536 synchronized (mNumBiometricsEnrolledLock) {
537 return pullNumBiometricsEnrolledLocked(
538 BiometricsProtoEnums.MODALITY_FINGERPRINT, atomTag, data);
539 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000540 case FrameworkStatsLog.NUM_FACES_ENROLLED:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700541 synchronized (mNumBiometricsEnrolledLock) {
542 return pullNumBiometricsEnrolledLocked(
543 BiometricsProtoEnums.MODALITY_FACE, atomTag, data);
544 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000545 case FrameworkStatsLog.PROC_STATS:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700546 synchronized (mProcStatsLock) {
547 return pullProcStatsLocked(ProcessStats.REPORT_ALL, atomTag, data);
548 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000549 case FrameworkStatsLog.PROC_STATS_PKG_PROC:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700550 synchronized (mProcStatsLock) {
551 return pullProcStatsLocked(ProcessStats.REPORT_PKG_PROC_STATS, atomTag,
552 data);
553 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000554 case FrameworkStatsLog.DISK_IO:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700555 synchronized (mDiskIoLock) {
556 return pullDiskIOLocked(atomTag, data);
557 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000558 case FrameworkStatsLog.POWER_PROFILE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700559 synchronized (mPowerProfileLock) {
560 return pullPowerProfileLocked(atomTag, data);
561 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000562 case FrameworkStatsLog.PROCESS_CPU_TIME:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700563 synchronized (mProcessCpuTimeLock) {
564 return pullProcessCpuTimeLocked(atomTag, data);
565 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000566 case FrameworkStatsLog.CPU_TIME_PER_THREAD_FREQ:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700567 synchronized (mCpuTimePerThreadFreqLock) {
568 return pullCpuTimePerThreadFreqLocked(atomTag, data);
569 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000570 case FrameworkStatsLog.DEVICE_CALCULATED_POWER_USE:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700571 synchronized (mDeviceCalculatedPowerUseLock) {
572 return pullDeviceCalculatedPowerUseLocked(atomTag, data);
573 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000574 case FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_UID:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700575 synchronized (mDeviceCalculatedPowerBlameUidLock) {
576 return pullDeviceCalculatedPowerBlameUidLocked(atomTag, data);
577 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000578 case FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_OTHER:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700579 synchronized (mDeviceCalculatedPowerBlameOtherLock) {
580 return pullDeviceCalculatedPowerBlameOtherLocked(atomTag, data);
581 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000582 case FrameworkStatsLog.DEBUG_ELAPSED_CLOCK:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700583 synchronized (mDebugElapsedClockLock) {
584 return pullDebugElapsedClockLocked(atomTag, data);
585 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000586 case FrameworkStatsLog.DEBUG_FAILING_ELAPSED_CLOCK:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700587 synchronized (mDebugFailingElapsedClockLock) {
588 return pullDebugFailingElapsedClockLocked(atomTag, data);
589 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000590 case FrameworkStatsLog.BUILD_INFORMATION:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700591 synchronized (mBuildInformationLock) {
592 return pullBuildInformationLocked(atomTag, data);
593 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000594 case FrameworkStatsLog.ROLE_HOLDER:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700595 synchronized (mRoleHolderLock) {
596 return pullRoleHolderLocked(atomTag, data);
597 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000598 case FrameworkStatsLog.DANGEROUS_PERMISSION_STATE:
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000599 case FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700600 synchronized (mDangerousPermissionStateLock) {
601 return pullDangerousPermissionStateLocked(atomTag, data);
602 }
603 case FrameworkStatsLog.TIME_ZONE_DATA_INFO:
604 synchronized (mTimeZoneDataInfoLock) {
605 return pullTimeZoneDataInfoLocked(atomTag, data);
606 }
607 case FrameworkStatsLog.EXTERNAL_STORAGE_INFO:
608 synchronized (mExternalStorageInfoLock) {
609 return pullExternalStorageInfoLocked(atomTag, data);
610 }
611 case FrameworkStatsLog.APPS_ON_EXTERNAL_STORAGE_INFO:
612 synchronized (mAppsOnExternalStorageInfoLock) {
613 return pullAppsOnExternalStorageInfoLocked(atomTag, data);
614 }
615 case FrameworkStatsLog.FACE_SETTINGS:
616 synchronized (mFaceSettingsLock) {
617 return pullFaceSettingsLocked(atomTag, data);
618 }
619 case FrameworkStatsLog.APP_OPS:
620 synchronized (mAppOpsLock) {
621 return pullAppOpsLocked(atomTag, data);
622 }
623 case FrameworkStatsLog.RUNTIME_APP_OP_ACCESS:
624 synchronized (mRuntimeAppOpAccessMessageLock) {
625 return pullRuntimeAppOpAccessMessageLocked(atomTag, data);
626 }
627 case FrameworkStatsLog.NOTIFICATION_REMOTE_VIEWS:
628 synchronized (mNotificationRemoteViewsLock) {
629 return pullNotificationRemoteViewsLocked(atomTag, data);
630 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000631 case FrameworkStatsLog.BATTERY_LEVEL:
632 case FrameworkStatsLog.REMAINING_BATTERY_CAPACITY:
633 case FrameworkStatsLog.FULL_BATTERY_CAPACITY:
634 case FrameworkStatsLog.BATTERY_VOLTAGE:
635 case FrameworkStatsLog.BATTERY_CYCLE_COUNT:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700636 synchronized (mHealthHalLock) {
637 return pullHealthHalLocked(atomTag, data);
638 }
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -0800639 case FrameworkStatsLog.ATTRIBUTED_APP_OPS:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700640 synchronized (mAttributedAppOpsLock) {
641 return pullAttributedAppOpsLocked(atomTag, data);
642 }
Raff Tsai87cefd42020-04-07 14:25:02 +0800643 case FrameworkStatsLog.SETTING_SNAPSHOT:
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700644 synchronized (mSettingsStatsLock) {
645 return pullSettingsStatsLocked(atomTag, data);
646 }
Ioannis Ilkos606bf6e2020-02-20 13:25:37 +0000647 default:
648 throw new UnsupportedOperationException("Unknown tagId=" + atomTag);
649 }
650 } finally {
651 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800652 }
653 }
654 }
655
Tej Singh953ad862020-01-03 12:47:07 -0800656 @Override
657 public void onStart() {
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800658 // no op
659 }
660
661 @Override
662 public void onBootPhase(int phase) {
663 super.onBootPhase(phase);
664 if (phase == PHASE_SYSTEM_SERVICES_READY) {
665 BackgroundThread.getHandler().post(() -> {
Jeffrey Huang4c527162020-01-30 17:53:13 -0800666 nativeInit();
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800667 initializePullersState();
junyulai39f15c82020-04-17 10:48:36 +0800668 registerPullers();
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800669 registerEventListeners();
670 });
junyulai39f15c82020-04-17 10:48:36 +0800671 } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
672 // Network stats related pullers can only be initialized after service is ready.
673 BackgroundThread.getHandler().post(() -> initAndRegisterNetworkStatsPullers());
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800674 }
675 }
676
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700677 // We do not hold locks within this function because it is guaranteed to be called before the
678 // pullers are ever run, as the pullers are not yet registered with statsd.
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800679 void initializePullersState() {
680 // Get Context Managers
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800681 mStatsManager = (StatsManager) mContext.getSystemService(Context.STATS_MANAGER);
Jeffrey Huang4df57402020-01-14 11:57:22 -0800682 mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
Jeffrey Huang1f818892020-01-14 12:05:05 -0800683 mTelephony = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
junyulaiaa31d3c2020-04-10 15:11:54 +0800684 mSubscriptionManager = (SubscriptionManager)
685 mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
686 mStatsSubscriptionsListener = new StatsSubscriptionsListener(mSubscriptionManager);
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -0800687 mStorageManager = (StorageManager) mContext.getSystemService(StorageManager.class);
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -0800688
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800689 // Initialize DiskIO
690 mStoragedUidIoStatsReader = new StoragedUidIoStatsReader();
Jeffrey Huangbf130832020-01-22 15:48:26 -0800691
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800692 // Initialize PROC_STATS
Jeffrey Huangb2cdb1a52020-02-24 15:26:13 -0800693 mBaseDir = new File(SystemServiceManager.ensureSystemDir(), "stats_pull");
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700694 mBaseDir.mkdirs();
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800695
696 // Disables throttler on CPU time readers.
697 mCpuUidUserSysTimeReader = new KernelCpuUidUserSysTimeReader(false);
698 mCpuUidFreqTimeReader = new KernelCpuUidFreqTimeReader(false);
699 mCpuUidActiveTimeReader = new KernelCpuUidActiveTimeReader(false);
700 mCpuUidClusterTimeReader = new KernelCpuUidClusterTimeReader(false);
701
702 // Initialize state for KERNEL_WAKELOCK
703 mKernelWakelockReader = new KernelWakelockReader();
704 mTmpWakelockStats = new KernelWakelockStats();
Jeffrey Huangbf130832020-01-22 15:48:26 -0800705
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800706 // Initialize state for CPU_TIME_PER_FREQ atom
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -0800707 PowerProfile powerProfile = new PowerProfile(mContext);
708 final int numClusters = powerProfile.getNumCpuClusters();
709 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters];
710 int firstCpuOfCluster = 0;
711 for (int i = 0; i < numClusters; i++) {
712 final int numSpeedSteps = powerProfile.getNumSpeedStepsInCpuCluster(i);
713 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster,
714 numSpeedSteps);
715 firstCpuOfCluster += powerProfile.getNumCoresInCpuCluster(i);
716 }
Jeffrey Huangbf4eef82020-01-16 15:38:58 -0800717
718 // Used for CPU_TIME_PER_THREAD_FREQ
719 mKernelCpuThreadReader =
720 KernelCpuThreadReaderSettingsObserver.getSettingsModifiedReader(mContext);
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800721
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -0800722 // Initialize HealthService
723 mHealthService = new BatteryService.HealthServiceWrapper();
724 try {
725 mHealthService.init();
726 } catch (RemoteException e) {
727 Slog.e(TAG, "failed to initialize healthHalWrapper");
728 }
Stanislav Zholnine08a2bb2020-05-17 17:51:31 +0100729
730 // Initialize list of AppOps related to DangerousPermissions
731 PackageManager pm = mContext.getPackageManager();
732 for (int op = 0; op < AppOpsManager._NUM_OP; op++) {
733 String perm = AppOpsManager.opToPermission(op);
734 if (perm == null) {
735 continue;
736 } else {
737 PermissionInfo permInfo;
738 try {
739 permInfo = pm.getPermissionInfo(perm, 0);
740 if (permInfo.getProtection() == PROTECTION_DANGEROUS) {
741 mDangerousAppOpsList.add(op);
742 }
743 } catch (PackageManager.NameNotFoundException exception) {
744 continue;
745 }
746 }
747 }
Tej Singh953ad862020-01-03 12:47:07 -0800748 }
749
Jeffrey Huang1c0fe042020-01-27 13:22:05 -0800750 void registerEventListeners() {
751 final ConnectivityManager connectivityManager =
752 (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
753 // Default NetworkRequest should cover all transport types.
754 final NetworkRequest request = new NetworkRequest.Builder().build();
755 connectivityManager.registerNetworkCallback(request, new ConnectivityStatsCallback());
756
757 // Enable push notifications of throttling from vendor thermal
758 // management subsystem via thermalservice.
759 IThermalService thermalService = getIThermalService();
760 if (thermalService != null) {
761 try {
762 thermalService.registerThermalEventListener(new ThermalEventListener());
763 Slog.i(TAG, "register thermal listener successfully");
764 } catch (RemoteException e) {
765 Slog.i(TAG, "failed to register thermal listener");
766 }
Tej Singh953ad862020-01-03 12:47:07 -0800767 }
768 }
769
junyulai39f15c82020-04-17 10:48:36 +0800770 void registerPullers() {
Tej Singh953ad862020-01-03 12:47:07 -0800771 if (DEBUG) {
junyulai39f15c82020-04-17 10:48:36 +0800772 Slog.d(TAG, "Registering pullers with statsd");
Tej Singh953ad862020-01-03 12:47:07 -0800773 }
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800774 mStatsCallbackImpl = new StatsPullAtomCallbackImpl();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800775 registerBluetoothBytesTransfer();
776 registerKernelWakelock();
777 registerCpuTimePerFreq();
778 registerCpuTimePerUid();
779 registerCpuTimePerUidFreq();
780 registerCpuActiveTime();
781 registerCpuClusterTime();
782 registerWifiActivityInfo();
783 registerModemActivityInfo();
784 registerBluetoothActivityInfo();
785 registerSystemElapsedRealtime();
786 registerSystemUptime();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800787 registerProcessMemoryState();
788 registerProcessMemoryHighWaterMark();
789 registerProcessMemorySnapshot();
790 registerSystemIonHeapSize();
Rafal Slawikbdd5a502020-01-14 14:14:29 +0000791 registerIonHeapSize();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800792 registerProcessSystemIonHeapSize();
793 registerTemperature();
794 registerCoolingDevice();
Jeffrey Huang877adfe2020-01-15 17:16:43 -0800795 registerBinderCallsStats();
796 registerBinderCallsStatsExceptions();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800797 registerLooperStats();
798 registerDiskStats();
799 registerDirectoryUsage();
800 registerAppSize();
801 registerCategorySize();
802 registerNumFingerprintsEnrolled();
803 registerNumFacesEnrolled();
804 registerProcStats();
805 registerProcStatsPkgProc();
806 registerDiskIO();
807 registerPowerProfile();
808 registerProcessCpuTime();
809 registerCpuTimePerThreadFreq();
810 registerDeviceCalculatedPowerUse();
811 registerDeviceCalculatedPowerBlameUid();
812 registerDeviceCalculatedPowerBlameOther();
813 registerDebugElapsedClock();
814 registerDebugFailingElapsedClock();
815 registerBuildInformation();
816 registerRoleHolder();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800817 registerTimeZoneDataInfo();
818 registerExternalStorageInfo();
819 registerAppsOnExternalStorageInfo();
820 registerFaceSettings();
821 registerAppOps();
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -0800822 registerAttributedAppOps();
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +0000823 registerRuntimeAppOpAccessMessage();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800824 registerNotificationRemoteViews();
825 registerDangerousPermissionState();
826 registerDangerousPermissionStateSampled();
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -0800827 registerBatteryLevel();
Jeffrey Huang43f4d262020-01-30 14:03:31 -0800828 registerRemainingBatteryCapacity();
829 registerFullBatteryCapacity();
830 registerBatteryVoltage();
831 registerBatteryCycleCount();
Raff Tsai87cefd42020-04-07 14:25:02 +0800832 registerSettingsStats();
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800833 }
834
junyulai39f15c82020-04-17 10:48:36 +0800835 private void initAndRegisterNetworkStatsPullers() {
836 if (DEBUG) {
837 Slog.d(TAG, "Registering NetworkStats pullers with statsd");
838 }
839 // Initialize NetworkStats baselines.
junyulai9f0146a2020-05-14 15:07:21 +0800840 mNetworkStatsBaselines.addAll(
841 collectNetworkStatsSnapshotForAtom(FrameworkStatsLog.WIFI_BYTES_TRANSFER));
842 mNetworkStatsBaselines.addAll(
843 collectNetworkStatsSnapshotForAtom(FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG));
844 mNetworkStatsBaselines.addAll(
845 collectNetworkStatsSnapshotForAtom(FrameworkStatsLog.MOBILE_BYTES_TRANSFER));
846 mNetworkStatsBaselines.addAll(collectNetworkStatsSnapshotForAtom(
847 FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG));
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -0700848 mNetworkStatsBaselines.addAll(collectNetworkStatsSnapshotForAtom(
849 FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED));
junyulaiee3ea792020-05-15 18:26:25 +0800850 mNetworkStatsBaselines.addAll(
851 collectNetworkStatsSnapshotForAtom(FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER));
junyulai39f15c82020-04-17 10:48:36 +0800852
junyulaiaa31d3c2020-04-10 15:11:54 +0800853 // Listen to subscription changes to record historical subscriptions that activated before
junyulai66e735e2020-05-29 11:24:58 +0800854 // pulling, this is used by {@code DATA_USAGE_BYTES_TRANSFER}.
junyulaiaa31d3c2020-04-10 15:11:54 +0800855 mSubscriptionManager.addOnSubscriptionsChangedListener(
856 BackgroundThread.getExecutor(), mStatsSubscriptionsListener);
857
junyulai39f15c82020-04-17 10:48:36 +0800858 registerWifiBytesTransfer();
859 registerWifiBytesTransferBackground();
860 registerMobileBytesTransfer();
861 registerMobileBytesTransferBackground();
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -0700862 registerBytesTransferByTagAndMetered();
junyulaiee3ea792020-05-15 18:26:25 +0800863 registerDataUsageBytesTransfer();
junyulai39f15c82020-04-17 10:48:36 +0800864 }
865
junyulai212a5f0e2020-02-07 17:42:39 +0800866 /**
867 * Return the {@code INetworkStatsSession} object that holds the necessary properties needed
868 * for the subsequent queries to {@link com.android.server.net.NetworkStatsService}. Or
junyulaiea76fb82020-05-29 14:32:21 +0800869 * null if the service or binder cannot be obtained. Calling this method will trigger poll
870 * in NetworkStatsService with once per 15 seconds rate-limit, unless {@code bypassRateLimit}
871 * is set to true. This is needed in {@link #getUidNetworkStatsSnapshotForTemplate}, where
872 * bypassing the limit is necessary for perfd to supply realtime stats to developers looking at
873 * the network usage of their app.
junyulai212a5f0e2020-02-07 17:42:39 +0800874 */
875 @Nullable
junyulaiea76fb82020-05-29 14:32:21 +0800876 private INetworkStatsSession getNetworkStatsSession(boolean bypassRateLimit) {
junyulai17941572020-05-27 14:44:13 +0800877 final INetworkStatsService networkStatsService =
878 INetworkStatsService.Stub.asInterface(
879 ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
880 if (networkStatsService == null) return null;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800881
junyulai17941572020-05-27 14:44:13 +0800882 try {
883 return networkStatsService.openSessionForUsageStats(
junyulaiea76fb82020-05-29 14:32:21 +0800884 FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN | (bypassRateLimit ? FLAG_POLL_FORCE
junyulai17941572020-05-27 14:44:13 +0800885 : FLAG_POLL_ON_OPEN), mContext.getOpPackageName());
886 } catch (RemoteException e) {
887 Slog.e(TAG, "Cannot get NetworkStats session", e);
888 return null;
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800889 }
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -0800890 }
891
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800892 private IThermalService getIThermalService() {
893 synchronized (mThermalLock) {
894 if (mThermalService == null) {
895 mThermalService = IThermalService.Stub.asInterface(
896 ServiceManager.getService(Context.THERMAL_SERVICE));
897 if (mThermalService != null) {
898 try {
899 mThermalService.asBinder().linkToDeath(() -> {
900 synchronized (mThermalLock) {
901 mThermalService = null;
902 }
903 }, /* flags */ 0);
904 } catch (RemoteException e) {
905 Slog.e(TAG, "linkToDeath with thermalService failed", e);
906 mThermalService = null;
907 }
908 }
909 }
910 return mThermalService;
911 }
912 }
Jeffrey Huang95765f02020-01-16 11:33:58 -0800913
914 private IStoraged getIStoragedService() {
915 synchronized (mStoragedLock) {
916 if (mStorageService == null) {
917 mStorageService = IStoraged.Stub.asInterface(
918 ServiceManager.getService("storaged"));
919 }
920 if (mStorageService != null) {
921 try {
922 mStorageService.asBinder().linkToDeath(() -> {
923 synchronized (mStoragedLock) {
924 mStorageService = null;
925 }
926 }, /* flags */ 0);
927 } catch (RemoteException e) {
928 Slog.e(TAG, "linkToDeath with storagedService failed", e);
929 mStorageService = null;
930 }
931 }
932 }
933 return mStorageService;
934 }
935
Jeffrey Huang730bf962020-01-16 15:59:52 -0800936 private INotificationManager getINotificationManagerService() {
937 synchronized (mNotificationStatsLock) {
938 if (mNotificationManagerService == null) {
939 mNotificationManagerService = INotificationManager.Stub.asInterface(
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800940 ServiceManager.getService(Context.NOTIFICATION_SERVICE));
Jeffrey Huang730bf962020-01-16 15:59:52 -0800941 }
942 if (mNotificationManagerService != null) {
943 try {
944 mNotificationManagerService.asBinder().linkToDeath(() -> {
945 synchronized (mNotificationStatsLock) {
946 mNotificationManagerService = null;
947 }
948 }, /* flags */ 0);
949 } catch (RemoteException e) {
950 Slog.e(TAG, "linkToDeath with notificationManager failed", e);
951 mNotificationManagerService = null;
952 }
953 }
954 }
955 return mNotificationManagerService;
956 }
957
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800958 private IProcessStats getIProcessStatsService() {
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700959 synchronized (mProcStatsLock) {
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800960 if (mProcessStatsService == null) {
961 mProcessStatsService = IProcessStats.Stub.asInterface(
962 ServiceManager.getService(ProcessStats.SERVICE_NAME));
963 }
964 if (mProcessStatsService != null) {
965 try {
966 mProcessStatsService.asBinder().linkToDeath(() -> {
Ruchir Rastogibba70a62020-06-01 10:43:31 -0700967 synchronized (mProcStatsLock) {
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -0800968 mProcessStatsService = null;
969 }
970 }, /* flags */ 0);
971 } catch (RemoteException e) {
972 Slog.e(TAG, "linkToDeath with ProcessStats failed", e);
973 mProcessStatsService = null;
974 }
975 }
976 }
977 return mProcessStatsService;
978 }
979
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800980 private void registerWifiBytesTransfer() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -0800981 int tagId = FrameworkStatsLog.WIFI_BYTES_TRANSFER;
Tej Singh6b979832020-01-02 15:23:02 -0800982 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800983 .setAdditiveFields(new int[] {2, 3, 4, 5})
984 .build();
Tej Singh72a70a82020-02-26 23:46:29 -0800985 mStatsManager.setPullAtomCallback(
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800986 tagId,
Jeffrey Huangacaee0f2020-01-10 14:45:19 -0800987 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -0700988 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -0800989 mStatsCallbackImpl
Jeffrey Huang3ee8e202020-01-09 15:31:16 -0800990 );
991 }
992
junyulai39f15c82020-04-17 10:48:36 +0800993 @NonNull
junyulai9f0146a2020-05-14 15:07:21 +0800994 private List<NetworkStatsExt> collectNetworkStatsSnapshotForAtom(int atomTag) {
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -0700995 List<NetworkStatsExt> ret = new ArrayList<>();
junyulai9f0146a2020-05-14 15:07:21 +0800996 switch(atomTag) {
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -0700997 case FrameworkStatsLog.WIFI_BYTES_TRANSFER: {
junyulaiee3ea792020-05-15 18:26:25 +0800998 final NetworkStats stats = getUidNetworkStatsSnapshotForTransport(TRANSPORT_WIFI);
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -0700999 if (stats != null) {
1000 ret.add(new NetworkStatsExt(stats.groupedByUid(), new int[] {TRANSPORT_WIFI},
1001 /*slicedByFgbg=*/false));
1002 }
1003 break;
1004 }
1005 case FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG: {
junyulaiee3ea792020-05-15 18:26:25 +08001006 final NetworkStats stats = getUidNetworkStatsSnapshotForTransport(TRANSPORT_WIFI);
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001007 if (stats != null) {
1008 ret.add(new NetworkStatsExt(sliceNetworkStatsByUidAndFgbg(stats),
1009 new int[] {TRANSPORT_WIFI}, /*slicedByFgbg=*/true));
1010 }
1011 break;
1012 }
1013 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER: {
junyulaiee3ea792020-05-15 18:26:25 +08001014 final NetworkStats stats =
1015 getUidNetworkStatsSnapshotForTransport(TRANSPORT_CELLULAR);
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001016 if (stats != null) {
1017 ret.add(new NetworkStatsExt(stats.groupedByUid(),
1018 new int[] {TRANSPORT_CELLULAR}, /*slicedByFgbg=*/false));
1019 }
1020 break;
1021 }
1022 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG: {
junyulaiee3ea792020-05-15 18:26:25 +08001023 final NetworkStats stats =
1024 getUidNetworkStatsSnapshotForTransport(TRANSPORT_CELLULAR);
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001025 if (stats != null) {
1026 ret.add(new NetworkStatsExt(sliceNetworkStatsByUidAndFgbg(stats),
1027 new int[] {TRANSPORT_CELLULAR}, /*slicedByFgbg=*/true));
1028 }
1029 break;
1030 }
1031 case FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED: {
junyulaiee3ea792020-05-15 18:26:25 +08001032 final NetworkStats wifiStats = getUidNetworkStatsSnapshotForTemplate(
1033 buildTemplateWifiWildcard(), /*includeTags=*/true);
1034 final NetworkStats cellularStats = getUidNetworkStatsSnapshotForTemplate(
1035 buildTemplateMobileWildcard(), /*includeTags=*/true);
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001036 if (wifiStats != null && cellularStats != null) {
1037 final NetworkStats stats = wifiStats.add(cellularStats);
1038 ret.add(new NetworkStatsExt(sliceNetworkStatsByUidTagAndMetered(stats),
junyulaiee3ea792020-05-15 18:26:25 +08001039 new int[] {TRANSPORT_WIFI, TRANSPORT_CELLULAR},
1040 /*slicedByFgbg=*/false, /*slicedByTag=*/true,
junyulaiaa31d3c2020-04-10 15:11:54 +08001041 /*slicedByMetered=*/true, TelephonyManager.NETWORK_TYPE_UNKNOWN,
1042 /*subInfo=*/null));
junyulaiee3ea792020-05-15 18:26:25 +08001043 }
1044 break;
1045 }
1046 case FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER: {
junyulaiaa31d3c2020-04-10 15:11:54 +08001047 for (final SubInfo subInfo : mHistoricalSubs) {
1048 ret.addAll(getDataUsageBytesTransferSnapshotForSub(subInfo));
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001049 }
1050 break;
1051 }
junyulai9f0146a2020-05-14 15:07:21 +08001052 default:
1053 throw new IllegalArgumentException("Unknown atomTag " + atomTag);
1054 }
junyulai39f15c82020-04-17 10:48:36 +08001055 return ret;
1056 }
1057
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001058 private int pullDataBytesTransferLocked(int atomTag, @NonNull List<StatsEvent> pulledData) {
junyulai9f0146a2020-05-14 15:07:21 +08001059 final List<NetworkStatsExt> current = collectNetworkStatsSnapshotForAtom(atomTag);
junyulai592c6052020-04-29 16:09:01 +08001060
junyulai39f15c82020-04-17 10:48:36 +08001061 if (current == null) {
1062 Slog.e(TAG, "current snapshot is null for " + atomTag + ", return.");
1063 return StatsManager.PULL_SKIP;
1064 }
1065
1066 for (final NetworkStatsExt item : current) {
1067 final NetworkStatsExt baseline = CollectionUtils.find(mNetworkStatsBaselines,
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001068 it -> it.hasSameSlicing(item));
junyulai39f15c82020-04-17 10:48:36 +08001069
1070 // No matched baseline indicates error has occurred during initialization stage,
1071 // skip reporting anything since the snapshot is invalid.
1072 if (baseline == null) {
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001073 Slog.e(TAG, "baseline is null for " + atomTag + ", return.");
junyulai39f15c82020-04-17 10:48:36 +08001074 return StatsManager.PULL_SKIP;
1075 }
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001076 final NetworkStatsExt diff = new NetworkStatsExt(
1077 item.stats.subtract(baseline.stats).removeEmptyEntries(), item.transports,
junyulaiaa31d3c2020-04-10 15:11:54 +08001078 item.slicedByFgbg, item.slicedByTag, item.slicedByMetered, item.ratType,
1079 item.subInfo);
junyulai39f15c82020-04-17 10:48:36 +08001080
1081 // If no diff, skip.
1082 if (diff.stats.size() == 0) continue;
1083
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001084 switch (atomTag) {
1085 case FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED:
1086 addBytesTransferByTagAndMeteredAtoms(diff, pulledData);
1087 break;
junyulaiee3ea792020-05-15 18:26:25 +08001088 case FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER:
1089 addDataUsageBytesTransferAtoms(diff, pulledData);
1090 break;
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001091 default:
1092 addNetworkStats(atomTag, pulledData, diff);
1093 }
junyulai39f15c82020-04-17 10:48:36 +08001094 }
junyulai592c6052020-04-29 16:09:01 +08001095 return StatsManager.PULL_SUCCESS;
junyulai212a5f0e2020-02-07 17:42:39 +08001096 }
1097
1098 private void addNetworkStats(int atomTag, @NonNull List<StatsEvent> ret,
junyulai39f15c82020-04-17 10:48:36 +08001099 @NonNull NetworkStatsExt statsExt) {
1100 int size = statsExt.stats.size();
junyulai212a5f0e2020-02-07 17:42:39 +08001101 final NetworkStats.Entry entry = new NetworkStats.Entry(); // For recycling
Jeffrey Huang3ee8e202020-01-09 15:31:16 -08001102 for (int j = 0; j < size; j++) {
junyulai39f15c82020-04-17 10:48:36 +08001103 statsExt.stats.getValues(j, entry);
Jeffrey Huang3ee8e202020-01-09 15:31:16 -08001104 StatsEvent.Builder e = StatsEvent.newBuilder();
junyulai212a5f0e2020-02-07 17:42:39 +08001105 e.setAtomId(atomTag);
Muhammad Qureshi09fc8c42020-05-06 14:50:54 -07001106 switch (atomTag) {
1107 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER:
1108 case FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG:
1109 e.addBooleanAnnotation(ANNOTATION_ID_TRUNCATE_TIMESTAMP, true);
1110 break;
1111 default:
1112 }
Jeffrey Huang3ee8e202020-01-09 15:31:16 -08001113 e.writeInt(entry.uid);
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001114 e.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001115 if (statsExt.slicedByFgbg) {
Jeffrey Huang3ee8e202020-01-09 15:31:16 -08001116 e.writeInt(entry.set);
1117 }
1118 e.writeLong(entry.rxBytes);
1119 e.writeLong(entry.rxPackets);
1120 e.writeLong(entry.txBytes);
1121 e.writeLong(entry.txPackets);
1122 ret.add(e.build());
1123 }
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001124 }
1125
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001126 private void addBytesTransferByTagAndMeteredAtoms(@NonNull NetworkStatsExt statsExt,
1127 @NonNull List<StatsEvent> pulledData) {
1128 final NetworkStats.Entry entry = new NetworkStats.Entry(); // for recycling
1129 for (int i = 0; i < statsExt.stats.size(); i++) {
1130 statsExt.stats.getValues(i, entry);
1131 StatsEvent e = StatsEvent.newBuilder()
1132 .setAtomId(FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED)
1133 .addBooleanAnnotation(ANNOTATION_ID_TRUNCATE_TIMESTAMP, true)
1134 .writeInt(entry.uid)
1135 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
1136 .writeBoolean(entry.metered == NetworkStats.METERED_YES)
1137 .writeInt(entry.tag)
1138 .writeLong(entry.rxBytes)
1139 .writeLong(entry.rxPackets)
1140 .writeLong(entry.txBytes)
1141 .writeLong(entry.txPackets)
1142 .build();
1143 pulledData.add(e);
1144 }
1145 }
1146
junyulaiee3ea792020-05-15 18:26:25 +08001147 private void addDataUsageBytesTransferAtoms(@NonNull NetworkStatsExt statsExt,
1148 @NonNull List<StatsEvent> pulledData) {
1149 final NetworkStats.Entry entry = new NetworkStats.Entry(); // for recycling
1150 for (int i = 0; i < statsExt.stats.size(); i++) {
1151 statsExt.stats.getValues(i, entry);
1152 StatsEvent e = StatsEvent.newBuilder()
1153 .setAtomId(FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER)
1154 .addBooleanAnnotation(ANNOTATION_ID_TRUNCATE_TIMESTAMP, true)
1155 .writeInt(entry.set)
1156 .writeLong(entry.rxBytes)
1157 .writeLong(entry.rxPackets)
1158 .writeLong(entry.txBytes)
1159 .writeLong(entry.txPackets)
1160 .writeInt(statsExt.ratType)
junyulaiaa31d3c2020-04-10 15:11:54 +08001161 // Fill information about subscription, these cannot be null since invalid data
1162 // would be filtered when adding into subInfo list.
1163 .writeString(statsExt.subInfo.mcc)
1164 .writeString(statsExt.subInfo.mnc)
1165 .writeInt(statsExt.subInfo.carrierId)
1166 .writeInt(statsExt.subInfo.isOpportunistic
1167 ? DATA_USAGE_BYTES_TRANSFER__OPPORTUNISTIC_DATA_SUB__OPPORTUNISTIC
1168 : DATA_USAGE_BYTES_TRANSFER__OPPORTUNISTIC_DATA_SUB__NOT_OPPORTUNISTIC)
junyulaiee3ea792020-05-15 18:26:25 +08001169 .build();
1170 pulledData.add(e);
1171 }
1172 }
1173
junyulai39f15c82020-04-17 10:48:36 +08001174 /**
junyulaiee3ea792020-05-15 18:26:25 +08001175 * Create a snapshot of NetworkStats for a given transport.
1176 */
1177 @Nullable private NetworkStats getUidNetworkStatsSnapshotForTransport(int transport) {
1178 final NetworkTemplate template = (transport == TRANSPORT_CELLULAR)
1179 ? NetworkTemplate.buildTemplateMobileWithRatType(
1180 /*subscriptionId=*/null, NETWORK_TYPE_ALL)
1181 : NetworkTemplate.buildTemplateWifiWildcard();
1182 return getUidNetworkStatsSnapshotForTemplate(template, /*includeTags=*/false);
1183 }
1184
1185 /**
1186 * Create a snapshot of NetworkStats since boot for the given template, but add 1 bucket
1187 * duration before boot as a buffer to ensure at least one full bucket will be included.
junyulai39f15c82020-04-17 10:48:36 +08001188 * Note that this should be only used to calculate diff since the snapshot might contains
1189 * some traffic before boot.
1190 */
junyulaiee3ea792020-05-15 18:26:25 +08001191 @Nullable private NetworkStats getUidNetworkStatsSnapshotForTemplate(
1192 @NonNull NetworkTemplate template, boolean includeTags) {
junyulai212a5f0e2020-02-07 17:42:39 +08001193 final long elapsedMillisSinceBoot = SystemClock.elapsedRealtime();
1194 final long currentTimeInMillis = MICROSECONDS.toMillis(SystemClock.currentTimeMicro());
junyulai39f15c82020-04-17 10:48:36 +08001195 final long bucketDuration = Settings.Global.getLong(mContext.getContentResolver(),
1196 NETSTATS_UID_BUCKET_DURATION, NETSTATS_UID_DEFAULT_BUCKET_DURATION_MS);
junyulai212a5f0e2020-02-07 17:42:39 +08001197 try {
junyulai17941572020-05-27 14:44:13 +08001198 // TODO (b/156313635): This is short-term hack to allow perfd gets updated networkStats
1199 // history when query in every second in order to show realtime statistics. However,
1200 // this is not a good long-term solution since NetworkStatsService will make frequent
1201 // I/O and also block main thread when polling.
1202 // Consider making perfd queries NetworkStatsService directly.
1203 final NetworkStats stats = getNetworkStatsSession(template.getMatchRule()
1204 == NetworkTemplate.MATCH_WIFI_WILDCARD).getSummaryForAllUid(template,
junyulai39f15c82020-04-17 10:48:36 +08001205 currentTimeInMillis - elapsedMillisSinceBoot - bucketDuration,
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001206 currentTimeInMillis, includeTags);
1207 return stats;
junyulai212a5f0e2020-02-07 17:42:39 +08001208 } catch (RemoteException | NullPointerException e) {
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001209 Slog.e(TAG, "Pulling netstats for template=" + template + " and includeTags="
1210 + includeTags + " causes error", e);
junyulai212a5f0e2020-02-07 17:42:39 +08001211 }
1212 return null;
1213 }
1214
junyulaiaa31d3c2020-04-10 15:11:54 +08001215 @NonNull private List<NetworkStatsExt> getDataUsageBytesTransferSnapshotForSub(
1216 @NonNull SubInfo subInfo) {
1217 final List<NetworkStatsExt> ret = new ArrayList<>();
1218 for (final int ratType : getAllCollapsedRatTypes()) {
1219 final NetworkTemplate template =
1220 buildTemplateMobileWithRatType(subInfo.subscriberId, ratType);
1221 final NetworkStats stats =
1222 getUidNetworkStatsSnapshotForTemplate(template, /*includeTags=*/false);
1223 if (stats != null) {
1224 ret.add(new NetworkStatsExt(sliceNetworkStatsByFgbg(stats),
1225 new int[] {TRANSPORT_CELLULAR}, /*slicedByFgbg=*/true,
1226 /*slicedByTag=*/false, /*slicedByMetered=*/false, ratType, subInfo));
1227 }
1228 }
1229 return ret;
1230 }
1231
junyulaiee3ea792020-05-15 18:26:25 +08001232 @NonNull private NetworkStats sliceNetworkStatsByFgbg(@NonNull NetworkStats stats) {
1233 return sliceNetworkStats(stats,
1234 (newEntry, oldEntry) -> {
1235 newEntry.set = oldEntry.set;
1236 });
1237 }
1238
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001239 @NonNull private NetworkStats sliceNetworkStatsByUidAndFgbg(@NonNull NetworkStats stats) {
1240 return sliceNetworkStats(stats,
1241 (newEntry, oldEntry) -> {
1242 newEntry.uid = oldEntry.uid;
1243 newEntry.set = oldEntry.set;
1244 });
1245 }
1246
1247 @NonNull private NetworkStats sliceNetworkStatsByUidTagAndMetered(@NonNull NetworkStats stats) {
1248 return sliceNetworkStats(stats,
1249 (newEntry, oldEntry) -> {
1250 newEntry.uid = oldEntry.uid;
1251 newEntry.tag = oldEntry.tag;
1252 newEntry.metered = oldEntry.metered;
1253 });
1254 }
1255
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001256 /**
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001257 * Slices NetworkStats along the dimensions specified in the slicer lambda and aggregates over
1258 * non-sliced dimensions.
1259 *
1260 * This function iterates through each NetworkStats.Entry, sets its dimensions equal to the
1261 * default state (with the presumption that we don't want to slice on anything), and then
1262 * applies the slicer lambda to allow users to control which dimensions to slice on. This is
1263 * adapted from groupedByUid within NetworkStats.java
1264 *
1265 * @param slicer An operation taking into two parameters, new NetworkStats.Entry and old
1266 * NetworkStats.Entry, that should be used to copy state from the old to the new.
1267 * This is useful for slicing by particular dimensions. For example, if we wished
1268 * to slice by uid and tag, we could write the following lambda:
1269 * (new, old) -> {
1270 * new.uid = old.uid;
1271 * new.tag = old.tag;
1272 * }
1273 * If no slicer is provided, the data is not sliced by any dimensions.
1274 * @return new NeworkStats object appropriately sliced
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001275 */
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001276 @NonNull private NetworkStats sliceNetworkStats(@NonNull NetworkStats stats,
1277 @Nullable BiConsumer<NetworkStats.Entry, NetworkStats.Entry> slicer) {
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001278 final NetworkStats ret = new NetworkStats(stats.getElapsedRealtime(), 1);
1279
1280 final NetworkStats.Entry entry = new NetworkStats.Entry();
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001281 entry.uid = NetworkStats.UID_ALL;
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001282 entry.iface = NetworkStats.IFACE_ALL;
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001283 entry.set = NetworkStats.SET_ALL;
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001284 entry.tag = NetworkStats.TAG_NONE;
1285 entry.metered = NetworkStats.METERED_ALL;
1286 entry.roaming = NetworkStats.ROAMING_ALL;
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001287 entry.defaultNetwork = NetworkStats.DEFAULT_NETWORK_ALL;
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001288
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001289 final NetworkStats.Entry recycle = new NetworkStats.Entry(); // used for retrieving values
1290 for (int i = 0; i < stats.size(); i++) {
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001291 stats.getValues(i, recycle);
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001292 if (slicer != null) {
1293 slicer.accept(entry, recycle);
1294 }
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001295
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001296 entry.rxBytes = recycle.rxBytes;
1297 entry.rxPackets = recycle.rxPackets;
1298 entry.txBytes = recycle.txBytes;
1299 entry.txPackets = recycle.txPackets;
1300 // Operations purposefully omitted since we don't use them for statsd.
1301 ret.combineValues(entry);
1302 }
1303 return ret;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001304 }
1305
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001306 private void registerWifiBytesTransferBackground() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001307 int tagId = FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG;
Tej Singh6b979832020-01-02 15:23:02 -08001308 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001309 .setAdditiveFields(new int[] {3, 4, 5, 6})
1310 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001311 mStatsManager.setPullAtomCallback(
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001312 tagId,
1313 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001314 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001315 mStatsCallbackImpl
Jeffrey Huangacaee0f2020-01-10 14:45:19 -08001316 );
1317 }
1318
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001319 private void registerMobileBytesTransfer() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001320 int tagId = FrameworkStatsLog.MOBILE_BYTES_TRANSFER;
Tej Singh6b979832020-01-02 15:23:02 -08001321 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangc8785422020-01-10 15:54:53 -08001322 .setAdditiveFields(new int[] {2, 3, 4, 5})
1323 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001324 mStatsManager.setPullAtomCallback(
Jeffrey Huangc8785422020-01-10 15:54:53 -08001325 tagId,
1326 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001327 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001328 mStatsCallbackImpl
Jeffrey Huangc8785422020-01-10 15:54:53 -08001329 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001330 }
1331
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001332 private void registerMobileBytesTransferBackground() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001333 int tagId = FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG;
Tej Singh6b979832020-01-02 15:23:02 -08001334 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huang89864442020-01-10 16:35:51 -08001335 .setAdditiveFields(new int[] {3, 4, 5, 6})
1336 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001337 mStatsManager.setPullAtomCallback(
Jeffrey Huang89864442020-01-10 16:35:51 -08001338 tagId,
1339 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001340 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001341 mStatsCallbackImpl
Jeffrey Huang89864442020-01-10 16:35:51 -08001342 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001343 }
1344
Ruchir Rastogie3cd20f2020-05-16 19:46:58 -07001345 private void registerBytesTransferByTagAndMetered() {
1346 int tagId = FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED;
1347 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
1348 .setAdditiveFields(new int[] {4, 5, 6, 7})
1349 .build();
1350 mStatsManager.setPullAtomCallback(
1351 tagId,
1352 metadata,
1353 BackgroundThread.getExecutor(),
1354 mStatsCallbackImpl
1355 );
1356 }
1357
junyulaiee3ea792020-05-15 18:26:25 +08001358 private void registerDataUsageBytesTransfer() {
1359 int tagId = FrameworkStatsLog.DATA_USAGE_BYTES_TRANSFER;
1360 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
1361 .setAdditiveFields(new int[] {2, 3, 4, 5})
1362 .build();
1363 mStatsManager.setPullAtomCallback(
1364 tagId,
1365 metadata,
1366 BackgroundThread.getExecutor(),
1367 mStatsCallbackImpl
1368 );
1369 }
1370
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001371 private void registerBluetoothBytesTransfer() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001372 int tagId = FrameworkStatsLog.BLUETOOTH_BYTES_TRANSFER;
Tej Singh6b979832020-01-02 15:23:02 -08001373 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangfa917892020-01-10 16:58:03 -08001374 .setAdditiveFields(new int[] {2, 3})
1375 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001376 mStatsManager.setPullAtomCallback(
Jeffrey Huangfa917892020-01-10 16:58:03 -08001377 tagId,
1378 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001379 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001380 mStatsCallbackImpl
Jeffrey Huangfa917892020-01-10 16:58:03 -08001381 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001382 }
1383
Jeffrey Huangfa917892020-01-10 16:58:03 -08001384 /**
1385 * Helper method to extract the Parcelable controller info from a
1386 * SynchronousResultReceiver.
1387 */
1388 private static <T extends Parcelable> T awaitControllerInfo(
1389 @Nullable SynchronousResultReceiver receiver) {
1390 if (receiver == null) {
1391 return null;
1392 }
1393
1394 try {
1395 final SynchronousResultReceiver.Result result =
1396 receiver.awaitResult(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS);
1397 if (result.bundle != null) {
1398 // This is the final destination for the Bundle.
1399 result.bundle.setDefusable(true);
1400
1401 final T data = result.bundle.getParcelable(RESULT_RECEIVER_CONTROLLER_KEY);
1402 if (data != null) {
1403 return data;
1404 }
1405 }
Jeffrey Huangfa917892020-01-10 16:58:03 -08001406 } catch (TimeoutException e) {
1407 Slog.w(TAG, "timeout reading " + receiver.getName() + " stats");
1408 }
1409 return null;
1410 }
1411
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001412 private BluetoothActivityEnergyInfo fetchBluetoothData() {
Jeffrey Huangfa917892020-01-10 16:58:03 -08001413 final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
1414 if (adapter != null) {
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001415 SynchronousResultReceiver bluetoothReceiver =
1416 new SynchronousResultReceiver("bluetooth");
Jeffrey Huangfa917892020-01-10 16:58:03 -08001417 adapter.requestControllerActivityEnergyInfo(bluetoothReceiver);
1418 return awaitControllerInfo(bluetoothReceiver);
1419 } else {
1420 Slog.e(TAG, "Failed to get bluetooth adapter!");
1421 return null;
1422 }
1423 }
1424
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001425 int pullBluetoothBytesTransferLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangfa917892020-01-10 16:58:03 -08001426 BluetoothActivityEnergyInfo info = fetchBluetoothData();
1427 if (info == null || info.getUidTraffic() == null) {
1428 return StatsManager.PULL_SKIP;
1429 }
1430 for (UidTraffic traffic : info.getUidTraffic()) {
1431 StatsEvent e = StatsEvent.newBuilder()
1432 .setAtomId(atomTag)
1433 .writeInt(traffic.getUid())
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001434 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangfa917892020-01-10 16:58:03 -08001435 .writeLong(traffic.getRxBytes())
1436 .writeLong(traffic.getTxBytes())
1437 .build();
1438 pulledData.add(e);
1439 }
1440 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001441 }
1442
1443 private void registerKernelWakelock() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001444 int tagId = FrameworkStatsLog.KERNEL_WAKELOCK;
Tej Singh72a70a82020-02-26 23:46:29 -08001445 mStatsManager.setPullAtomCallback(
Jeffrey Huanga6e5a9b2020-01-13 15:59:16 -08001446 tagId,
1447 /* PullAtomMetadata */ null,
Tej Singhe19799f2020-05-20 19:14:26 -07001448 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001449 mStatsCallbackImpl
Jeffrey Huanga6e5a9b2020-01-13 15:59:16 -08001450 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001451 }
1452
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001453 int pullKernelWakelockLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huanga6e5a9b2020-01-13 15:59:16 -08001454 final KernelWakelockStats wakelockStats =
1455 mKernelWakelockReader.readKernelWakelockStats(mTmpWakelockStats);
1456 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) {
1457 String name = ent.getKey();
1458 KernelWakelockStats.Entry kws = ent.getValue();
1459 StatsEvent e = StatsEvent.newBuilder()
1460 .setAtomId(atomTag)
1461 .writeString(name)
1462 .writeInt(kws.mCount)
1463 .writeInt(kws.mVersion)
1464 .writeLong(kws.mTotalTime)
1465 .build();
1466 pulledData.add(e);
1467 }
1468 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001469 }
1470
1471 private void registerCpuTimePerFreq() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001472 int tagId = FrameworkStatsLog.CPU_TIME_PER_FREQ;
Tej Singh6b979832020-01-02 15:23:02 -08001473 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -08001474 .setAdditiveFields(new int[] {3})
1475 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001476 mStatsManager.setPullAtomCallback(
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -08001477 tagId,
1478 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001479 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001480 mStatsCallbackImpl
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -08001481 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001482 }
1483
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001484 int pullCpuTimePerFreqLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang43d5e2d2020-01-13 16:22:36 -08001485 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) {
1486 long[] clusterTimeMs = mKernelCpuSpeedReaders[cluster].readAbsolute();
1487 if (clusterTimeMs != null) {
1488 for (int speed = clusterTimeMs.length - 1; speed >= 0; --speed) {
1489 StatsEvent e = StatsEvent.newBuilder()
1490 .setAtomId(atomTag)
1491 .writeInt(cluster)
1492 .writeInt(speed)
1493 .writeLong(clusterTimeMs[speed])
1494 .build();
1495 pulledData.add(e);
1496 }
1497 }
1498 }
1499 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001500 }
1501
1502 private void registerCpuTimePerUid() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001503 int tagId = FrameworkStatsLog.CPU_TIME_PER_UID;
Tej Singh6b979832020-01-02 15:23:02 -08001504 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangd5f053e2020-01-13 16:27:53 -08001505 .setAdditiveFields(new int[] {2, 3})
1506 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001507 mStatsManager.setPullAtomCallback(
Jeffrey Huangd5f053e2020-01-13 16:27:53 -08001508 tagId,
1509 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001510 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001511 mStatsCallbackImpl
Jeffrey Huangd5f053e2020-01-13 16:27:53 -08001512 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001513 }
1514
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001515 int pullCpuTimePerUidLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangd5f053e2020-01-13 16:27:53 -08001516 mCpuUidUserSysTimeReader.readAbsolute((uid, timesUs) -> {
1517 long userTimeUs = timesUs[0], systemTimeUs = timesUs[1];
1518 StatsEvent e = StatsEvent.newBuilder()
1519 .setAtomId(atomTag)
1520 .writeInt(uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001521 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangd5f053e2020-01-13 16:27:53 -08001522 .writeLong(userTimeUs)
1523 .writeLong(systemTimeUs)
1524 .build();
1525 pulledData.add(e);
1526 });
1527 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001528 }
1529
1530 private void registerCpuTimePerUidFreq() {
Jeffrey Huanga9899302020-01-13 16:34:03 -08001531 // the throttling is 3sec, handled in
1532 // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001533 int tagId = FrameworkStatsLog.CPU_TIME_PER_UID_FREQ;
Tej Singh6b979832020-01-02 15:23:02 -08001534 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Tej Singh137aa832020-05-28 18:21:52 -07001535 .setAdditiveFields(new int[] {3})
Jeffrey Huanga9899302020-01-13 16:34:03 -08001536 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001537 mStatsManager.setPullAtomCallback(
Jeffrey Huanga9899302020-01-13 16:34:03 -08001538 tagId,
1539 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001540 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001541 mStatsCallbackImpl
Jeffrey Huanga9899302020-01-13 16:34:03 -08001542 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001543 }
1544
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001545 int pullCpuTimePerUidFreqLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huanga9899302020-01-13 16:34:03 -08001546 mCpuUidFreqTimeReader.readAbsolute((uid, cpuFreqTimeMs) -> {
1547 for (int freqIndex = 0; freqIndex < cpuFreqTimeMs.length; ++freqIndex) {
1548 if (cpuFreqTimeMs[freqIndex] != 0) {
1549 StatsEvent e = StatsEvent.newBuilder()
1550 .setAtomId(atomTag)
1551 .writeInt(uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001552 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huanga9899302020-01-13 16:34:03 -08001553 .writeInt(freqIndex)
1554 .writeLong(cpuFreqTimeMs[freqIndex])
1555 .build();
1556 pulledData.add(e);
1557 }
1558 }
1559 });
1560 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001561 }
1562
1563 private void registerCpuActiveTime() {
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001564 // the throttling is 3sec, handled in
1565 // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001566 int tagId = FrameworkStatsLog.CPU_ACTIVE_TIME;
Tej Singh6b979832020-01-02 15:23:02 -08001567 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001568 .setAdditiveFields(new int[] {2})
1569 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001570 mStatsManager.setPullAtomCallback(
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001571 tagId,
1572 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001573 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001574 mStatsCallbackImpl
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001575 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001576 }
1577
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001578 int pullCpuActiveTimeLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001579 mCpuUidActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> {
1580 StatsEvent e = StatsEvent.newBuilder()
1581 .setAtomId(atomTag)
1582 .writeInt(uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001583 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangccfcdf02020-01-13 16:38:27 -08001584 .writeLong(cpuActiveTimesMs)
1585 .build();
1586 pulledData.add(e);
1587 });
1588 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001589 }
1590
1591 private void registerCpuClusterTime() {
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001592 // the throttling is 3sec, handled in
1593 // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001594 int tagId = FrameworkStatsLog.CPU_CLUSTER_TIME;
Tej Singh6b979832020-01-02 15:23:02 -08001595 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001596 .setAdditiveFields(new int[] {3})
1597 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001598 mStatsManager.setPullAtomCallback(
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001599 tagId,
1600 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001601 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001602 mStatsCallbackImpl
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001603 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001604 }
1605
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001606 int pullCpuClusterTimeLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001607 mCpuUidClusterTimeReader.readAbsolute((uid, cpuClusterTimesMs) -> {
1608 for (int i = 0; i < cpuClusterTimesMs.length; i++) {
1609 StatsEvent e = StatsEvent.newBuilder()
1610 .setAtomId(atomTag)
1611 .writeInt(uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001612 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangceb1d252020-01-13 16:47:44 -08001613 .writeInt(i)
1614 .writeLong(cpuClusterTimesMs[i])
1615 .build();
1616 pulledData.add(e);
1617 }
1618 });
1619 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001620 }
1621
1622 private void registerWifiActivityInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001623 int tagId = FrameworkStatsLog.WIFI_ACTIVITY_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08001624 mStatsManager.setPullAtomCallback(
Jeffrey Huang4df57402020-01-14 11:57:22 -08001625 tagId,
1626 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07001627 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001628 mStatsCallbackImpl
Jeffrey Huang4df57402020-01-14 11:57:22 -08001629 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001630 }
1631
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001632 int pullWifiActivityInfoLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang4df57402020-01-14 11:57:22 -08001633 long token = Binder.clearCallingIdentity();
1634 try {
1635 SynchronousResultReceiver wifiReceiver = new SynchronousResultReceiver("wifi");
1636 mWifiManager.getWifiActivityEnergyInfoAsync(
1637 new Executor() {
1638 @Override
1639 public void execute(Runnable runnable) {
1640 // run the listener on the binder thread, if it was run on the main
1641 // thread it would deadlock since we would be waiting on ourselves
1642 runnable.run();
1643 }
1644 },
1645 info -> {
1646 Bundle bundle = new Bundle();
1647 bundle.putParcelable(BatteryStats.RESULT_RECEIVER_CONTROLLER_KEY, info);
1648 wifiReceiver.send(0, bundle);
1649 }
1650 );
1651 final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver);
1652 if (wifiInfo == null) {
1653 return StatsManager.PULL_SKIP;
1654 }
1655 StatsEvent e = StatsEvent.newBuilder()
1656 .setAtomId(atomTag)
1657 .writeLong(wifiInfo.getTimeSinceBootMillis())
1658 .writeInt(wifiInfo.getStackState())
1659 .writeLong(wifiInfo.getControllerTxDurationMillis())
1660 .writeLong(wifiInfo.getControllerRxDurationMillis())
1661 .writeLong(wifiInfo.getControllerIdleDurationMillis())
1662 .writeLong(wifiInfo.getControllerEnergyUsedMicroJoules())
1663 .build();
1664 pulledData.add(e);
1665 } catch (RuntimeException e) {
1666 Slog.e(TAG, "failed to getWifiActivityEnergyInfoAsync", e);
1667 return StatsManager.PULL_SKIP;
1668 } finally {
1669 Binder.restoreCallingIdentity(token);
1670 }
1671 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001672 }
1673
1674 private void registerModemActivityInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001675 int tagId = FrameworkStatsLog.MODEM_ACTIVITY_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08001676 mStatsManager.setPullAtomCallback(
Jeffrey Huang1f818892020-01-14 12:05:05 -08001677 tagId,
1678 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07001679 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001680 mStatsCallbackImpl
Jeffrey Huang1f818892020-01-14 12:05:05 -08001681 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001682 }
1683
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001684 int pullModemActivityInfoLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang1f818892020-01-14 12:05:05 -08001685 long token = Binder.clearCallingIdentity();
1686 try {
1687 SynchronousResultReceiver modemReceiver = new SynchronousResultReceiver("telephony");
1688 mTelephony.requestModemActivityInfo(modemReceiver);
1689 final ModemActivityInfo modemInfo = awaitControllerInfo(modemReceiver);
1690 if (modemInfo == null) {
1691 return StatsManager.PULL_SKIP;
1692 }
1693 StatsEvent e = StatsEvent.newBuilder()
1694 .setAtomId(atomTag)
1695 .writeLong(modemInfo.getTimestamp())
1696 .writeLong(modemInfo.getSleepTimeMillis())
1697 .writeLong(modemInfo.getIdleTimeMillis())
1698 .writeLong(modemInfo.getTransmitPowerInfo().get(0).getTimeInMillis())
1699 .writeLong(modemInfo.getTransmitPowerInfo().get(1).getTimeInMillis())
1700 .writeLong(modemInfo.getTransmitPowerInfo().get(2).getTimeInMillis())
1701 .writeLong(modemInfo.getTransmitPowerInfo().get(3).getTimeInMillis())
1702 .writeLong(modemInfo.getTransmitPowerInfo().get(4).getTimeInMillis())
1703 .writeLong(modemInfo.getReceiveTimeMillis())
1704 .build();
1705 pulledData.add(e);
1706 } finally {
1707 Binder.restoreCallingIdentity(token);
1708 }
1709 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001710 }
1711
1712 private void registerBluetoothActivityInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001713 int tagId = FrameworkStatsLog.BLUETOOTH_ACTIVITY_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08001714 mStatsManager.setPullAtomCallback(
Jeffrey Huangaafccb32020-01-13 10:16:58 -08001715 tagId,
1716 /* metadata */ null,
Tej Singhe19799f2020-05-20 19:14:26 -07001717 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001718 mStatsCallbackImpl
Jeffrey Huangaafccb32020-01-13 10:16:58 -08001719 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001720 }
1721
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001722 int pullBluetoothActivityInfoLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangaafccb32020-01-13 10:16:58 -08001723 BluetoothActivityEnergyInfo info = fetchBluetoothData();
1724 if (info == null) {
1725 return StatsManager.PULL_SKIP;
1726 }
1727 StatsEvent e = StatsEvent.newBuilder()
1728 .setAtomId(atomTag)
1729 .writeLong(info.getTimeStamp())
1730 .writeInt(info.getBluetoothStackState())
1731 .writeLong(info.getControllerTxTimeMillis())
1732 .writeLong(info.getControllerRxTimeMillis())
1733 .writeLong(info.getControllerIdleTimeMillis())
1734 .writeLong(info.getControllerEnergyUsed())
1735 .build();
1736 pulledData.add(e);
1737 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001738 }
1739
1740 private void registerSystemElapsedRealtime() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001741 int tagId = FrameworkStatsLog.SYSTEM_ELAPSED_REALTIME;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001742 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Tej Singh72a70a82020-02-26 23:46:29 -08001743 .setCoolDownMillis(MILLIS_PER_SEC)
1744 .setTimeoutMillis(MILLIS_PER_SEC / 2)
Jeffrey Huang882f99a2020-01-14 14:33:52 -08001745 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001746 mStatsManager.setPullAtomCallback(
Jeffrey Huang882f99a2020-01-14 14:33:52 -08001747 tagId,
1748 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001749 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001750 mStatsCallbackImpl
Jeffrey Huang882f99a2020-01-14 14:33:52 -08001751 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001752 }
1753
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001754 int pullSystemElapsedRealtimeLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang882f99a2020-01-14 14:33:52 -08001755 StatsEvent e = StatsEvent.newBuilder()
1756 .setAtomId(atomTag)
1757 .writeLong(SystemClock.elapsedRealtime())
1758 .build();
1759 pulledData.add(e);
1760 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001761 }
1762
1763 private void registerSystemUptime() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001764 int tagId = FrameworkStatsLog.SYSTEM_UPTIME;
Tej Singh72a70a82020-02-26 23:46:29 -08001765 mStatsManager.setPullAtomCallback(
Ruchir Rastogice29fc12020-01-09 17:08:20 -08001766 tagId,
1767 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07001768 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001769 mStatsCallbackImpl
Ruchir Rastogice29fc12020-01-09 17:08:20 -08001770 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001771 }
1772
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001773 int pullSystemUptimeLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogice29fc12020-01-09 17:08:20 -08001774 StatsEvent e = StatsEvent.newBuilder()
1775 .setAtomId(atomTag)
tsaichristinedc1c34a2020-03-18 14:43:06 -07001776 .writeLong(SystemClock.uptimeMillis())
Ruchir Rastogice29fc12020-01-09 17:08:20 -08001777 .build();
1778 pulledData.add(e);
1779 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001780 }
1781
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001782 private void registerProcessMemoryState() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001783 int tagId = FrameworkStatsLog.PROCESS_MEMORY_STATE;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08001784 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001785 .setAdditiveFields(new int[] {4, 5, 6, 7, 8})
1786 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08001787 mStatsManager.setPullAtomCallback(
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001788 tagId,
1789 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07001790 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001791 mStatsCallbackImpl
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001792 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001793 }
1794
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001795 int pullProcessMemoryStateLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001796 List<ProcessMemoryState> processMemoryStates =
1797 LocalServices.getService(ActivityManagerInternal.class)
1798 .getMemoryStateForProcesses();
1799 for (ProcessMemoryState processMemoryState : processMemoryStates) {
1800 final MemoryStat memoryStat = readMemoryStatFromFilesystem(processMemoryState.uid,
1801 processMemoryState.pid);
1802 if (memoryStat == null) {
1803 continue;
1804 }
1805 StatsEvent e = StatsEvent.newBuilder()
1806 .setAtomId(atomTag)
1807 .writeInt(processMemoryState.uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001808 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001809 .writeString(processMemoryState.processName)
1810 .writeInt(processMemoryState.oomScore)
1811 .writeLong(memoryStat.pgfault)
1812 .writeLong(memoryStat.pgmajfault)
1813 .writeLong(memoryStat.rssInBytes)
1814 .writeLong(memoryStat.cacheInBytes)
1815 .writeLong(memoryStat.swapInBytes)
1816 .writeLong(-1) // unused
1817 .writeLong(-1) // unused
1818 .writeInt(-1) // unused
1819 .build();
1820 pulledData.add(e);
1821 }
1822 return StatsManager.PULL_SUCCESS;
1823 }
1824
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001825 private void registerProcessMemoryHighWaterMark() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001826 int tagId = FrameworkStatsLog.PROCESS_MEMORY_HIGH_WATER_MARK;
Tej Singh72a70a82020-02-26 23:46:29 -08001827 mStatsManager.setPullAtomCallback(
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001828 tagId,
1829 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07001830 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001831 mStatsCallbackImpl
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001832 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001833 }
1834
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001835 int pullProcessMemoryHighWaterMarkLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001836 List<ProcessMemoryState> managedProcessList =
1837 LocalServices.getService(ActivityManagerInternal.class)
1838 .getMemoryStateForProcesses();
1839 for (ProcessMemoryState managedProcess : managedProcessList) {
1840 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(managedProcess.pid);
1841 if (snapshot == null) {
1842 continue;
1843 }
1844 StatsEvent e = StatsEvent.newBuilder()
1845 .setAtomId(atomTag)
1846 .writeInt(managedProcess.uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001847 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001848 .writeString(managedProcess.processName)
1849 // RSS high-water mark in bytes.
1850 .writeLong(snapshot.rssHighWaterMarkInKilobytes * 1024L)
1851 .writeInt(snapshot.rssHighWaterMarkInKilobytes)
1852 .build();
1853 pulledData.add(e);
1854 }
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001855 // Complement the data with native system processes
1856 SparseArray<String> processCmdlines = getProcessCmdlines();
1857 managedProcessList.forEach(managedProcess -> processCmdlines.delete(managedProcess.pid));
1858 int size = processCmdlines.size();
1859 for (int i = 0; i < size; ++i) {
1860 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(processCmdlines.keyAt(i));
Ioannis Ilkose0ec1f32020-06-11 14:56:13 +01001861 if (snapshot == null) {
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001862 continue;
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001863 }
1864 StatsEvent e = StatsEvent.newBuilder()
1865 .setAtomId(atomTag)
1866 .writeInt(snapshot.uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001867 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001868 .writeString(processCmdlines.valueAt(i))
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001869 // RSS high-water mark in bytes.
1870 .writeLong(snapshot.rssHighWaterMarkInKilobytes * 1024L)
1871 .writeInt(snapshot.rssHighWaterMarkInKilobytes)
1872 .build();
1873 pulledData.add(e);
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001874 }
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001875 // Invoke rss_hwm_reset binary to reset RSS HWM counters for all processes.
1876 SystemProperties.set("sys.rss_hwm_reset.on", "1");
1877 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001878 }
1879
1880 private void registerProcessMemorySnapshot() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001881 int tagId = FrameworkStatsLog.PROCESS_MEMORY_SNAPSHOT;
Tej Singh72a70a82020-02-26 23:46:29 -08001882 mStatsManager.setPullAtomCallback(
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001883 tagId,
1884 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07001885 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001886 mStatsCallbackImpl
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001887 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001888 }
1889
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001890 int pullProcessMemorySnapshotLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001891 List<ProcessMemoryState> managedProcessList =
1892 LocalServices.getService(ActivityManagerInternal.class)
1893 .getMemoryStateForProcesses();
1894 for (ProcessMemoryState managedProcess : managedProcessList) {
1895 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(managedProcess.pid);
1896 if (snapshot == null) {
1897 continue;
1898 }
1899 StatsEvent e = StatsEvent.newBuilder()
Ioannis Ilkosda5d8812020-01-27 16:04:10 +00001900 .setAtomId(atomTag)
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001901 .writeInt(managedProcess.uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001902 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001903 .writeString(managedProcess.processName)
1904 .writeInt(managedProcess.pid)
1905 .writeInt(managedProcess.oomScore)
1906 .writeInt(snapshot.rssInKilobytes)
1907 .writeInt(snapshot.anonRssInKilobytes)
1908 .writeInt(snapshot.swapInKilobytes)
1909 .writeInt(snapshot.anonRssInKilobytes + snapshot.swapInKilobytes)
1910 .build();
1911 pulledData.add(e);
1912 }
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001913 // Complement the data with native system processes. Given these measurements can be taken
1914 // in response to LMKs happening, we want to first collect the managed app stats (to
1915 // maximize the probability that a heavyweight process will be sampled before it dies).
1916 SparseArray<String> processCmdlines = getProcessCmdlines();
1917 managedProcessList.forEach(managedProcess -> processCmdlines.delete(managedProcess.pid));
1918 int size = processCmdlines.size();
1919 for (int i = 0; i < size; ++i) {
1920 int pid = processCmdlines.keyAt(i);
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001921 final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(pid);
Ioannis Ilkose0ec1f32020-06-11 14:56:13 +01001922 if (snapshot == null) {
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001923 continue;
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001924 }
1925 StatsEvent e = StatsEvent.newBuilder()
1926 .setAtomId(atomTag)
1927 .writeInt(snapshot.uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07001928 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001929 .writeString(processCmdlines.valueAt(i))
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001930 .writeInt(pid)
1931 .writeInt(-1001) // Placeholder for native processes, OOM_SCORE_ADJ_MIN - 1.
1932 .writeInt(snapshot.rssInKilobytes)
1933 .writeInt(snapshot.anonRssInKilobytes)
1934 .writeInt(snapshot.swapInKilobytes)
1935 .writeInt(snapshot.anonRssInKilobytes + snapshot.swapInKilobytes)
1936 .build();
1937 pulledData.add(e);
Ioannis Ilkos754eb072020-01-27 16:42:24 +00001938 }
Jeffrey Huangb1c16342020-01-15 15:36:42 -08001939 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001940 }
1941
1942 private void registerSystemIonHeapSize() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001943 int tagId = FrameworkStatsLog.SYSTEM_ION_HEAP_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08001944 mStatsManager.setPullAtomCallback(
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001945 tagId,
1946 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07001947 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001948 mStatsCallbackImpl
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001949 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001950 }
1951
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001952 int pullSystemIonHeapSizeLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001953 final long systemIonHeapSizeInBytes = readSystemIonHeapSizeFromDebugfs();
1954 StatsEvent e = StatsEvent.newBuilder()
1955 .setAtomId(atomTag)
1956 .writeLong(systemIonHeapSizeInBytes)
1957 .build();
1958 pulledData.add(e);
1959 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001960 }
1961
Rafal Slawikbdd5a502020-01-14 14:14:29 +00001962 private void registerIonHeapSize() {
Rafal Slawikded83052020-02-28 13:20:13 +00001963 if (!new File("/sys/kernel/ion/total_heaps_kb").exists()) {
1964 return;
1965 }
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001966 int tagId = FrameworkStatsLog.ION_HEAP_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08001967 mStatsManager.setPullAtomCallback(
Rafal Slawikbdd5a502020-01-14 14:14:29 +00001968 tagId,
1969 /* PullAtomMetadata */ null,
Tej Singhe19799f2020-05-20 19:14:26 -07001970 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001971 mStatsCallbackImpl
Rafal Slawikbdd5a502020-01-14 14:14:29 +00001972 );
1973 }
1974
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001975 int pullIonHeapSizeLocked(int atomTag, List<StatsEvent> pulledData) {
Rafal Slawikbdd5a502020-01-14 14:14:29 +00001976 int ionHeapSizeInKilobytes = (int) getIonHeapsSizeKb();
1977 StatsEvent e = StatsEvent.newBuilder()
1978 .setAtomId(atomTag)
1979 .writeInt(ionHeapSizeInKilobytes)
1980 .build();
1981 pulledData.add(e);
1982 return StatsManager.PULL_SUCCESS;
1983 }
1984
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001985 private void registerProcessSystemIonHeapSize() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08001986 int tagId = FrameworkStatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08001987 mStatsManager.setPullAtomCallback(
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001988 tagId,
1989 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07001990 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08001991 mStatsCallbackImpl
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001992 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08001993 }
1994
Ruchir Rastogibba70a62020-06-01 10:43:31 -07001995 int pullProcessSystemIonHeapSizeLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08001996 List<IonAllocations> result = readProcessSystemIonHeapSizesFromDebugfs();
1997 for (IonAllocations allocations : result) {
1998 StatsEvent e = StatsEvent.newBuilder()
1999 .setAtomId(atomTag)
2000 .writeInt(getUidForPid(allocations.pid))
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07002001 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huanga0e1cd22020-01-15 16:05:07 -08002002 .writeString(readCmdlineFromProcfs(allocations.pid))
2003 .writeInt((int) (allocations.totalSizeInBytes / 1024))
2004 .writeInt(allocations.count)
2005 .writeInt((int) (allocations.maxSizeInBytes / 1024))
2006 .build();
2007 pulledData.add(e);
2008 }
2009 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002010 }
2011
2012 private void registerTemperature() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002013 int tagId = FrameworkStatsLog.TEMPERATURE;
Tej Singh72a70a82020-02-26 23:46:29 -08002014 mStatsManager.setPullAtomCallback(
Jeffrey Huangb92de552020-01-15 16:50:07 -08002015 tagId,
2016 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002017 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002018 mStatsCallbackImpl
Jeffrey Huangb92de552020-01-15 16:50:07 -08002019 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002020 }
2021
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002022 int pullTemperatureLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb92de552020-01-15 16:50:07 -08002023 IThermalService thermalService = getIThermalService();
2024 if (thermalService == null) {
2025 return StatsManager.PULL_SKIP;
2026 }
2027 final long callingToken = Binder.clearCallingIdentity();
2028 try {
Chris Ye48dbcaa2020-02-10 13:29:01 -08002029 Temperature temperatures[] = thermalService.getCurrentTemperatures();
Jeffrey Huangb92de552020-01-15 16:50:07 -08002030 for (Temperature temp : temperatures) {
2031 StatsEvent e = StatsEvent.newBuilder()
2032 .setAtomId(atomTag)
2033 .writeInt(temp.getType())
2034 .writeString(temp.getName())
2035 .writeInt((int) (temp.getValue() * 10))
2036 .writeInt(temp.getStatus())
2037 .build();
2038 pulledData.add(e);
2039 }
2040 } catch (RemoteException e) {
2041 // Should not happen.
2042 Slog.e(TAG, "Disconnected from thermal service. Cannot pull temperatures.");
2043 return StatsManager.PULL_SKIP;
2044 } finally {
2045 Binder.restoreCallingIdentity(callingToken);
2046 }
2047 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002048 }
2049
2050 private void registerCoolingDevice() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002051 int tagId = FrameworkStatsLog.COOLING_DEVICE;
Tej Singh72a70a82020-02-26 23:46:29 -08002052 mStatsManager.setPullAtomCallback(
Jeffrey Huangb92de552020-01-15 16:50:07 -08002053 tagId,
2054 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002055 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002056 mStatsCallbackImpl
Jeffrey Huangb92de552020-01-15 16:50:07 -08002057 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002058 }
2059
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002060 int pullCooldownDeviceLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangb92de552020-01-15 16:50:07 -08002061 IThermalService thermalService = getIThermalService();
2062 if (thermalService == null) {
2063 return StatsManager.PULL_SKIP;
2064 }
2065 final long callingToken = Binder.clearCallingIdentity();
2066 try {
Chris Ye48dbcaa2020-02-10 13:29:01 -08002067 CoolingDevice devices[] = thermalService.getCurrentCoolingDevices();
Jeffrey Huangb92de552020-01-15 16:50:07 -08002068 for (CoolingDevice device : devices) {
2069 StatsEvent e = StatsEvent.newBuilder()
2070 .setAtomId(atomTag)
2071 .writeInt(device.getType())
2072 .writeString(device.getName())
2073 .writeInt((int) (device.getValue()))
2074 .build();
2075 pulledData.add(e);
2076 }
2077 } catch (RemoteException e) {
2078 // Should not happen.
2079 Slog.e(TAG, "Disconnected from thermal service. Cannot pull temperatures.");
2080 return StatsManager.PULL_SKIP;
2081 } finally {
2082 Binder.restoreCallingIdentity(callingToken);
2083 }
2084 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002085 }
2086
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002087 private void registerBinderCallsStats() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002088 int tagId = FrameworkStatsLog.BINDER_CALLS;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002089 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002090 .setAdditiveFields(new int[] {4, 5, 6, 8, 12})
2091 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002092 mStatsManager.setPullAtomCallback(
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002093 tagId,
2094 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07002095 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002096 mStatsCallbackImpl
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002097 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002098 }
2099
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002100 int pullBinderCallsStatsLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002101 BinderCallsStatsService.Internal binderStats =
2102 LocalServices.getService(BinderCallsStatsService.Internal.class);
2103 if (binderStats == null) {
2104 Slog.e(TAG, "failed to get binderStats");
2105 return StatsManager.PULL_SKIP;
2106 }
2107
2108 List<ExportedCallStat> callStats = binderStats.getExportedCallStats();
2109 binderStats.reset();
2110 for (ExportedCallStat callStat : callStats) {
2111 StatsEvent e = StatsEvent.newBuilder()
2112 .setAtomId(atomTag)
2113 .writeInt(callStat.workSourceUid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07002114 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002115 .writeString(callStat.className)
2116 .writeString(callStat.methodName)
2117 .writeLong(callStat.callCount)
2118 .writeLong(callStat.exceptionCount)
2119 .writeLong(callStat.latencyMicros)
2120 .writeLong(callStat.maxLatencyMicros)
2121 .writeLong(callStat.cpuTimeMicros)
2122 .writeLong(callStat.maxCpuTimeMicros)
2123 .writeLong(callStat.maxReplySizeBytes)
2124 .writeLong(callStat.maxRequestSizeBytes)
2125 .writeLong(callStat.recordedCallCount)
2126 .writeInt(callStat.screenInteractive ? 1 : 0)
2127 .writeInt(callStat.callingUid)
2128 .build();
2129 pulledData.add(e);
2130 }
2131 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002132 }
2133
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002134 private void registerBinderCallsStatsExceptions() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002135 int tagId = FrameworkStatsLog.BINDER_CALLS_EXCEPTIONS;
Tej Singh72a70a82020-02-26 23:46:29 -08002136 mStatsManager.setPullAtomCallback(
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002137 tagId,
2138 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002139 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002140 mStatsCallbackImpl
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002141 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002142 }
2143
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002144 int pullBinderCallsStatsExceptionsLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang877adfe2020-01-15 17:16:43 -08002145 BinderCallsStatsService.Internal binderStats =
2146 LocalServices.getService(BinderCallsStatsService.Internal.class);
2147 if (binderStats == null) {
2148 Slog.e(TAG, "failed to get binderStats");
2149 return StatsManager.PULL_SKIP;
2150 }
2151
2152 ArrayMap<String, Integer> exceptionStats = binderStats.getExportedExceptionStats();
2153 // TODO: decouple binder calls exceptions with the rest of the binder calls data so that we
2154 // can reset the exception stats.
2155 for (Map.Entry<String, Integer> entry : exceptionStats.entrySet()) {
2156 StatsEvent e = StatsEvent.newBuilder()
2157 .setAtomId(atomTag)
2158 .writeString(entry.getKey())
2159 .writeInt(entry.getValue())
2160 .build();
2161 pulledData.add(e);
2162 }
2163 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002164 }
2165
2166 private void registerLooperStats() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002167 int tagId = FrameworkStatsLog.LOOPER_STATS;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002168 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangfd037c52020-01-16 10:42:59 -08002169 .setAdditiveFields(new int[] {5, 6, 7, 8, 9})
2170 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002171 mStatsManager.setPullAtomCallback(
Jeffrey Huangfd037c52020-01-16 10:42:59 -08002172 tagId,
2173 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07002174 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002175 mStatsCallbackImpl
Jeffrey Huangfd037c52020-01-16 10:42:59 -08002176 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002177 }
2178
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002179 int pullLooperStatsLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangfd037c52020-01-16 10:42:59 -08002180 LooperStats looperStats = LocalServices.getService(LooperStats.class);
2181 if (looperStats == null) {
2182 return StatsManager.PULL_SKIP;
2183 }
2184
2185 List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
2186 looperStats.reset();
2187 for (LooperStats.ExportedEntry entry : entries) {
2188 StatsEvent e = StatsEvent.newBuilder()
2189 .setAtomId(atomTag)
2190 .writeInt(entry.workSourceUid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07002191 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangfd037c52020-01-16 10:42:59 -08002192 .writeString(entry.handlerClassName)
2193 .writeString(entry.threadName)
2194 .writeString(entry.messageName)
2195 .writeLong(entry.messageCount)
2196 .writeLong(entry.exceptionCount)
2197 .writeLong(entry.recordedMessageCount)
2198 .writeLong(entry.totalLatencyMicros)
2199 .writeLong(entry.cpuUsageMicros)
2200 .writeBoolean(entry.isInteractive)
2201 .writeLong(entry.maxCpuUsageMicros)
2202 .writeLong(entry.maxLatencyMicros)
2203 .writeLong(entry.recordedDelayMessageCount)
2204 .writeLong(entry.delayMillis)
2205 .writeLong(entry.maxDelayMillis)
2206 .build();
2207 pulledData.add(e);
2208 }
2209 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002210 }
2211
2212 private void registerDiskStats() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002213 int tagId = FrameworkStatsLog.DISK_STATS;
Tej Singh72a70a82020-02-26 23:46:29 -08002214 mStatsManager.setPullAtomCallback(
Jeffrey Huang95765f02020-01-16 11:33:58 -08002215 tagId,
2216 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002217 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002218 mStatsCallbackImpl
Jeffrey Huang95765f02020-01-16 11:33:58 -08002219 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002220 }
2221
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002222 int pullDiskStatsLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang95765f02020-01-16 11:33:58 -08002223 // Run a quick-and-dirty performance test: write 512 bytes
2224 byte[] junk = new byte[512];
2225 for (int i = 0; i < junk.length; i++) junk[i] = (byte) i; // Write nonzero bytes
2226
2227 File tmp = new File(Environment.getDataDirectory(), "system/statsdperftest.tmp");
2228 FileOutputStream fos = null;
2229 IOException error = null;
2230
2231 long before = SystemClock.elapsedRealtime();
2232 try {
2233 fos = new FileOutputStream(tmp);
2234 fos.write(junk);
2235 } catch (IOException e) {
2236 error = e;
2237 } finally {
2238 try {
2239 if (fos != null) fos.close();
2240 } catch (IOException e) {
2241 // Do nothing.
2242 }
2243 }
2244
2245 long latency = SystemClock.elapsedRealtime() - before;
2246 if (tmp.exists()) tmp.delete();
2247
2248 if (error != null) {
2249 Slog.e(TAG, "Error performing diskstats latency test");
2250 latency = -1;
2251 }
2252 // File based encryption.
2253 boolean fileBased = StorageManager.isFileEncryptedNativeOnly();
2254
2255 //Recent disk write speed. Binder call to storaged.
2256 int writeSpeed = -1;
2257 IStoraged storaged = getIStoragedService();
2258 if (storaged == null) {
2259 return StatsManager.PULL_SKIP;
2260 }
2261 try {
2262 writeSpeed = storaged.getRecentPerf();
2263 } catch (RemoteException e) {
2264 Slog.e(TAG, "storaged not found");
2265 }
2266
2267 // Add info pulledData.
2268 StatsEvent e = StatsEvent.newBuilder()
2269 .setAtomId(atomTag)
2270 .writeLong(latency)
2271 .writeBoolean(fileBased)
2272 .writeInt(writeSpeed)
2273 .build();
2274 pulledData.add(e);
2275 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002276 }
2277
2278 private void registerDirectoryUsage() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002279 int tagId = FrameworkStatsLog.DIRECTORY_USAGE;
Tej Singh72a70a82020-02-26 23:46:29 -08002280 mStatsManager.setPullAtomCallback(
Jeffrey Huang95765f02020-01-16 11:33:58 -08002281 tagId,
2282 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002283 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002284 mStatsCallbackImpl
Jeffrey Huang95765f02020-01-16 11:33:58 -08002285 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002286 }
2287
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002288 int pullDirectoryUsageLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang95765f02020-01-16 11:33:58 -08002289 StatFs statFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath());
2290 StatFs statFsSystem = new StatFs(Environment.getRootDirectory().getAbsolutePath());
2291 StatFs statFsCache = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath());
2292
2293 StatsEvent e = StatsEvent.newBuilder()
2294 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002295 .writeInt(FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__DATA)
Jeffrey Huang95765f02020-01-16 11:33:58 -08002296 .writeLong(statFsData.getAvailableBytes())
2297 .writeLong(statFsData.getTotalBytes())
2298 .build();
2299 pulledData.add(e);
2300
2301 e = StatsEvent.newBuilder()
2302 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002303 .writeInt(FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__CACHE)
Jeffrey Huang95765f02020-01-16 11:33:58 -08002304 .writeLong(statFsCache.getAvailableBytes())
2305 .writeLong(statFsCache.getTotalBytes())
2306 .build();
2307 pulledData.add(e);
2308
2309 e = StatsEvent.newBuilder()
2310 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002311 .writeInt(FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__SYSTEM)
Jeffrey Huang95765f02020-01-16 11:33:58 -08002312 .writeLong(statFsSystem.getAvailableBytes())
2313 .writeLong(statFsSystem.getTotalBytes())
2314 .build();
2315 pulledData.add(e);
2316 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002317 }
2318
2319 private void registerAppSize() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002320 int tagId = FrameworkStatsLog.APP_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08002321 mStatsManager.setPullAtomCallback(
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002322 tagId,
2323 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002324 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002325 mStatsCallbackImpl
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002326 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002327 }
2328
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002329 int pullAppSizeLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002330 try {
2331 String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
2332 JSONObject json = new JSONObject(jsonStr);
2333 long cache_time = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L);
2334 JSONArray pkg_names = json.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY);
2335 JSONArray app_sizes = json.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY);
2336 JSONArray app_data_sizes = json.getJSONArray(DiskStatsFileLogger.APP_DATA_KEY);
2337 JSONArray app_cache_sizes = json.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY);
2338 // Sanity check: Ensure all 4 lists have the same length.
2339 int length = pkg_names.length();
2340 if (app_sizes.length() != length || app_data_sizes.length() != length
2341 || app_cache_sizes.length() != length) {
2342 Slog.e(TAG, "formatting error in diskstats cache file!");
2343 return StatsManager.PULL_SKIP;
2344 }
2345 for (int i = 0; i < length; i++) {
2346 StatsEvent e = StatsEvent.newBuilder()
2347 .setAtomId(atomTag)
2348 .writeString(pkg_names.getString(i))
2349 .writeLong(app_sizes.optLong(i, /* fallback */ -1L))
2350 .writeLong(app_data_sizes.optLong(i, /* fallback */ -1L))
2351 .writeLong(app_cache_sizes.optLong(i, /* fallback */ -1L))
2352 .writeLong(cache_time)
2353 .build();
2354 pulledData.add(e);
2355 }
2356 } catch (IOException | JSONException e) {
Ruchir Rastogie965f4a2020-06-05 08:32:05 -07002357 Slog.w(TAG, "Unable to read diskstats cache file within pullAppSize");
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002358 return StatsManager.PULL_SKIP;
2359 }
2360 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002361 }
2362
2363 private void registerCategorySize() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002364 int tagId = FrameworkStatsLog.CATEGORY_SIZE;
Tej Singh72a70a82020-02-26 23:46:29 -08002365 mStatsManager.setPullAtomCallback(
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002366 tagId,
2367 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002368 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002369 mStatsCallbackImpl
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002370 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002371 }
2372
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002373 int pullCategorySizeLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002374 try {
2375 String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
2376 JSONObject json = new JSONObject(jsonStr);
2377 long cacheTime = json.optLong(
2378 DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, /* fallback */ -1L);
2379
2380 StatsEvent e = StatsEvent.newBuilder()
2381 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002382 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__APP_SIZE)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002383 .writeLong(json.optLong(
2384 DiskStatsFileLogger.APP_SIZE_AGG_KEY, /* fallback */ -1L))
2385 .writeLong(cacheTime)
2386 .build();
2387 pulledData.add(e);
2388
2389 e = StatsEvent.newBuilder()
2390 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002391 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__APP_DATA_SIZE)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002392 .writeLong(json.optLong(
2393 DiskStatsFileLogger.APP_DATA_SIZE_AGG_KEY, /* fallback */ -1L))
2394 .writeLong(cacheTime)
2395 .build();
2396 pulledData.add(e);
2397
2398 e = StatsEvent.newBuilder()
2399 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002400 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__APP_CACHE_SIZE)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002401 .writeLong(json.optLong(
2402 DiskStatsFileLogger.APP_CACHE_AGG_KEY, /* fallback */ -1L))
2403 .writeLong(cacheTime)
2404 .build();
2405 pulledData.add(e);
2406
2407 e = StatsEvent.newBuilder()
2408 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002409 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__PHOTOS)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002410 .writeLong(json.optLong(
2411 DiskStatsFileLogger.PHOTOS_KEY, /* fallback */ -1L))
2412 .writeLong(cacheTime)
2413 .build();
2414 pulledData.add(e);
2415
2416 e = StatsEvent.newBuilder()
2417 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002418 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__VIDEOS)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002419 .writeLong(
2420 json.optLong(DiskStatsFileLogger.VIDEOS_KEY, /* fallback */ -1L))
2421 .writeLong(cacheTime)
2422 .build();
2423 pulledData.add(e);
2424
2425 e = StatsEvent.newBuilder()
2426 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002427 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__AUDIO)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002428 .writeLong(json.optLong(
2429 DiskStatsFileLogger.AUDIO_KEY, /* fallback */ -1L))
2430 .writeLong(cacheTime)
2431 .build();
2432 pulledData.add(e);
2433
2434 e = StatsEvent.newBuilder()
2435 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002436 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__DOWNLOADS)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002437 .writeLong(
2438 json.optLong(DiskStatsFileLogger.DOWNLOADS_KEY, /* fallback */ -1L))
2439 .writeLong(cacheTime)
2440 .build();
2441 pulledData.add(e);
2442
2443 e = StatsEvent.newBuilder()
Tej Singh5dd1dc92020-01-29 20:44:42 -08002444 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002445 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__SYSTEM)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002446 .writeLong(json.optLong(
2447 DiskStatsFileLogger.SYSTEM_KEY, /* fallback */ -1L))
2448 .writeLong(cacheTime)
2449 .build();
2450 pulledData.add(e);
2451
2452 e = StatsEvent.newBuilder()
2453 .setAtomId(atomTag)
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002454 .writeInt(FrameworkStatsLog.CATEGORY_SIZE__CATEGORY__OTHER)
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002455 .writeLong(json.optLong(
2456 DiskStatsFileLogger.MISC_KEY, /* fallback */ -1L))
2457 .writeLong(cacheTime)
2458 .build();
2459 pulledData.add(e);
2460 } catch (IOException | JSONException e) {
Ruchir Rastogie965f4a2020-06-05 08:32:05 -07002461 Slog.w(TAG, "Unable to read diskstats cache file within pullCategorySize");
Jeffrey Huange85d7ad2020-01-16 13:02:22 -08002462 return StatsManager.PULL_SKIP;
2463 }
2464 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002465 }
2466
2467 private void registerNumFingerprintsEnrolled() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002468 int tagId = FrameworkStatsLog.NUM_FINGERPRINTS_ENROLLED;
Tej Singh72a70a82020-02-26 23:46:29 -08002469 mStatsManager.setPullAtomCallback(
Jeffrey Huang597a8862020-01-16 14:56:37 -08002470 tagId,
2471 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002472 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002473 mStatsCallbackImpl
Jeffrey Huang597a8862020-01-16 14:56:37 -08002474 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002475 }
2476
2477 private void registerNumFacesEnrolled() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002478 int tagId = FrameworkStatsLog.NUM_FACES_ENROLLED;
Tej Singh72a70a82020-02-26 23:46:29 -08002479 mStatsManager.setPullAtomCallback(
Jeffrey Huang597a8862020-01-16 14:56:37 -08002480 tagId,
2481 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002482 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002483 mStatsCallbackImpl
Jeffrey Huang597a8862020-01-16 14:56:37 -08002484 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002485 }
2486
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002487 private int pullNumBiometricsEnrolledLocked(int modality, int atomTag,
2488 List<StatsEvent> pulledData) {
Jeffrey Huang597a8862020-01-16 14:56:37 -08002489 final PackageManager pm = mContext.getPackageManager();
2490 FingerprintManager fingerprintManager = null;
2491 FaceManager faceManager = null;
2492
2493 if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
2494 fingerprintManager = mContext.getSystemService(FingerprintManager.class);
2495 }
2496 if (pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
2497 faceManager = mContext.getSystemService(FaceManager.class);
2498 }
2499
2500 if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT && fingerprintManager == null) {
2501 return StatsManager.PULL_SKIP;
2502 }
2503 if (modality == BiometricsProtoEnums.MODALITY_FACE && faceManager == null) {
2504 return StatsManager.PULL_SKIP;
2505 }
2506 UserManager userManager = mContext.getSystemService(UserManager.class);
2507 if (userManager == null) {
2508 return StatsManager.PULL_SKIP;
2509 }
2510
2511 final long token = Binder.clearCallingIdentity();
2512 try {
2513 for (UserInfo user : userManager.getUsers()) {
2514 final int userId = user.getUserHandle().getIdentifier();
2515 int numEnrolled = 0;
2516 if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT) {
2517 numEnrolled = fingerprintManager.getEnrolledFingerprints(userId).size();
2518 } else if (modality == BiometricsProtoEnums.MODALITY_FACE) {
2519 numEnrolled = faceManager.getEnrolledFaces(userId).size();
2520 } else {
2521 return StatsManager.PULL_SKIP;
2522 }
2523 StatsEvent e = StatsEvent.newBuilder()
2524 .setAtomId(atomTag)
2525 .writeInt(userId)
2526 .writeInt(numEnrolled)
2527 .build();
2528 pulledData.add(e);
2529 }
2530 } finally {
2531 Binder.restoreCallingIdentity(token);
2532 }
2533 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002534 }
2535
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002536 private void registerProcStats() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002537 int tagId = FrameworkStatsLog.PROC_STATS;
Tej Singh72a70a82020-02-26 23:46:29 -08002538 mStatsManager.setPullAtomCallback(
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002539 tagId,
2540 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002541 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002542 mStatsCallbackImpl
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002543 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002544 }
2545
2546 private void registerProcStatsPkgProc() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002547 int tagId = FrameworkStatsLog.PROC_STATS_PKG_PROC;
Tej Singh72a70a82020-02-26 23:46:29 -08002548 mStatsManager.setPullAtomCallback(
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002549 tagId,
2550 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002551 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002552 mStatsCallbackImpl
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002553 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002554 }
2555
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002556 private int pullProcStatsLocked(int section, int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002557 IProcessStats processStatsService = getIProcessStatsService();
2558 if (processStatsService == null) {
2559 return StatsManager.PULL_SKIP;
2560 }
2561
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002562 final long token = Binder.clearCallingIdentity();
2563 try {
2564 // force procstats to flush & combine old files into one store
2565 long lastHighWaterMark = readProcStatsHighWaterMark(section);
2566 List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
Richard Gaywood863a7212020-03-16 17:49:54 +00002567
Richard Gaywood52a2edf2020-06-14 17:39:15 +01002568 ProtoOutputStream[] protoStreams = new ProtoOutputStream[MAX_PROCSTATS_SHARDS];
2569 for (int i = 0; i < protoStreams.length; i++) {
2570 protoStreams[i] = new ProtoOutputStream();
2571 }
2572
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002573 ProcessStats procStats = new ProcessStats(false);
Richard Gaywood52a2edf2020-06-14 17:39:15 +01002574 // Force processStatsService to aggregate all in-storage and in-memory data.
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002575 long highWaterMark = processStatsService.getCommittedStatsMerged(
2576 lastHighWaterMark, section, true, statsFiles, procStats);
Richard Gaywood52a2edf2020-06-14 17:39:15 +01002577 procStats.dumpAggregatedProtoForStatsd(protoStreams, MAX_PROCSTATS_RAW_SHARD_SIZE);
Richard Gaywood863a7212020-03-16 17:49:54 +00002578
Richard Gaywood52a2edf2020-06-14 17:39:15 +01002579 for (ProtoOutputStream proto : protoStreams) {
2580 if (proto.getBytes().length > 0) {
2581 StatsEvent e = StatsEvent.newBuilder()
2582 .setAtomId(atomTag)
2583 .writeByteArray(proto.getBytes())
2584 .build();
2585 pulledData.add(e);
2586 }
2587 }
Richard Gaywood863a7212020-03-16 17:49:54 +00002588
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002589 new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + lastHighWaterMark)
2590 .delete();
2591 new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + highWaterMark)
2592 .createNewFile();
2593 } catch (RemoteException | IOException e) {
2594 Slog.e(TAG, "Getting procstats failed: ", e);
2595 return StatsManager.PULL_SKIP;
2596 } finally {
2597 Binder.restoreCallingIdentity(token);
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002598 }
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002599 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002600 }
2601
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002602 // read high watermark for section
2603 private long readProcStatsHighWaterMark(int section) {
2604 try {
2605 File[] files = mBaseDir.listFiles((d, name) -> {
2606 return name.toLowerCase().startsWith(String.valueOf(section) + '_');
2607 });
2608 if (files == null || files.length == 0) {
2609 return 0;
2610 }
2611 if (files.length > 1) {
2612 Slog.e(TAG, "Only 1 file expected for high water mark. Found " + files.length);
2613 }
2614 return Long.valueOf(files[0].getName().split("_")[1]);
2615 } catch (SecurityException e) {
2616 Slog.e(TAG, "Failed to get procstats high watermark file.", e);
2617 } catch (NumberFormatException e) {
2618 Slog.e(TAG, "Failed to parse file name.", e);
2619 }
2620 return 0;
2621 }
2622
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002623 private void registerDiskIO() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002624 int tagId = FrameworkStatsLog.DISK_IO;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002625 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002626 .setAdditiveFields(new int[] {2, 3, 4, 5, 6, 7, 8, 9, 10, 11})
Tej Singh72a70a82020-02-26 23:46:29 -08002627 .setCoolDownMillis(3 * MILLIS_PER_SEC)
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002628 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002629 mStatsManager.setPullAtomCallback(
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002630 tagId,
2631 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07002632 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002633 mStatsCallbackImpl
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002634 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002635 }
2636
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002637 int pullDiskIOLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002638 mStoragedUidIoStatsReader.readAbsolute((uid, fgCharsRead, fgCharsWrite, fgBytesRead,
2639 fgBytesWrite, bgCharsRead, bgCharsWrite, bgBytesRead, bgBytesWrite,
2640 fgFsync, bgFsync) -> {
2641 StatsEvent e = StatsEvent.newBuilder()
2642 .setAtomId(atomTag)
2643 .writeInt(uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07002644 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Jeffrey Huangfdc53692020-01-14 15:17:30 -08002645 .writeLong(fgCharsRead)
2646 .writeLong(fgCharsWrite)
2647 .writeLong(fgBytesRead)
2648 .writeLong(fgBytesWrite)
2649 .writeLong(bgCharsRead)
2650 .writeLong(bgCharsWrite)
2651 .writeLong(bgBytesRead)
2652 .writeLong(bgBytesWrite)
2653 .writeLong(fgFsync)
2654 .writeLong(bgFsync)
2655 .build();
2656 pulledData.add(e);
2657 });
2658 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002659 }
2660
2661 private void registerPowerProfile() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002662 int tagId = FrameworkStatsLog.POWER_PROFILE;
Tej Singh72a70a82020-02-26 23:46:29 -08002663 mStatsManager.setPullAtomCallback(
Jeffrey Huang1a3935c2020-01-13 10:51:17 -08002664 tagId,
2665 /* PullAtomMetadata */ null,
Tej Singhe19799f2020-05-20 19:14:26 -07002666 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002667 mStatsCallbackImpl
Jeffrey Huang1a3935c2020-01-13 10:51:17 -08002668 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002669 }
2670
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002671 int pullPowerProfileLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang1a3935c2020-01-13 10:51:17 -08002672 PowerProfile powerProfile = new PowerProfile(mContext);
2673 ProtoOutputStream proto = new ProtoOutputStream();
2674 powerProfile.dumpDebug(proto);
2675 proto.flush();
2676 StatsEvent e = StatsEvent.newBuilder()
2677 .setAtomId(atomTag)
2678 .writeByteArray(proto.getBytes())
2679 .build();
2680 pulledData.add(e);
2681 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002682 }
2683
2684 private void registerProcessCpuTime() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002685 int tagId = FrameworkStatsLog.PROCESS_CPU_TIME;
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08002686 // Min cool-down is 5 sec, in line with what ActivityManagerService uses.
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002687 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Tej Singh72a70a82020-02-26 23:46:29 -08002688 .setCoolDownMillis(5 * MILLIS_PER_SEC)
Jeffrey Huang7a9ae132020-01-14 15:44:58 -08002689 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002690 mStatsManager.setPullAtomCallback(
Jeffrey Huang7a9ae132020-01-14 15:44:58 -08002691 tagId,
2692 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07002693 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002694 mStatsCallbackImpl
Jeffrey Huang7a9ae132020-01-14 15:44:58 -08002695 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002696 }
2697
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002698 int pullProcessCpuTimeLocked(int atomTag, List<StatsEvent> pulledData) {
2699 if (mProcessCpuTracker == null) {
2700 mProcessCpuTracker = new ProcessCpuTracker(false);
2701 mProcessCpuTracker.init();
2702 }
2703 mProcessCpuTracker.update();
2704 for (int i = 0; i < mProcessCpuTracker.countStats(); i++) {
2705 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2706 StatsEvent e = StatsEvent.newBuilder()
2707 .setAtomId(atomTag)
2708 .writeInt(st.uid)
2709 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
2710 .writeString(st.name)
2711 .writeLong(st.base_utime)
2712 .writeLong(st.base_stime)
2713 .build();
2714 pulledData.add(e);
Jeffrey Huang7a9ae132020-01-14 15:44:58 -08002715 }
2716 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002717 }
2718
2719 private void registerCpuTimePerThreadFreq() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002720 int tagId = FrameworkStatsLog.CPU_TIME_PER_THREAD_FREQ;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002721 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Jeffrey Huangbf4eef82020-01-16 15:38:58 -08002722 .setAdditiveFields(new int[] {7, 9, 11, 13, 15, 17, 19, 21})
2723 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002724 mStatsManager.setPullAtomCallback(
Jeffrey Huangbf4eef82020-01-16 15:38:58 -08002725 tagId,
2726 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07002727 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002728 mStatsCallbackImpl
Jeffrey Huangbf4eef82020-01-16 15:38:58 -08002729 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002730 }
2731
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002732 int pullCpuTimePerThreadFreqLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huangbf4eef82020-01-16 15:38:58 -08002733 if (this.mKernelCpuThreadReader == null) {
2734 Slog.e(TAG, "mKernelCpuThreadReader is null");
2735 return StatsManager.PULL_SKIP;
2736 }
2737 ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages =
2738 this.mKernelCpuThreadReader.getProcessCpuUsageDiffed();
2739 if (processCpuUsages == null) {
2740 Slog.e(TAG, "processCpuUsages is null");
2741 return StatsManager.PULL_SKIP;
2742 }
2743 int[] cpuFrequencies = mKernelCpuThreadReader.getCpuFrequenciesKhz();
2744 if (cpuFrequencies.length > CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES) {
2745 String message = "Expected maximum " + CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES
2746 + " frequencies, but got " + cpuFrequencies.length;
2747 Slog.w(TAG, message);
2748 return StatsManager.PULL_SKIP;
2749 }
2750 for (int i = 0; i < processCpuUsages.size(); i++) {
2751 KernelCpuThreadReader.ProcessCpuUsage processCpuUsage = processCpuUsages.get(i);
2752 ArrayList<KernelCpuThreadReader.ThreadCpuUsage> threadCpuUsages =
2753 processCpuUsage.threadCpuUsages;
2754 for (int j = 0; j < threadCpuUsages.size(); j++) {
2755 KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage = threadCpuUsages.get(j);
2756 if (threadCpuUsage.usageTimesMillis.length != cpuFrequencies.length) {
2757 String message = "Unexpected number of usage times,"
2758 + " expected " + cpuFrequencies.length
2759 + " but got " + threadCpuUsage.usageTimesMillis.length;
2760 Slog.w(TAG, message);
2761 return StatsManager.PULL_SKIP;
2762 }
2763
2764 StatsEvent.Builder e = StatsEvent.newBuilder();
2765 e.setAtomId(atomTag);
2766 e.writeInt(processCpuUsage.uid);
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07002767 e.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
Jeffrey Huangbf4eef82020-01-16 15:38:58 -08002768 e.writeInt(processCpuUsage.processId);
2769 e.writeInt(threadCpuUsage.threadId);
2770 e.writeString(processCpuUsage.processName);
2771 e.writeString(threadCpuUsage.threadName);
2772 for (int k = 0; k < CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES; k++) {
2773 if (k < cpuFrequencies.length) {
2774 e.writeInt(cpuFrequencies[k]);
2775 e.writeInt(threadCpuUsage.usageTimesMillis[k]);
2776 } else {
2777 // If we have no more frequencies to write, we still must write empty data.
2778 // We know that this data is empty (and not just zero) because all
2779 // frequencies are expected to be greater than zero
2780 e.writeInt(0);
2781 e.writeInt(0);
2782 }
2783 }
2784 pulledData.add(e.build());
2785 }
2786 }
2787 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002788 }
2789
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002790 private BatteryStatsHelper getBatteryStatsHelper() {
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002791 synchronized (mBatteryStatsHelperLock) {
2792 if (mBatteryStatsHelper == null) {
2793 final long callingToken = Binder.clearCallingIdentity();
2794 try {
2795 // clearCallingIdentity required for BatteryStatsHelper.checkWifiOnly().
2796 mBatteryStatsHelper = new BatteryStatsHelper(mContext, false);
2797 } finally {
2798 Binder.restoreCallingIdentity(callingToken);
2799 }
2800 mBatteryStatsHelper.create((Bundle) null);
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002801 }
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002802 long currentTime = SystemClock.elapsedRealtime();
2803 if (currentTime - mBatteryStatsHelperTimestampMs
2804 >= MAX_BATTERY_STATS_HELPER_FREQUENCY_MS) {
2805 // Load BatteryStats and do all the calculations.
2806 mBatteryStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED,
2807 UserHandle.USER_ALL);
2808 // Calculations are done so we don't need to save the raw BatteryStats data in RAM.
2809 mBatteryStatsHelper.clearStats();
2810 mBatteryStatsHelperTimestampMs = currentTime;
2811 }
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002812 }
2813 return mBatteryStatsHelper;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002814 }
2815
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002816 private long milliAmpHrsToNanoAmpSecs(double mAh) {
2817 return (long) (mAh * MILLI_AMP_HR_TO_NANO_AMP_SECS + 0.5);
2818 }
2819
2820 private void registerDeviceCalculatedPowerUse() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002821 int tagId = FrameworkStatsLog.DEVICE_CALCULATED_POWER_USE;
Tej Singh72a70a82020-02-26 23:46:29 -08002822 mStatsManager.setPullAtomCallback(
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002823 tagId,
2824 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002825 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002826 mStatsCallbackImpl
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002827 );
2828 }
2829
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002830 int pullDeviceCalculatedPowerUseLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002831 BatteryStatsHelper bsHelper = getBatteryStatsHelper();
2832 StatsEvent e = StatsEvent.newBuilder()
2833 .setAtomId(atomTag)
2834 .writeLong(milliAmpHrsToNanoAmpSecs(bsHelper.getComputedPower()))
2835 .build();
2836 pulledData.add(e);
2837 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002838 }
2839
2840 private void registerDeviceCalculatedPowerBlameUid() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002841 int tagId = FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_UID;
Tej Singh72a70a82020-02-26 23:46:29 -08002842 mStatsManager.setPullAtomCallback(
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002843 tagId,
2844 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002845 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002846 mStatsCallbackImpl
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002847 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002848 }
2849
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002850 int pullDeviceCalculatedPowerBlameUidLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002851 final List<BatterySipper> sippers = getBatteryStatsHelper().getUsageList();
2852 if (sippers == null) {
2853 return StatsManager.PULL_SKIP;
2854 }
2855
2856 for (BatterySipper bs : sippers) {
2857 if (bs.drainType != bs.drainType.APP) {
2858 continue;
2859 }
2860 StatsEvent e = StatsEvent.newBuilder()
2861 .setAtomId(atomTag)
2862 .writeInt(bs.uidObj.getUid())
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07002863 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002864 .writeLong(milliAmpHrsToNanoAmpSecs(bs.totalPowerMah))
2865 .build();
2866 pulledData.add(e);
2867 }
2868 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002869 }
2870
2871 private void registerDeviceCalculatedPowerBlameOther() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002872 int tagId = FrameworkStatsLog.DEVICE_CALCULATED_POWER_BLAME_OTHER;
Tej Singh72a70a82020-02-26 23:46:29 -08002873 mStatsManager.setPullAtomCallback(
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002874 tagId,
2875 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002876 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002877 mStatsCallbackImpl
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002878 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002879 }
2880
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002881 int pullDeviceCalculatedPowerBlameOtherLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi5ea31632020-01-13 16:42:12 -08002882 final List<BatterySipper> sippers = getBatteryStatsHelper().getUsageList();
2883 if (sippers == null) {
2884 return StatsManager.PULL_SKIP;
2885 }
2886
2887 for (BatterySipper bs : sippers) {
2888 if (bs.drainType == bs.drainType.APP) {
2889 continue; // This is a separate atom; see pullDeviceCalculatedPowerBlameUid().
2890 }
2891 if (bs.drainType == bs.drainType.USER) {
2892 continue; // This is not supported. We purposefully calculate over USER_ALL.
2893 }
2894 StatsEvent e = StatsEvent.newBuilder()
2895 .setAtomId(atomTag)
2896 .writeInt(bs.drainType.ordinal())
2897 .writeLong(milliAmpHrsToNanoAmpSecs(bs.totalPowerMah))
2898 .build();
2899 pulledData.add(e);
2900 }
2901 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002902 }
2903
2904 private void registerDebugElapsedClock() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002905 int tagId = FrameworkStatsLog.DEBUG_ELAPSED_CLOCK;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002906 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002907 .setAdditiveFields(new int[] {1, 2, 3, 4})
2908 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002909 mStatsManager.setPullAtomCallback(
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002910 tagId,
2911 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07002912 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002913 mStatsCallbackImpl
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002914 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002915 }
2916
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002917 int pullDebugElapsedClockLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002918 final long elapsedMillis = SystemClock.elapsedRealtime();
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002919 final long clockDiffMillis = mDebugElapsedClockPreviousValue == 0
2920 ? 0 : elapsedMillis - mDebugElapsedClockPreviousValue;
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002921
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002922 StatsEvent e = StatsEvent.newBuilder()
2923 .setAtomId(atomTag)
2924 .writeLong(mDebugElapsedClockPullCount)
2925 .writeLong(elapsedMillis)
2926 // Log it twice to be able to test multi-value aggregation from ValueMetric.
2927 .writeLong(elapsedMillis)
2928 .writeLong(clockDiffMillis)
2929 .writeInt(1 /* always set */)
2930 .build();
2931 pulledData.add(e);
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002932
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002933 if (mDebugElapsedClockPullCount % 2 == 1) {
2934 StatsEvent e2 = StatsEvent.newBuilder()
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002935 .setAtomId(atomTag)
2936 .writeLong(mDebugElapsedClockPullCount)
2937 .writeLong(elapsedMillis)
2938 // Log it twice to be able to test multi-value aggregation from ValueMetric.
2939 .writeLong(elapsedMillis)
2940 .writeLong(clockDiffMillis)
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002941 .writeInt(2 /* set on odd pulls */)
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002942 .build();
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002943 pulledData.add(e2);
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002944 }
2945
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002946 mDebugElapsedClockPullCount++;
2947 mDebugElapsedClockPreviousValue = elapsedMillis;
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002948 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002949 }
2950
2951 private void registerDebugFailingElapsedClock() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002952 int tagId = FrameworkStatsLog.DEBUG_FAILING_ELAPSED_CLOCK;
Jeffrey Huanga85d8f92020-01-24 13:28:45 -08002953 PullAtomMetadata metadata = new PullAtomMetadata.Builder()
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002954 .setAdditiveFields(new int[] {1, 2, 3, 4})
2955 .build();
Tej Singh72a70a82020-02-26 23:46:29 -08002956 mStatsManager.setPullAtomCallback(
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002957 tagId,
2958 metadata,
Tej Singhe19799f2020-05-20 19:14:26 -07002959 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002960 mStatsCallbackImpl
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002961 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002962 }
2963
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002964 int pullDebugFailingElapsedClockLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002965 final long elapsedMillis = SystemClock.elapsedRealtime();
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002966 // Fails every 5 buckets.
2967 if (mDebugFailingElapsedClockPullCount++ % 5 == 0) {
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002968 mDebugFailingElapsedClockPreviousValue = elapsedMillis;
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002969 Slog.e(TAG, "Failing debug elapsed clock");
2970 return StatsManager.PULL_SKIP;
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002971 }
2972
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002973 StatsEvent e = StatsEvent.newBuilder()
2974 .setAtomId(atomTag)
2975 .writeLong(mDebugFailingElapsedClockPullCount)
2976 .writeLong(elapsedMillis)
2977 // Log it twice to be able to test multi-value aggregation from ValueMetric.
2978 .writeLong(elapsedMillis)
2979 .writeLong(mDebugFailingElapsedClockPreviousValue == 0
2980 ? 0 : elapsedMillis - mDebugFailingElapsedClockPreviousValue)
2981 .build();
2982 pulledData.add(e);
2983
2984 mDebugFailingElapsedClockPreviousValue = elapsedMillis;
Ruchir Rastogid428dfb2020-01-14 16:51:55 -08002985 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002986 }
2987
2988 private void registerBuildInformation() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08002989 int tagId = FrameworkStatsLog.BUILD_INFORMATION;
Tej Singh72a70a82020-02-26 23:46:29 -08002990 mStatsManager.setPullAtomCallback(
Ruchir Rastogi425d8362020-01-14 23:51:46 -08002991 tagId,
2992 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07002993 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08002994 mStatsCallbackImpl
Ruchir Rastogi425d8362020-01-14 23:51:46 -08002995 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08002996 }
2997
Ruchir Rastogibba70a62020-06-01 10:43:31 -07002998 int pullBuildInformationLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi425d8362020-01-14 23:51:46 -08002999 StatsEvent e = StatsEvent.newBuilder()
3000 .setAtomId(atomTag)
3001 .writeString(Build.FINGERPRINT)
3002 .writeString(Build.BRAND)
3003 .writeString(Build.PRODUCT)
3004 .writeString(Build.DEVICE)
Dianne Hackborndb007452019-10-28 16:34:22 -07003005 .writeString(Build.VERSION.RELEASE_OR_CODENAME)
Ruchir Rastogi425d8362020-01-14 23:51:46 -08003006 .writeString(Build.ID)
3007 .writeString(Build.VERSION.INCREMENTAL)
3008 .writeString(Build.TYPE)
3009 .writeString(Build.TAGS)
3010 .build();
3011 pulledData.add(e);
3012 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003013 }
3014
3015 private void registerRoleHolder() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003016 int tagId = FrameworkStatsLog.ROLE_HOLDER;
Tej Singh72a70a82020-02-26 23:46:29 -08003017 mStatsManager.setPullAtomCallback(
Ruchir Rastogie4fd3212020-01-15 00:39:12 -08003018 tagId,
3019 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003020 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003021 mStatsCallbackImpl
Ruchir Rastogie4fd3212020-01-15 00:39:12 -08003022 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003023 }
3024
Ruchir Rastogie4fd3212020-01-15 00:39:12 -08003025 // Add a RoleHolder atom for each package that holds a role.
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003026 int pullRoleHolderLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogie4fd3212020-01-15 00:39:12 -08003027 long callingToken = Binder.clearCallingIdentity();
3028 try {
3029 PackageManager pm = mContext.getPackageManager();
3030 RoleManagerInternal rmi = LocalServices.getService(RoleManagerInternal.class);
3031
3032 List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
3033
3034 int numUsers = users.size();
3035 for (int userNum = 0; userNum < numUsers; userNum++) {
3036 int userId = users.get(userNum).getUserHandle().getIdentifier();
3037
3038 ArrayMap<String, ArraySet<String>> roles = rmi.getRolesAndHolders(userId);
3039
3040 int numRoles = roles.size();
3041 for (int roleNum = 0; roleNum < numRoles; roleNum++) {
3042 String roleName = roles.keyAt(roleNum);
3043 ArraySet<String> holders = roles.valueAt(roleNum);
3044
3045 int numHolders = holders.size();
3046 for (int holderNum = 0; holderNum < numHolders; holderNum++) {
3047 String holderName = holders.valueAt(holderNum);
3048
3049 PackageInfo pkg;
3050 try {
3051 pkg = pm.getPackageInfoAsUser(holderName, 0, userId);
3052 } catch (PackageManager.NameNotFoundException e) {
3053 Slog.w(TAG, "Role holder " + holderName + " not found");
3054 return StatsManager.PULL_SKIP;
3055 }
3056
3057 StatsEvent e = StatsEvent.newBuilder()
3058 .setAtomId(atomTag)
3059 .writeInt(pkg.applicationInfo.uid)
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07003060 .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true)
Ruchir Rastogie4fd3212020-01-15 00:39:12 -08003061 .writeString(holderName)
3062 .writeString(roleName)
3063 .build();
3064 pulledData.add(e);
3065 }
3066 }
3067 }
3068 } finally {
3069 Binder.restoreCallingIdentity(callingToken);
3070 }
3071 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003072 }
3073
3074 private void registerDangerousPermissionState() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003075 int tagId = FrameworkStatsLog.DANGEROUS_PERMISSION_STATE;
Tej Singh72a70a82020-02-26 23:46:29 -08003076 mStatsManager.setPullAtomCallback(
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003077 tagId,
3078 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003079 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003080 mStatsCallbackImpl
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003081 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003082 }
3083
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003084 int pullDangerousPermissionStateLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003085 final long token = Binder.clearCallingIdentity();
Stanislav Zholnina093ae72020-04-18 19:14:17 +01003086 float samplingRate = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_PERMISSIONS,
3087 DANGEROUS_PERMISSION_STATE_SAMPLE_RATE, 0.02f);
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003088 Set<Integer> reportedUids = new HashSet<>();
3089 try {
3090 PackageManager pm = mContext.getPackageManager();
3091
3092 List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
3093
3094 int numUsers = users.size();
3095 for (int userNum = 0; userNum < numUsers; userNum++) {
3096 UserHandle user = users.get(userNum).getUserHandle();
3097
3098 List<PackageInfo> pkgs = pm.getInstalledPackagesAsUser(
3099 PackageManager.GET_PERMISSIONS, user.getIdentifier());
3100
3101 int numPkgs = pkgs.size();
3102 for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) {
3103 PackageInfo pkg = pkgs.get(pkgNum);
3104
3105 if (pkg.requestedPermissions == null) {
3106 continue;
3107 }
3108
3109 if (reportedUids.contains(pkg.applicationInfo.uid)) {
3110 // do not report same uid twice
3111 continue;
3112 }
3113 reportedUids.add(pkg.applicationInfo.uid);
3114
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003115 if (atomTag == FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED
Stanislav Zholnina093ae72020-04-18 19:14:17 +01003116 && ThreadLocalRandom.current().nextFloat() > samplingRate) {
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003117 continue;
3118 }
3119
3120 int numPerms = pkg.requestedPermissions.length;
3121 for (int permNum = 0; permNum < numPerms; permNum++) {
3122 String permName = pkg.requestedPermissions[permNum];
3123
3124 PermissionInfo permissionInfo;
3125 int permissionFlags = 0;
3126 try {
3127 permissionInfo = pm.getPermissionInfo(permName, 0);
3128 permissionFlags =
3129 pm.getPermissionFlags(permName, pkg.packageName, user);
3130 } catch (PackageManager.NameNotFoundException ignored) {
3131 continue;
3132 }
3133
3134 if (permissionInfo.getProtection() != PROTECTION_DANGEROUS) {
3135 continue;
3136 }
3137
Stanislav Zholnindbcf85e2020-02-24 18:17:55 +00003138 if (permName.startsWith(COMMON_PERMISSION_PREFIX)) {
3139 permName = permName.substring(COMMON_PERMISSION_PREFIX.length());
3140 }
3141
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003142 StatsEvent.Builder e = StatsEvent.newBuilder();
3143 e.setAtomId(atomTag);
3144 e.writeString(permName);
3145 e.writeInt(pkg.applicationInfo.uid);
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07003146 e.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003147 if (atomTag == FrameworkStatsLog.DANGEROUS_PERMISSION_STATE) {
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003148 e.writeString("");
3149 }
3150 e.writeBoolean((pkg.requestedPermissionsFlags[permNum]
3151 & REQUESTED_PERMISSION_GRANTED) != 0);
3152 e.writeInt(permissionFlags);
3153
3154 pulledData.add(e.build());
3155 }
3156 }
3157 }
3158 } catch (Throwable t) {
3159 Log.e(TAG, "Could not read permissions", t);
3160 return StatsManager.PULL_SKIP;
3161 } finally {
3162 Binder.restoreCallingIdentity(token);
3163 }
3164 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003165 }
3166
3167 private void registerTimeZoneDataInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003168 int tagId = FrameworkStatsLog.TIME_ZONE_DATA_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08003169 mStatsManager.setPullAtomCallback(
Ruchir Rastogibd2c4ba2020-01-15 14:48:36 -08003170 tagId,
3171 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003172 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003173 mStatsCallbackImpl
Ruchir Rastogibd2c4ba2020-01-15 14:48:36 -08003174 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003175 }
3176
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003177 int pullTimeZoneDataInfoLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogibd2c4ba2020-01-15 14:48:36 -08003178 String tzDbVersion = "Unknown";
3179 try {
3180 tzDbVersion = android.icu.util.TimeZone.getTZDataVersion();
3181 } catch (MissingResourceException e) {
3182 Slog.e(TAG, "Getting tzdb version failed: ", e);
3183 return StatsManager.PULL_SKIP;
3184 }
3185
3186 StatsEvent e = StatsEvent.newBuilder()
3187 .setAtomId(atomTag)
3188 .writeString(tzDbVersion)
3189 .build();
3190 pulledData.add(e);
3191 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003192 }
3193
3194 private void registerExternalStorageInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003195 int tagId = FrameworkStatsLog.EXTERNAL_STORAGE_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08003196 mStatsManager.setPullAtomCallback(
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08003197 tagId,
3198 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003199 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003200 mStatsCallbackImpl
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08003201 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003202 }
3203
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003204 int pullExternalStorageInfoLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08003205 if (mStorageManager == null) {
3206 return StatsManager.PULL_SKIP;
3207 }
3208
3209 List<VolumeInfo> volumes = mStorageManager.getVolumes();
3210 for (VolumeInfo vol : volumes) {
3211 final String envState = VolumeInfo.getEnvironmentForState(vol.getState());
3212 final DiskInfo diskInfo = vol.getDisk();
3213 if (diskInfo != null && envState.equals(Environment.MEDIA_MOUNTED)) {
3214 // Get the type of the volume, if it is adoptable or portable.
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003215 int volumeType = FrameworkStatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__OTHER;
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08003216 if (vol.getType() == TYPE_PUBLIC) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003217 volumeType = FrameworkStatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PUBLIC;
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08003218 } else if (vol.getType() == TYPE_PRIVATE) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003219 volumeType = FrameworkStatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PRIVATE;
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08003220 }
3221
3222 // Get the type of external storage inserted in the device (sd cards, usb, etc.)
3223 int externalStorageType;
3224 if (diskInfo.isSd()) {
3225 externalStorageType = StorageEnums.SD_CARD;
3226 } else if (diskInfo.isUsb()) {
3227 externalStorageType = StorageEnums.USB;
3228 } else {
3229 externalStorageType = StorageEnums.OTHER;
3230 }
3231
3232 StatsEvent e = StatsEvent.newBuilder()
3233 .setAtomId(atomTag)
3234 .writeInt(externalStorageType)
3235 .writeInt(volumeType)
3236 .writeLong(diskInfo.size)
3237 .build();
3238 pulledData.add(e);
3239 }
3240 }
3241 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003242 }
3243
3244 private void registerAppsOnExternalStorageInfo() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003245 int tagId = FrameworkStatsLog.APPS_ON_EXTERNAL_STORAGE_INFO;
Tej Singh72a70a82020-02-26 23:46:29 -08003246 mStatsManager.setPullAtomCallback(
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08003247 tagId,
3248 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003249 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003250 mStatsCallbackImpl
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08003251 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003252 }
3253
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003254 int pullAppsOnExternalStorageInfoLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi6fc44a82020-01-17 10:22:41 -08003255 if (mStorageManager == null) {
3256 return StatsManager.PULL_SKIP;
3257 }
3258
3259 PackageManager pm = mContext.getPackageManager();
3260 List<ApplicationInfo> apps = pm.getInstalledApplications(/*flags=*/ 0);
3261 for (ApplicationInfo appInfo : apps) {
3262 UUID storageUuid = appInfo.storageUuid;
3263 if (storageUuid == null) {
3264 continue;
3265 }
3266
3267 VolumeInfo volumeInfo = mStorageManager.findVolumeByUuid(
3268 appInfo.storageUuid.toString());
3269 if (volumeInfo == null) {
3270 continue;
3271 }
3272
3273 DiskInfo diskInfo = volumeInfo.getDisk();
3274 if (diskInfo == null) {
3275 continue;
3276 }
3277
3278 int externalStorageType = -1;
3279 if (diskInfo.isSd()) {
3280 externalStorageType = StorageEnums.SD_CARD;
3281 } else if (diskInfo.isUsb()) {
3282 externalStorageType = StorageEnums.USB;
3283 } else if (appInfo.isExternal()) {
3284 externalStorageType = StorageEnums.OTHER;
3285 }
3286
3287 // App is installed on external storage.
3288 if (externalStorageType != -1) {
3289 StatsEvent e = StatsEvent.newBuilder()
3290 .setAtomId(atomTag)
3291 .writeInt(externalStorageType)
3292 .writeString(appInfo.packageName)
3293 .build();
3294 pulledData.add(e);
3295 }
3296 }
3297 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003298 }
3299
3300 private void registerFaceSettings() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003301 int tagId = FrameworkStatsLog.FACE_SETTINGS;
Tej Singh72a70a82020-02-26 23:46:29 -08003302 mStatsManager.setPullAtomCallback(
Ruchir Rastogi329c7672020-01-17 15:33:05 -08003303 tagId,
3304 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003305 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003306 mStatsCallbackImpl
Ruchir Rastogi329c7672020-01-17 15:33:05 -08003307 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003308 }
3309
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003310 int pullFaceSettingsLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi329c7672020-01-17 15:33:05 -08003311 final long callingToken = Binder.clearCallingIdentity();
3312 try {
3313 List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
3314 int numUsers = users.size();
3315 for (int userNum = 0; userNum < numUsers; userNum++) {
3316 int userId = users.get(userNum).getUserHandle().getIdentifier();
3317
3318 int unlockKeyguardEnabled = Settings.Secure.getIntForUser(
3319 mContext.getContentResolver(),
3320 Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED, 1, userId);
3321 int unlockDismissesKeyguard = Settings.Secure.getIntForUser(
3322 mContext.getContentResolver(),
3323 Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, 0, userId);
3324 int unlockAttentionRequired = Settings.Secure.getIntForUser(
3325 mContext.getContentResolver(),
3326 Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED, 1, userId);
3327 int unlockAppEnabled = Settings.Secure.getIntForUser(
3328 mContext.getContentResolver(),
3329 Settings.Secure.FACE_UNLOCK_APP_ENABLED, 1, userId);
3330 int unlockAlwaysRequireConfirmation = Settings.Secure.getIntForUser(
3331 mContext.getContentResolver(),
3332 Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, 0, userId);
3333 int unlockDiversityRequired = Settings.Secure.getIntForUser(
3334 mContext.getContentResolver(),
3335 Settings.Secure.FACE_UNLOCK_DIVERSITY_REQUIRED, 1, userId);
3336
3337 StatsEvent e = StatsEvent.newBuilder()
3338 .setAtomId(atomTag)
3339 .writeBoolean(unlockKeyguardEnabled != 0)
3340 .writeBoolean(unlockDismissesKeyguard != 0)
3341 .writeBoolean(unlockAttentionRequired != 0)
3342 .writeBoolean(unlockAppEnabled != 0)
3343 .writeBoolean(unlockAlwaysRequireConfirmation != 0)
3344 .writeBoolean(unlockDiversityRequired != 0)
3345 .build();
3346 pulledData.add(e);
3347 }
3348 } finally {
3349 Binder.restoreCallingIdentity(callingToken);
3350 }
3351 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003352 }
3353
3354 private void registerAppOps() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003355 int tagId = FrameworkStatsLog.APP_OPS;
Tej Singh72a70a82020-02-26 23:46:29 -08003356 mStatsManager.setPullAtomCallback(
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08003357 tagId,
3358 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003359 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003360 mStatsCallbackImpl
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08003361 );
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003362 }
3363
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003364 private void registerRuntimeAppOpAccessMessage() {
3365 int tagId = FrameworkStatsLog.RUNTIME_APP_OP_ACCESS;
Tej Singh72a70a82020-02-26 23:46:29 -08003366 mStatsManager.setPullAtomCallback(
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003367 tagId,
3368 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003369 DIRECT_EXECUTOR,
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003370 mStatsCallbackImpl
3371 );
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003372 }
3373
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003374 private class AppOpEntry {
3375 public final String mPackageName;
3376 public final String mAttributionTag;
3377 public final int mUid;
3378 public final HistoricalOp mOp;
3379 public final int mHash;
3380
3381 AppOpEntry(String packageName, @Nullable String attributionTag, HistoricalOp op, int uid) {
3382 mPackageName = packageName;
3383 mAttributionTag = attributionTag;
3384 mUid = uid;
3385 mOp = op;
3386 mHash = ((op.getOpCode() * 961
3387 + (attributionTag == null ? 0 : attributionTag.hashCode()) * 31
3388 + packageName.hashCode() + RANDOM_SEED) & 0x7fffffff) % 100;
3389 }
3390 }
3391
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003392 int pullAppOpsLocked(int atomTag, List<StatsEvent> pulledData) {
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08003393 final long token = Binder.clearCallingIdentity();
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08003394 try {
3395 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
3396
3397 CompletableFuture<HistoricalOps> ops = new CompletableFuture<>();
Stanislav Zholnin050abc32020-02-17 14:14:52 +00003398 HistoricalOpsRequest histOpsRequest = new HistoricalOpsRequest.Builder(0,
3399 Long.MAX_VALUE).setFlags(OP_FLAGS_PULLED).build();
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003400 appOps.getHistoricalOps(histOpsRequest, AsyncTask.THREAD_POOL_EXECUTOR, ops::complete);
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08003401 HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
3402 TimeUnit.MILLISECONDS);
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003403
3404 List<AppOpEntry> opsList = processHistoricalOps(histOps, atomTag, 100);
3405 int samplingRate = sampleAppOps(pulledData, opsList, atomTag, 100);
3406 if (samplingRate != 100) {
3407 Slog.e(TAG, "Atom 10060 downsampled - too many dimensions");
3408 }
Ruchir Rastogi97050e1c2020-01-15 17:25:00 -08003409 } catch (Throwable t) {
3410 // TODO: catch exceptions at a more granular level
3411 Slog.e(TAG, "Could not read appops", t);
3412 return StatsManager.PULL_SKIP;
3413 } finally {
3414 Binder.restoreCallingIdentity(token);
3415 }
3416 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003417 }
3418
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003419 private int sampleAppOps(List<StatsEvent> pulledData, List<AppOpEntry> opsList, int atomTag,
3420 int samplingRate) {
3421 int nOps = opsList.size();
3422 for (int i = 0; i < nOps; i++) {
3423 AppOpEntry entry = opsList.get(i);
3424 if (entry.mHash >= samplingRate) {
3425 continue;
3426 }
3427 StatsEvent.Builder e = StatsEvent.newBuilder();
3428 e.setAtomId(atomTag);
3429 e.writeInt(entry.mUid);
3430 e.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
3431 e.writeString(entry.mPackageName);
3432 if (atomTag == FrameworkStatsLog.ATTRIBUTED_APP_OPS) {
3433 e.writeString(entry.mAttributionTag);
3434 }
3435 e.writeInt(entry.mOp.getOpCode());
3436 e.writeLong(entry.mOp.getForegroundAccessCount(OP_FLAGS_PULLED));
3437 e.writeLong(entry.mOp.getBackgroundAccessCount(OP_FLAGS_PULLED));
3438 e.writeLong(entry.mOp.getForegroundRejectCount(OP_FLAGS_PULLED));
3439 e.writeLong(entry.mOp.getBackgroundRejectCount(OP_FLAGS_PULLED));
3440 e.writeLong(entry.mOp.getForegroundAccessDuration(OP_FLAGS_PULLED));
3441 e.writeLong(entry.mOp.getBackgroundAccessDuration(OP_FLAGS_PULLED));
3442 e.writeBoolean(mDangerousAppOpsList.contains(entry.mOp.getOpCode()));
3443
3444 if (atomTag == FrameworkStatsLog.ATTRIBUTED_APP_OPS) {
3445 e.writeInt(samplingRate);
3446 }
3447 pulledData.add(e.build());
3448 }
3449 if (pulledData.size() > DIMENSION_KEY_SIZE_HARD_LIMIT) {
3450 int adjustedSamplingRate = constrain(
3451 samplingRate * DIMENSION_KEY_SIZE_SOFT_LIMIT / pulledData.size(), 0,
3452 samplingRate - 1);
3453 pulledData.clear();
3454 return sampleAppOps(pulledData, opsList, atomTag, adjustedSamplingRate);
3455 }
3456 return samplingRate;
3457 }
3458
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003459 private void registerAttributedAppOps() {
3460 int tagId = FrameworkStatsLog.ATTRIBUTED_APP_OPS;
Tej Singh72a70a82020-02-26 23:46:29 -08003461 mStatsManager.setPullAtomCallback(
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00003462 tagId,
3463 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003464 DIRECT_EXECUTOR,
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00003465 mStatsCallbackImpl
3466 );
3467 }
3468
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003469 int pullAttributedAppOpsLocked(int atomTag, List<StatsEvent> pulledData) {
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00003470 final long token = Binder.clearCallingIdentity();
3471 try {
3472 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00003473 CompletableFuture<HistoricalOps> ops = new CompletableFuture<>();
3474 HistoricalOpsRequest histOpsRequest =
3475 new HistoricalOpsRequest.Builder(0, Long.MAX_VALUE).setFlags(
3476 OP_FLAGS_PULLED).build();
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003477
3478 appOps.getHistoricalOps(histOpsRequest, AsyncTask.THREAD_POOL_EXECUTOR, ops::complete);
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00003479 HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
3480 TimeUnit.MILLISECONDS);
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003481
3482 synchronized (mAppOpsSamplingRateLock) {
3483 if (mAppOpsSamplingRate == 0) {
3484 mContext.getMainThreadHandler().postDelayed(new Runnable() {
3485 @Override
3486 public void run() {
3487 try {
3488 estimateAppOpsSamplingRate();
Stanislav Zholnin74b048a2020-05-31 13:17:16 +01003489 } catch (Throwable e) {
3490 Slog.e(TAG, "AppOps sampling ratio estimation failed: ", e);
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003491 synchronized (mAppOpsSamplingRateLock) {
3492 mAppOpsSamplingRate = min(mAppOpsSamplingRate, 10);
3493 }
3494 }
3495 }
3496 }, APP_OPS_SAMPLING_INITIALIZATION_DELAY_MILLIS);
3497 mAppOpsSamplingRate = 100;
3498 }
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00003499 }
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003500
3501 List<AppOpEntry> opsList =
3502 processHistoricalOps(histOps, atomTag, mAppOpsSamplingRate);
3503
3504 int newSamplingRate = sampleAppOps(pulledData, opsList, atomTag, mAppOpsSamplingRate);
3505
3506 synchronized (mAppOpsSamplingRateLock) {
3507 mAppOpsSamplingRate = min(mAppOpsSamplingRate, newSamplingRate);
3508 }
Stanislav Zholnin7dcc51d2020-01-29 16:53:24 +00003509 } catch (Throwable t) {
3510 // TODO: catch exceptions at a more granular level
3511 Slog.e(TAG, "Could not read appops", t);
3512 return StatsManager.PULL_SKIP;
3513 } finally {
3514 Binder.restoreCallingIdentity(token);
3515 }
3516 return StatsManager.PULL_SUCCESS;
3517 }
3518
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003519 private void estimateAppOpsSamplingRate() throws Exception {
3520 int appOpsTargetCollectionSize = DeviceConfig.getInt(
3521 DeviceConfig.NAMESPACE_PERMISSIONS, APP_OPS_TARGET_COLLECTION_SIZE,
3522 APP_OPS_SIZE_ESTIMATE);
Stanislav Zholnin59199132020-03-06 14:19:25 +00003523 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
3524
3525 CompletableFuture<HistoricalOps> ops = new CompletableFuture<>();
3526 HistoricalOpsRequest histOpsRequest =
3527 new HistoricalOpsRequest.Builder(
Hai Zhang4d0bf0f2020-06-08 16:42:53 -07003528 Math.max(Instant.now().minus(1, ChronoUnit.DAYS).toEpochMilli(), 0),
Stanislav Zholnin59199132020-03-06 14:19:25 +00003529 Long.MAX_VALUE).setFlags(
3530 OP_FLAGS_PULLED).build();
Stanislav Zholnin74b048a2020-05-31 13:17:16 +01003531 appOps.getHistoricalOps(histOpsRequest, AsyncTask.THREAD_POOL_EXECUTOR, ops::complete);
Stanislav Zholnin59199132020-03-06 14:19:25 +00003532 HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
3533 TimeUnit.MILLISECONDS);
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003534 List<AppOpEntry> opsList =
3535 processHistoricalOps(histOps, FrameworkStatsLog.ATTRIBUTED_APP_OPS, 100);
3536
3537 long estimatedSize = 0;
3538 int nOps = opsList.size();
3539 for (int i = 0; i < nOps; i++) {
3540 AppOpEntry entry = opsList.get(i);
3541 estimatedSize += 32 + entry.mPackageName.length() + (entry.mAttributionTag == null ? 1
3542 : entry.mAttributionTag.length());
3543
3544 }
3545 int estimatedSamplingRate = (int) constrain(
3546 appOpsTargetCollectionSize * 100 / estimatedSize, 0, 100);
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003547 synchronized (mAppOpsSamplingRateLock) {
3548 mAppOpsSamplingRate = min(mAppOpsSamplingRate, estimatedSamplingRate);
3549 }
Stanislav Zholnin59199132020-03-06 14:19:25 +00003550 }
3551
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003552 private List<AppOpEntry> processHistoricalOps(
3553 HistoricalOps histOps, int atomTag, int samplingRatio) {
3554 List<AppOpEntry> opsList = new ArrayList<>();
Stanislav Zholnin59199132020-03-06 14:19:25 +00003555 for (int uidIdx = 0; uidIdx < histOps.getUidCount(); uidIdx++) {
3556 final HistoricalUidOps uidOps = histOps.getUidOpsAt(uidIdx);
3557 final int uid = uidOps.getUid();
3558 for (int pkgIdx = 0; pkgIdx < uidOps.getPackageCount(); pkgIdx++) {
3559 final HistoricalPackageOps packageOps = uidOps.getPackageOpsAt(pkgIdx);
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003560 if (atomTag == FrameworkStatsLog.ATTRIBUTED_APP_OPS) {
3561 for (int attributionIdx = 0;
3562 attributionIdx < packageOps.getAttributedOpsCount(); attributionIdx++) {
3563 final AppOpsManager.AttributedHistoricalOps attributedOps =
3564 packageOps.getAttributedOpsAt(attributionIdx);
3565 for (int opIdx = 0; opIdx < attributedOps.getOpCount(); opIdx++) {
3566 final AppOpsManager.HistoricalOp op = attributedOps.getOpAt(opIdx);
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003567 processHistoricalOp(op, opsList, uid, samplingRatio,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003568 packageOps.getPackageName(), attributedOps.getTag());
Stanislav Zholnin59199132020-03-06 14:19:25 +00003569 }
3570 }
3571 } else if (atomTag == FrameworkStatsLog.APP_OPS) {
3572 for (int opIdx = 0; opIdx < packageOps.getOpCount(); opIdx++) {
3573 final AppOpsManager.HistoricalOp op = packageOps.getOpAt(opIdx);
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003574 processHistoricalOp(op, opsList, uid, samplingRatio,
Stanislav Zholnin59199132020-03-06 14:19:25 +00003575 packageOps.getPackageName(), null);
3576 }
3577 }
3578 }
3579 }
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003580 return opsList;
Stanislav Zholnin59199132020-03-06 14:19:25 +00003581 }
3582
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003583 private void processHistoricalOp(AppOpsManager.HistoricalOp op,
3584 List<AppOpEntry> opsList, int uid, int samplingRatio, String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003585 @Nullable String attributionTag) {
Stanislav Zholnin044b1792020-06-03 17:53:53 +01003586 int firstChar = 0;
3587 if (attributionTag != null && attributionTag.startsWith(packageName)) {
3588 firstChar = packageName.length();
3589 if (firstChar < attributionTag.length() && attributionTag.charAt(firstChar) == '.') {
3590 firstChar++;
3591 }
3592 }
3593 AppOpEntry entry = new AppOpEntry(packageName,
3594 attributionTag == null ? null : attributionTag.substring(firstChar), op,
3595 uid);
Stanislav Zholnin841c9ab2020-05-24 04:56:18 +01003596 if (entry.mHash < samplingRatio) {
3597 opsList.add(entry);
Stanislav Zholnin59199132020-03-06 14:19:25 +00003598 }
Stanislav Zholnin59199132020-03-06 14:19:25 +00003599 }
3600
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003601 int pullRuntimeAppOpAccessMessageLocked(int atomTag, List<StatsEvent> pulledData) {
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003602 final long token = Binder.clearCallingIdentity();
3603 try {
3604 AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
3605
3606 RuntimeAppOpAccessMessage message = appOps.collectRuntimeAppOpAccessMessage();
3607 if (message == null) {
3608 Slog.i(TAG, "No runtime appop access message collected");
3609 return StatsManager.PULL_SUCCESS;
3610 }
3611
3612 StatsEvent.Builder e = StatsEvent.newBuilder();
3613 e.setAtomId(atomTag);
3614 e.writeInt(message.getUid());
Muhammad Qureshi22e52da2020-03-30 21:14:21 -07003615 e.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003616 e.writeString(message.getPackageName());
Stanislav Zholnin3a2a6e42020-03-30 10:44:51 +01003617 e.writeString("");
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003618 if (message.getAttributionTag() == null) {
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003619 e.writeString("");
3620 } else {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003621 e.writeString(message.getAttributionTag());
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003622 }
3623 e.writeString(message.getMessage());
3624 e.writeInt(message.getSamplingStrategy());
Stanislav Zholnin3a2a6e42020-03-30 10:44:51 +01003625 e.writeInt(AppOpsManager.strOpToOp(message.getOp()));
Stanislav Zholnindf3eeac2020-02-17 18:06:07 +00003626
3627 pulledData.add(e.build());
3628 } catch (Throwable t) {
3629 // TODO: catch exceptions at a more granular level
3630 Slog.e(TAG, "Could not read runtime appop access message", t);
3631 return StatsManager.PULL_SKIP;
3632 } finally {
3633 Binder.restoreCallingIdentity(token);
3634 }
3635 return StatsManager.PULL_SUCCESS;
3636 }
3637
Jeffrey Huang730bf962020-01-16 15:59:52 -08003638 static void unpackStreamedData(int atomTag, List<StatsEvent> pulledData,
3639 List<ParcelFileDescriptor> statsFiles) throws IOException {
3640 InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(statsFiles.get(0));
3641 int[] len = new int[1];
3642 byte[] stats = readFully(stream, len);
3643 StatsEvent e = StatsEvent.newBuilder()
3644 .setAtomId(atomTag)
3645 .writeByteArray(Arrays.copyOf(stats, len[0]))
3646 .build();
3647 pulledData.add(e);
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003648 }
3649
Jeffrey Huang730bf962020-01-16 15:59:52 -08003650 static byte[] readFully(InputStream stream, int[] outLen) throws IOException {
3651 int pos = 0;
3652 final int initialAvail = stream.available();
3653 byte[] data = new byte[initialAvail > 0 ? (initialAvail + 1) : 16384];
3654 while (true) {
3655 int amt = stream.read(data, pos, data.length - pos);
3656 if (DEBUG) {
3657 Slog.i(TAG, "Read " + amt + " bytes at " + pos + " of avail " + data.length);
3658 }
3659 if (amt < 0) {
3660 if (DEBUG) {
3661 Slog.i(TAG, "**** FINISHED READING: pos=" + pos + " len=" + data.length);
3662 }
3663 outLen[0] = pos;
3664 return data;
3665 }
3666 pos += amt;
3667 if (pos >= data.length) {
3668 byte[] newData = new byte[pos + 16384];
3669 if (DEBUG) {
3670 Slog.i(TAG, "Copying " + pos + " bytes to new array len " + newData.length);
3671 }
3672 System.arraycopy(data, 0, newData, 0, pos);
3673 data = newData;
3674 }
3675 }
3676 }
3677
3678 private void registerNotificationRemoteViews() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003679 int tagId = FrameworkStatsLog.NOTIFICATION_REMOTE_VIEWS;
Tej Singh72a70a82020-02-26 23:46:29 -08003680 mStatsManager.setPullAtomCallback(
Jeffrey Huang730bf962020-01-16 15:59:52 -08003681 tagId,
3682 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003683 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003684 mStatsCallbackImpl
Jeffrey Huang730bf962020-01-16 15:59:52 -08003685 );
3686 }
3687
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003688 int pullNotificationRemoteViewsLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang730bf962020-01-16 15:59:52 -08003689 INotificationManager notificationManagerService = getINotificationManagerService();
3690 if (notificationManagerService == null) {
3691 return StatsManager.PULL_SKIP;
3692 }
3693 final long callingToken = Binder.clearCallingIdentity();
3694 try {
Ruchir Rastogi92cf9a22020-01-17 15:55:39 -08003695 // determine last pull tine. Copy file trick from pullProcStats?
Jeffrey Huang730bf962020-01-16 15:59:52 -08003696 long wallClockNanos = SystemClock.currentTimeMicro() * 1000L;
3697 long lastNotificationStatsNs = wallClockNanos -
3698 TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS);
3699
3700 List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
3701 notificationManagerService.pullStats(lastNotificationStatsNs,
3702 NotificationManagerService.REPORT_REMOTE_VIEWS, true, statsFiles);
3703 if (statsFiles.size() != 1) {
3704 return StatsManager.PULL_SKIP;
3705 }
3706 unpackStreamedData(atomTag, pulledData, statsFiles);
3707 } catch (IOException e) {
3708 Slog.e(TAG, "Getting notistats failed: ", e);
3709 return StatsManager.PULL_SKIP;
3710 } catch (RemoteException e) {
3711 Slog.e(TAG, "Getting notistats failed: ", e);
3712 return StatsManager.PULL_SKIP;
3713 } catch (SecurityException e) {
3714 Slog.e(TAG, "Getting notistats failed: ", e);
3715 return StatsManager.PULL_SKIP;
3716 } finally {
3717 Binder.restoreCallingIdentity(callingToken);
3718 }
3719 return StatsManager.PULL_SUCCESS;
Jeffrey Huangfdd3c7c2020-01-09 13:54:24 -08003720 }
3721
3722 private void registerDangerousPermissionStateSampled() {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003723 int tagId = FrameworkStatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED;
Tej Singh72a70a82020-02-26 23:46:29 -08003724 mStatsManager.setPullAtomCallback(
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003725 tagId,
3726 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003727 DIRECT_EXECUTOR,
Jeffrey Huang8fb5b832020-01-27 13:20:16 -08003728 mStatsCallbackImpl
Jeffrey Huang7f9fe502020-01-16 16:47:22 -08003729 );
Tej Singh953ad862020-01-03 12:47:07 -08003730 }
Jeffrey Huangbf130832020-01-22 15:48:26 -08003731
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003732 private void registerBatteryLevel() {
3733 int tagId = FrameworkStatsLog.BATTERY_LEVEL;
Tej Singh72a70a82020-02-26 23:46:29 -08003734 mStatsManager.setPullAtomCallback(
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003735 tagId,
3736 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003737 DIRECT_EXECUTOR,
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003738 mStatsCallbackImpl
3739 );
3740 }
3741
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003742 private void registerRemainingBatteryCapacity() {
3743 int tagId = FrameworkStatsLog.REMAINING_BATTERY_CAPACITY;
Tej Singh72a70a82020-02-26 23:46:29 -08003744 mStatsManager.setPullAtomCallback(
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003745 tagId,
3746 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003747 DIRECT_EXECUTOR,
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003748 mStatsCallbackImpl
3749 );
3750 }
3751
3752 private void registerFullBatteryCapacity() {
3753 int tagId = FrameworkStatsLog.FULL_BATTERY_CAPACITY;
Tej Singh72a70a82020-02-26 23:46:29 -08003754 mStatsManager.setPullAtomCallback(
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003755 tagId,
3756 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003757 DIRECT_EXECUTOR,
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003758 mStatsCallbackImpl
3759 );
3760 }
3761
3762 private void registerBatteryVoltage() {
3763 int tagId = FrameworkStatsLog.BATTERY_VOLTAGE;
Tej Singh72a70a82020-02-26 23:46:29 -08003764 mStatsManager.setPullAtomCallback(
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003765 tagId,
3766 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003767 DIRECT_EXECUTOR,
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003768 mStatsCallbackImpl
3769 );
3770 }
3771
3772 private void registerBatteryCycleCount() {
3773 int tagId = FrameworkStatsLog.BATTERY_CYCLE_COUNT;
Tej Singh72a70a82020-02-26 23:46:29 -08003774 mStatsManager.setPullAtomCallback(
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003775 tagId,
3776 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003777 DIRECT_EXECUTOR,
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003778 mStatsCallbackImpl
3779 );
3780 }
3781
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003782 int pullHealthHalLocked(int atomTag, List<StatsEvent> pulledData) {
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003783 IHealth healthService = mHealthService.getLastService();
3784 if (healthService == null) {
3785 return StatsManager.PULL_SKIP;
3786 }
3787 try {
3788 healthService.getHealthInfo((result, value) -> {
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003789 int pulledValue;
3790 switch(atomTag) {
3791 case FrameworkStatsLog.BATTERY_LEVEL:
3792 pulledValue = value.legacy.batteryLevel;
3793 break;
3794 case FrameworkStatsLog.REMAINING_BATTERY_CAPACITY:
3795 pulledValue = value.legacy.batteryChargeCounter;
3796 break;
3797 case FrameworkStatsLog.FULL_BATTERY_CAPACITY:
3798 pulledValue = value.legacy.batteryFullCharge;
3799 break;
3800 case FrameworkStatsLog.BATTERY_VOLTAGE:
3801 pulledValue = value.legacy.batteryVoltage;
3802 break;
3803 case FrameworkStatsLog.BATTERY_CYCLE_COUNT:
3804 pulledValue = value.legacy.batteryCycleCount;
3805 break;
3806 default:
3807 throw new IllegalStateException("Invalid atomTag in healthHal puller: "
3808 + atomTag);
3809 }
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003810 StatsEvent e = StatsEvent.newBuilder()
3811 .setAtomId(atomTag)
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003812 .writeInt(pulledValue)
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003813 .build();
3814 pulledData.add(e);
3815 });
Jeffrey Huang43f4d262020-01-30 14:03:31 -08003816 } catch (RemoteException | IllegalStateException e) {
Jeffrey Huang9a3c1b62020-01-27 17:33:13 -08003817 return StatsManager.PULL_SKIP;
3818 }
3819 return StatsManager.PULL_SUCCESS;
3820 }
Jeffrey Huangbf130832020-01-22 15:48:26 -08003821
Raff Tsai87cefd42020-04-07 14:25:02 +08003822 private void registerSettingsStats() {
3823 int tagId = FrameworkStatsLog.SETTING_SNAPSHOT;
3824 mStatsManager.setPullAtomCallback(
3825 tagId,
3826 null, // use default PullAtomMetadata values
Tej Singhe19799f2020-05-20 19:14:26 -07003827 DIRECT_EXECUTOR,
Raff Tsai87cefd42020-04-07 14:25:02 +08003828 mStatsCallbackImpl
3829 );
3830 }
3831
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003832 int pullSettingsStatsLocked(int atomTag, List<StatsEvent> pulledData) {
Raff Tsai87cefd42020-04-07 14:25:02 +08003833 UserManager userManager = mContext.getSystemService(UserManager.class);
3834 if (userManager == null) {
3835 return StatsManager.PULL_SKIP;
3836 }
3837
3838 final long token = Binder.clearCallingIdentity();
3839 try {
3840 for (UserInfo user : userManager.getUsers()) {
3841 final int userId = user.getUserHandle().getIdentifier();
3842
3843 if (userId == UserHandle.USER_SYSTEM) {
3844 pulledData.addAll(SettingsStatsUtil.logGlobalSettings(mContext, atomTag,
3845 UserHandle.USER_SYSTEM));
3846 }
3847 pulledData.addAll(SettingsStatsUtil.logSystemSettings(mContext, atomTag, userId));
3848 pulledData.addAll(SettingsStatsUtil.logSecureSettings(mContext, atomTag, userId));
3849 }
3850 } catch (Exception e) {
3851 Slog.e(TAG, "failed to pullSettingsStats", e);
3852 return StatsManager.PULL_SKIP;
3853 } finally {
3854 Binder.restoreCallingIdentity(token);
3855 }
3856 return StatsManager.PULL_SUCCESS;
3857 }
3858
Jeffrey Huangbf130832020-01-22 15:48:26 -08003859 // Thermal event received from vendor thermal management subsystem
3860 private static final class ThermalEventListener extends IThermalEventListener.Stub {
3861 @Override
3862 public void notifyThrottling(Temperature temp) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003863 FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_THROTTLING_SEVERITY_STATE_CHANGED,
3864 temp.getType(), temp.getName(), (int) (temp.getValue() * 10), temp.getStatus());
Jeffrey Huangbf130832020-01-22 15:48:26 -08003865 }
3866 }
3867
3868 private static final class ConnectivityStatsCallback extends
3869 ConnectivityManager.NetworkCallback {
3870 @Override
3871 public void onAvailable(Network network) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003872 FrameworkStatsLog.write(FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED, network.netId,
3873 FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED__STATE__CONNECTED);
Jeffrey Huangbf130832020-01-22 15:48:26 -08003874 }
3875
3876 @Override
3877 public void onLost(Network network) {
Muhammad Qureshi4e4c44f2020-01-27 17:18:52 -08003878 FrameworkStatsLog.write(FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED, network.netId,
3879 FrameworkStatsLog.CONNECTIVITY_STATE_CHANGED__STATE__DISCONNECTED);
Jeffrey Huangbf130832020-01-22 15:48:26 -08003880 }
3881 }
junyulaiaa31d3c2020-04-10 15:11:54 +08003882
3883 private final class StatsSubscriptionsListener
3884 extends SubscriptionManager.OnSubscriptionsChangedListener {
3885 @NonNull
3886 private final SubscriptionManager mSm;
3887
3888 StatsSubscriptionsListener(@NonNull SubscriptionManager sm) {
3889 mSm = sm;
3890 }
3891
3892 @Override
3893 public void onSubscriptionsChanged() {
3894 final List<SubscriptionInfo> currentSubs = mSm.getCompleteActiveSubscriptionInfoList();
3895 for (final SubscriptionInfo sub : currentSubs) {
3896 final SubInfo match = CollectionUtils.find(mHistoricalSubs,
3897 (SubInfo it) -> it.subId == sub.getSubscriptionId());
3898 // SubInfo exists, ignore.
3899 if (match != null) continue;
3900
3901 // Ignore if no valid mcc, mnc, imsi, carrierId.
3902 final int subId = sub.getSubscriptionId();
3903 final String mcc = sub.getMccString();
3904 final String mnc = sub.getMncString();
3905 final String subscriberId = mTelephony.getSubscriberId(subId);
3906 if (TextUtils.isEmpty(subscriberId) || TextUtils.isEmpty(mcc)
3907 || TextUtils.isEmpty(mnc) || sub.getCarrierId() == UNKNOWN_CARRIER_ID) {
3908 Slog.e(TAG, "subInfo of subId " + subId + " is invalid, ignored.");
3909 continue;
3910 }
3911
3912 final SubInfo subInfo = new SubInfo(subId, sub.getCarrierId(), mcc, mnc,
3913 subscriberId, sub.isOpportunistic());
3914 Slog.i(TAG, "subId " + subId + " added into historical sub list");
junyulaiaa31d3c2020-04-10 15:11:54 +08003915
Ruchir Rastogibba70a62020-06-01 10:43:31 -07003916 synchronized (mDataBytesTransferLock) {
3917 mHistoricalSubs.add(subInfo);
3918 // Since getting snapshot when pulling will also include data before boot,
3919 // query stats as baseline to prevent double count is needed.
3920 mNetworkStatsBaselines.addAll(getDataUsageBytesTransferSnapshotForSub(subInfo));
3921 }
junyulaiaa31d3c2020-04-10 15:11:54 +08003922 }
3923 }
3924 }
3925
Tej Singh953ad862020-01-03 12:47:07 -08003926}