blob: 556038f3f6466a77d1d326d3bda17aca25831a9b [file] [log] [blame]
Bookatz94726412017-08-31 09:26:15 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.server.stats;
17
Chenjie Yu05013b32017-11-21 10:21:41 -080018import android.annotation.Nullable;
Rajeev Kumar22d92b72018-02-07 18:38:36 -080019import android.app.ActivityManagerInternal;
Bookatz94726412017-08-31 09:26:15 -070020import android.app.AlarmManager;
Bookatz75158ac2018-05-18 15:55:23 -070021import android.app.AlarmManager.OnAlarmListener;
Tej Singh6188aa32018-08-29 00:21:07 +000022import android.app.PendingIntent;
Rajeev Kumar22d92b72018-02-07 18:38:36 -080023import android.app.ProcessMemoryState;
Bookatzc6977972018-01-16 16:55:05 -080024import android.app.StatsManager;
Chenjie Yu9d7720b2018-01-24 10:34:48 -080025import android.bluetooth.BluetoothActivityEnergyInfo;
26import android.bluetooth.BluetoothAdapter;
27import android.bluetooth.UidTraffic;
Bookatz94726412017-08-31 09:26:15 -070028import android.content.BroadcastReceiver;
29import android.content.Context;
30import android.content.Intent;
David Chende701692017-10-05 13:16:02 -070031import android.content.IntentFilter;
Bookatzc6977972018-01-16 16:55:05 -080032import android.content.IntentSender;
David Chende701692017-10-05 13:16:02 -070033import android.content.pm.PackageInfo;
34import android.content.pm.PackageManager;
35import android.content.pm.UserInfo;
David Chenc8a43242017-10-17 16:23:28 -070036import android.net.NetworkStats;
Chenjie Yu05013b32017-11-21 10:21:41 -080037import android.net.wifi.IWifiManager;
38import android.net.wifi.WifiActivityEnergyInfo;
David Chenc8a43242017-10-17 16:23:28 -070039import android.os.BatteryStatsInternal;
Bookatz94726412017-08-31 09:26:15 -070040import android.os.Binder;
David Chende701692017-10-05 13:16:02 -070041import android.os.Bundle;
Chenjie Yu937d7422018-01-10 16:37:53 -080042import android.os.Environment;
yroe26c97b2018-03-27 10:30:11 -070043import android.os.FileUtils;
Bookatzb487b552017-09-18 11:26:01 -070044import android.os.IBinder;
Bookatz94726412017-08-31 09:26:15 -070045import android.os.IStatsCompanionService;
46import android.os.IStatsManager;
Chenjie Yu05013b32017-11-21 10:21:41 -080047import android.os.Parcelable;
Bookatz94726412017-08-31 09:26:15 -070048import android.os.Process;
Bookatz1b0b1142017-09-08 11:58:42 -070049import android.os.RemoteException;
Bookatz94726412017-08-31 09:26:15 -070050import android.os.ServiceManager;
Chenjie Yu937d7422018-01-10 16:37:53 -080051import android.os.StatFs;
Chenjie Yu9d7720b2018-01-24 10:34:48 -080052import android.os.StatsDimensionsValue;
David Chen1481fe12017-10-16 13:16:34 -070053import android.os.StatsLogEventWrapper;
Chenjie Yu05013b32017-11-21 10:21:41 -080054import android.os.SynchronousResultReceiver;
Chenjie Yu937d7422018-01-10 16:37:53 -080055import android.os.SystemClock;
David Chende701692017-10-05 13:16:02 -070056import android.os.UserHandle;
57import android.os.UserManager;
Chenjie Yu937d7422018-01-10 16:37:53 -080058import android.telephony.ModemActivityInfo;
59import android.telephony.TelephonyManager;
Olivier Gaillard00bfb1b2018-07-10 11:25:09 +010060import android.util.ArrayMap;
Bookatz94726412017-08-31 09:26:15 -070061import android.util.Slog;
David Chenc8a43242017-10-17 16:23:28 -070062import android.util.StatsLog;
63
64import com.android.internal.annotations.GuardedBy;
65import com.android.internal.net.NetworkStatsFactory;
Olivier Gaillard00bfb1b2018-07-10 11:25:09 +010066import com.android.internal.os.BinderCallsStats.ExportedCallStat;
Chenjie Yu937d7422018-01-10 16:37:53 -080067import com.android.internal.os.KernelCpuSpeedReader;
Tej Singhf154cf02018-08-16 18:31:54 -070068import com.android.internal.os.KernelUidCpuTimeReader;
Tej Singh6188aa32018-08-29 00:21:07 +000069import com.android.internal.os.KernelUidCpuClusterTimeReader;
70import com.android.internal.os.KernelUidCpuActiveTimeReader;
71import com.android.internal.os.KernelUidCpuFreqTimeReader;
David Chenc8a43242017-10-17 16:23:28 -070072import com.android.internal.os.KernelWakelockReader;
73import com.android.internal.os.KernelWakelockStats;
Chenjie Yu7f8def92017-11-03 09:33:15 -070074import com.android.internal.os.PowerProfile;
yroe26c97b2018-03-27 10:30:11 -070075import com.android.internal.util.DumpUtils;
Olivier Gaillard289ba402018-07-24 18:50:13 +010076import com.android.server.BinderCallsStatsService;
David Chenc8a43242017-10-17 16:23:28 -070077import com.android.server.LocalServices;
78import com.android.server.SystemService;
Bookatz94726412017-08-31 09:26:15 -070079
yroe26c97b2018-03-27 10:30:11 -070080import java.io.File;
81import java.io.FileDescriptor;
Chenjie Yuec676612018-03-07 09:19:17 -080082import java.io.IOException;
yroe26c97b2018-03-27 10:30:11 -070083import java.io.PrintWriter;
David Chende701692017-10-05 13:16:02 -070084import java.util.ArrayList;
Bookatz058d8692018-03-06 09:53:47 -080085import java.util.Arrays;
yroe26c97b2018-03-27 10:30:11 -070086import java.util.HashMap;
87import java.util.HashSet;
David Chende701692017-10-05 13:16:02 -070088import java.util.List;
Bookatzc68a9d22017-09-27 14:09:55 -070089import java.util.Map;
Olivier Gaillard6f52d152018-07-25 12:13:12 +010090import java.util.Map.Entry;
yroe26c97b2018-03-27 10:30:11 -070091import java.util.concurrent.TimeUnit;
Chenjie Yu05013b32017-11-21 10:21:41 -080092import java.util.concurrent.TimeoutException;
Bookatzc68a9d22017-09-27 14:09:55 -070093
Bookatz94726412017-08-31 09:26:15 -070094/**
95 * Helper service for statsd (the native stats management service in cmds/statsd/).
96 * Used for registering and receiving alarms on behalf of statsd.
David Chen1481fe12017-10-16 13:16:34 -070097 *
Bookatz6bc51d72017-09-28 16:43:40 -070098 * @hide
Bookatz94726412017-08-31 09:26:15 -070099 */
100public class StatsCompanionService extends IStatsCompanionService.Stub {
Chenjie Yu05013b32017-11-21 10:21:41 -0800101 /**
102 * How long to wait on an individual subsystem to return its stats.
103 */
104 private static final long EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS = 2000;
yroe26c97b2018-03-27 10:30:11 -0700105 private static final long MILLIS_IN_A_DAY = TimeUnit.DAYS.toMillis(1);
Chenjie Yu05013b32017-11-21 10:21:41 -0800106
107 public static final String RESULT_RECEIVER_CONTROLLER_KEY = "controller_activity";
yroe26c97b2018-03-27 10:30:11 -0700108 public static final String CONFIG_DIR = "/data/misc/stats-service";
Chenjie Yu05013b32017-11-21 10:21:41 -0800109
Bookatz94726412017-08-31 09:26:15 -0700110 static final String TAG = "StatsCompanionService";
Tej Singh484524a2018-02-01 15:10:05 -0800111 static final boolean DEBUG = false;
Bookatzc6977972018-01-16 16:55:05 -0800112
David Chen661f7912018-01-22 17:46:24 -0800113 public static final int CODE_DATA_BROADCAST = 1;
Bookatzc6977972018-01-16 16:55:05 -0800114 public static final int CODE_SUBSCRIBER_BROADCAST = 1;
David Chend37bc232018-04-12 18:05:11 -0700115 /**
116 * The last report time is provided with each intent registered to
117 * StatsManager#setFetchReportsOperation. This allows easy de-duping in the receiver if
118 * statsd is requesting the client to retrieve the same statsd data. The last report time
119 * corresponds to the last_report_elapsed_nanos that will provided in the current
120 * ConfigMetricsReport, and this timestamp also corresponds to the
121 * current_report_elapsed_nanos of the most recently obtained ConfigMetricsReport.
122 */
123 public static final String EXTRA_LAST_REPORT_TIME = "android.app.extra.LAST_REPORT_TIME";
yroe26c97b2018-03-27 10:30:11 -0700124 public static final int DEATH_THRESHOLD = 10;
Bookatzc6977972018-01-16 16:55:05 -0800125
Bookatz94726412017-08-31 09:26:15 -0700126 private final Context mContext;
127 private final AlarmManager mAlarmManager;
Bookatzb487b552017-09-18 11:26:01 -0700128 @GuardedBy("sStatsdLock")
Bookatz1b0b1142017-09-08 11:58:42 -0700129 private static IStatsManager sStatsd;
Bookatzb487b552017-09-18 11:26:01 -0700130 private static final Object sStatsdLock = new Object();
Bookatz94726412017-08-31 09:26:15 -0700131
Bookatz75158ac2018-05-18 15:55:23 -0700132 private final OnAlarmListener mAnomalyAlarmListener = new AnomalyAlarmListener();
133 private final OnAlarmListener mPullingAlarmListener = new PullingAlarmListener();
134 private final OnAlarmListener mPeriodicAlarmListener = new PeriodicAlarmListener();
David Chende701692017-10-05 13:16:02 -0700135 private final BroadcastReceiver mAppUpdateReceiver;
David Chen47e8f4d2017-10-11 15:34:13 -0700136 private final BroadcastReceiver mUserUpdateReceiver;
yro947fbce2017-11-15 22:50:23 -0800137 private final ShutdownEventReceiver mShutdownEventReceiver;
Chenjie Yu7f8def92017-11-03 09:33:15 -0700138 private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader();
139 private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats();
Chenjie Yu05013b32017-11-21 10:21:41 -0800140 private IWifiManager mWifiManager = null;
141 private TelephonyManager mTelephony = null;
Chenjie Yu937d7422018-01-10 16:37:53 -0800142 private final StatFs mStatFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath());
143 private final StatFs mStatFsSystem =
David Chen661f7912018-01-22 17:46:24 -0800144 new StatFs(Environment.getRootDirectory().getAbsolutePath());
Chenjie Yu937d7422018-01-10 16:37:53 -0800145 private final StatFs mStatFsTemp =
David Chen661f7912018-01-22 17:46:24 -0800146 new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath());
yroe26c97b2018-03-27 10:30:11 -0700147 @GuardedBy("sStatsdLock")
148 private final HashSet<Long> mDeathTimeMillis = new HashSet<>();
149 @GuardedBy("sStatsdLock")
150 private final HashMap<Long, String> mDeletedFiles = new HashMap<>();
Bookatz94726412017-08-31 09:26:15 -0700151
Chenjie Yuec676612018-03-07 09:19:17 -0800152 private KernelUidCpuTimeReader mKernelUidCpuTimeReader = new KernelUidCpuTimeReader();
153 private KernelCpuSpeedReader[] mKernelCpuSpeedReaders;
154 private KernelUidCpuFreqTimeReader mKernelUidCpuFreqTimeReader =
155 new KernelUidCpuFreqTimeReader();
156 private KernelUidCpuActiveTimeReader mKernelUidCpuActiveTimeReader =
157 new KernelUidCpuActiveTimeReader();
158 private KernelUidCpuClusterTimeReader mKernelUidCpuClusterTimeReader =
159 new KernelUidCpuClusterTimeReader();
160
Bookatz94726412017-08-31 09:26:15 -0700161 public StatsCompanionService(Context context) {
162 super();
163 mContext = context;
164 mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
165
David Chende701692017-10-05 13:16:02 -0700166 mAppUpdateReceiver = new AppUpdateReceiver();
David Chen47e8f4d2017-10-11 15:34:13 -0700167 mUserUpdateReceiver = new BroadcastReceiver() {
168 @Override
169 public void onReceive(Context context, Intent intent) {
170 synchronized (sStatsdLock) {
171 sStatsd = fetchStatsdService();
172 if (sStatsd == null) {
Bookatz111ed732018-02-16 15:54:05 -0800173 Slog.w(TAG, "Could not access statsd for UserUpdateReceiver");
David Chen47e8f4d2017-10-11 15:34:13 -0700174 return;
175 }
176 try {
177 // Pull the latest state of UID->app name, version mapping.
178 // Needed since the new user basically has a version of every app.
179 informAllUidsLocked(context);
180 } catch (RemoteException e) {
David Chen1481fe12017-10-16 13:16:34 -0700181 Slog.e(TAG, "Failed to inform statsd latest update of all apps", e);
yroe26c97b2018-03-27 10:30:11 -0700182 forgetEverythingLocked();
David Chen47e8f4d2017-10-11 15:34:13 -0700183 }
184 }
185 }
186 };
yro947fbce2017-11-15 22:50:23 -0800187 mShutdownEventReceiver = new ShutdownEventReceiver();
Bookatz111ed732018-02-16 15:54:05 -0800188 if (DEBUG) Slog.d(TAG, "Registered receiver for ACTION_PACKAGE_REPLACED and ADDED.");
Chenjie Yu7f8def92017-11-03 09:33:15 -0700189 PowerProfile powerProfile = new PowerProfile(context);
190 final int numClusters = powerProfile.getNumCpuClusters();
191 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters];
192 int firstCpuOfCluster = 0;
193 for (int i = 0; i < numClusters; i++) {
194 final int numSpeedSteps = powerProfile.getNumSpeedStepsInCpuCluster(i);
195 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster,
David Chen661f7912018-01-22 17:46:24 -0800196 numSpeedSteps);
Chenjie Yu7f8def92017-11-03 09:33:15 -0700197 firstCpuOfCluster += powerProfile.getNumCoresInCpuCluster(i);
198 }
Chenjie Yuec676612018-03-07 09:19:17 -0800199 // use default throttling in
200 // frameworks/base/core/java/com/android/internal/os/KernelCpuProcReader
201 mKernelUidCpuFreqTimeReader.setThrottleInterval(0);
202 long[] freqs = mKernelUidCpuFreqTimeReader.readFreqs(powerProfile);
Chenjie Yuec676612018-03-07 09:19:17 -0800203 mKernelUidCpuClusterTimeReader.setThrottleInterval(0);
204 mKernelUidCpuActiveTimeReader.setThrottleInterval(0);
Bookatz94726412017-08-31 09:26:15 -0700205 }
206
David Chenadaf8b32017-11-03 15:42:08 -0700207 @Override
David Chend37bc232018-04-12 18:05:11 -0700208 public void sendDataBroadcast(IBinder intentSenderBinder, long lastReportTimeNs) {
Bookatz36920822018-01-26 09:18:07 -0800209 enforceCallingPermission();
David Chen661f7912018-01-22 17:46:24 -0800210 IntentSender intentSender = new IntentSender(intentSenderBinder);
211 Intent intent = new Intent();
David Chend37bc232018-04-12 18:05:11 -0700212 intent.putExtra(EXTRA_LAST_REPORT_TIME, lastReportTimeNs);
David Chen661f7912018-01-22 17:46:24 -0800213 try {
214 intentSender.sendIntent(mContext, CODE_DATA_BROADCAST, intent, null, null);
215 } catch (IntentSender.SendIntentException e) {
216 Slog.w(TAG, "Unable to send using IntentSender");
217 }
David Chenadaf8b32017-11-03 15:42:08 -0700218 }
219
Bookatzc6977972018-01-16 16:55:05 -0800220 @Override
221 public void sendSubscriberBroadcast(IBinder intentSenderBinder, long configUid, long configKey,
222 long subscriptionId, long subscriptionRuleId,
Bookatz058d8692018-03-06 09:53:47 -0800223 String[] cookies,
Bookatzc6977972018-01-16 16:55:05 -0800224 StatsDimensionsValue dimensionsValue) {
Bookatzc6977972018-01-16 16:55:05 -0800225 enforceCallingPermission();
226 IntentSender intentSender = new IntentSender(intentSenderBinder);
227 Intent intent = new Intent()
228 .putExtra(StatsManager.EXTRA_STATS_CONFIG_UID, configUid)
229 .putExtra(StatsManager.EXTRA_STATS_CONFIG_KEY, configKey)
230 .putExtra(StatsManager.EXTRA_STATS_SUBSCRIPTION_ID, subscriptionId)
231 .putExtra(StatsManager.EXTRA_STATS_SUBSCRIPTION_RULE_ID, subscriptionRuleId)
232 .putExtra(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE, dimensionsValue);
Bookatz058d8692018-03-06 09:53:47 -0800233
234 ArrayList<String> cookieList = new ArrayList<>(cookies.length);
235 for (String cookie : cookies) { cookieList.add(cookie); }
236 intent.putStringArrayListExtra(
237 StatsManager.EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES, cookieList);
238
Bookatz1476ef22018-02-13 12:26:01 -0800239 if (DEBUG) {
Bookatz058d8692018-03-06 09:53:47 -0800240 Slog.d(TAG, String.format(
241 "Statsd sendSubscriberBroadcast with params {%d %d %d %d %s %s}",
242 configUid, configKey, subscriptionId, subscriptionRuleId,
243 Arrays.toString(cookies), dimensionsValue));
Bookatz1476ef22018-02-13 12:26:01 -0800244 }
Bookatzc6977972018-01-16 16:55:05 -0800245 try {
246 intentSender.sendIntent(mContext, CODE_SUBSCRIBER_BROADCAST, intent, null, null);
247 } catch (IntentSender.SendIntentException e) {
248 Slog.w(TAG, "Unable to send using IntentSender from uid " + configUid
249 + "; presumably it had been cancelled.");
Bookatzc6977972018-01-16 16:55:05 -0800250 }
251 }
252
David Chen1481fe12017-10-16 13:16:34 -0700253 private final static int[] toIntArray(List<Integer> list) {
David Chende701692017-10-05 13:16:02 -0700254 int[] ret = new int[list.size()];
David Chen1481fe12017-10-16 13:16:34 -0700255 for (int i = 0; i < ret.length; i++) {
David Chende701692017-10-05 13:16:02 -0700256 ret[i] = list.get(i);
257 }
258 return ret;
259 }
260
Dianne Hackborn3accca02013-09-20 09:32:11 -0700261 private final static long[] toLongArray(List<Long> list) {
262 long[] ret = new long[list.size()];
263 for (int i = 0; i < ret.length; i++) {
264 ret[i] = list.get(i);
265 }
266 return ret;
267 }
268
David Chende701692017-10-05 13:16:02 -0700269 // Assumes that sStatsdLock is held.
Andreas Gampea36dc622018-02-05 17:19:22 -0800270 @GuardedBy("sStatsdLock")
David Chende701692017-10-05 13:16:02 -0700271 private final void informAllUidsLocked(Context context) throws RemoteException {
272 UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
273 PackageManager pm = context.getPackageManager();
274 final List<UserInfo> users = um.getUsers(true);
275 if (DEBUG) {
Bookatz111ed732018-02-16 15:54:05 -0800276 Slog.d(TAG, "Iterating over " + users.size() + " profiles.");
David Chende701692017-10-05 13:16:02 -0700277 }
278
Rajeev Kumar22d92b72018-02-07 18:38:36 -0800279 List<Integer> uids = new ArrayList<>();
280 List<Long> versions = new ArrayList<>();
281 List<String> apps = new ArrayList<>();
David Chende701692017-10-05 13:16:02 -0700282
283 // Add in all the apps for every user/profile.
284 for (UserInfo profile : users) {
David Chenbd125272018-04-04 19:02:50 -0700285 List<PackageInfo> pi =
David Chend37bc232018-04-12 18:05:11 -0700286 pm.getInstalledPackagesAsUser(PackageManager.MATCH_KNOWN_PACKAGES, profile.id);
David Chen1481fe12017-10-16 13:16:34 -0700287 for (int j = 0; j < pi.size(); j++) {
288 if (pi.get(j).applicationInfo != null) {
289 uids.add(pi.get(j).applicationInfo.uid);
Dianne Hackborn3accca02013-09-20 09:32:11 -0700290 versions.add(pi.get(j).getLongVersionCode());
David Chen1481fe12017-10-16 13:16:34 -0700291 apps.add(pi.get(j).packageName);
292 }
293 }
David Chende701692017-10-05 13:16:02 -0700294 }
Dianne Hackborn3accca02013-09-20 09:32:11 -0700295 sStatsd.informAllUidData(toIntArray(uids), toLongArray(versions), apps.toArray(new
David Chen1481fe12017-10-16 13:16:34 -0700296 String[apps.size()]));
David Chende701692017-10-05 13:16:02 -0700297 if (DEBUG) {
Bookatz111ed732018-02-16 15:54:05 -0800298 Slog.d(TAG, "Sent data for " + uids.size() + " apps");
David Chende701692017-10-05 13:16:02 -0700299 }
300 }
301
Bookatz36920822018-01-26 09:18:07 -0800302 private final static class AppUpdateReceiver extends BroadcastReceiver {
David Chende701692017-10-05 13:16:02 -0700303 @Override
304 public void onReceive(Context context, Intent intent) {
David Chen47e8f4d2017-10-11 15:34:13 -0700305 /**
306 * App updates actually consist of REMOVE, ADD, and then REPLACE broadcasts. To avoid
307 * waste, we ignore the REMOVE and ADD broadcasts that contain the replacing flag.
David Chend6896892017-10-25 11:49:03 -0700308 * If we can't find the value for EXTRA_REPLACING, we default to false.
David Chen47e8f4d2017-10-11 15:34:13 -0700309 */
David Chend6896892017-10-25 11:49:03 -0700310 if (!intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)
311 && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
David Chen47e8f4d2017-10-11 15:34:13 -0700312 return; // Keep only replacing or normal add and remove.
313 }
Tej Singh90d3aa02018-03-08 19:07:58 -0800314 if (DEBUG) Slog.d(TAG, "StatsCompanionService noticed an app was updated.");
David Chende701692017-10-05 13:16:02 -0700315 synchronized (sStatsdLock) {
316 if (sStatsd == null) {
yrof6d1ca52017-11-15 15:38:34 -0800317 Slog.w(TAG, "Could not access statsd to inform it of an app update");
David Chende701692017-10-05 13:16:02 -0700318 return;
319 }
320 try {
321 if (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) {
322 Bundle b = intent.getExtras();
323 int uid = b.getInt(Intent.EXTRA_UID);
324 boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
325 if (!replacing) {
326 // Don't bother sending an update if we're right about to get another
327 // intent for the new version that's added.
328 PackageManager pm = context.getPackageManager();
329 String app = intent.getData().getSchemeSpecificPart();
330 sStatsd.informOnePackageRemoved(app, uid);
Howard Roe4f3df62018-08-01 11:19:10 -0700331 StatsLog.write(StatsLog.GENERIC_ATOM, uid, 1000);
David Chende701692017-10-05 13:16:02 -0700332 }
333 } else {
334 PackageManager pm = context.getPackageManager();
335 Bundle b = intent.getExtras();
336 int uid = b.getInt(Intent.EXTRA_UID);
337 String app = intent.getData().getSchemeSpecificPart();
338 PackageInfo pi = pm.getPackageInfo(app, PackageManager.MATCH_ANY_USER);
Dianne Hackborn3accca02013-09-20 09:32:11 -0700339 sStatsd.informOnePackage(app, uid, pi.getLongVersionCode());
Howard Roe4f3df62018-08-01 11:19:10 -0700340 StatsLog.write(StatsLog.GENERIC_ATOM, uid, 1001);
David Chende701692017-10-05 13:16:02 -0700341 }
342 } catch (Exception e) {
343 Slog.w(TAG, "Failed to inform statsd of an app update", e);
344 }
345 }
346 }
David Chen1481fe12017-10-16 13:16:34 -0700347 }
David Chende701692017-10-05 13:16:02 -0700348
Bookatz75158ac2018-05-18 15:55:23 -0700349 public final static class AnomalyAlarmListener implements OnAlarmListener {
Bookatz94726412017-08-31 09:26:15 -0700350 @Override
Bookatz75158ac2018-05-18 15:55:23 -0700351 public void onAlarm() {
Bookatz66fe0612018-02-07 18:51:48 -0800352 Slog.i(TAG, "StatsCompanionService believes an anomaly has occurred at time "
353 + System.currentTimeMillis() + "ms.");
Bookatzb487b552017-09-18 11:26:01 -0700354 synchronized (sStatsdLock) {
355 if (sStatsd == null) {
356 Slog.w(TAG, "Could not access statsd to inform it of anomaly alarm firing");
357 return;
358 }
359 try {
360 // Two-way call to statsd to retain AlarmManager wakelock
361 sStatsd.informAnomalyAlarmFired();
362 } catch (RemoteException e) {
363 Slog.w(TAG, "Failed to inform statsd of anomaly alarm firing", e);
364 }
Bookatz94726412017-08-31 09:26:15 -0700365 }
Bookatzb487b552017-09-18 11:26:01 -0700366 // AlarmManager releases its own wakelock here.
Bookatz94726412017-08-31 09:26:15 -0700367 }
David Chen1481fe12017-10-16 13:16:34 -0700368 }
Bookatzb487b552017-09-18 11:26:01 -0700369
Bookatz75158ac2018-05-18 15:55:23 -0700370 public final static class PullingAlarmListener implements OnAlarmListener {
David Chen661f7912018-01-22 17:46:24 -0800371 @Override
Bookatz75158ac2018-05-18 15:55:23 -0700372 public void onAlarm() {
David Chen661f7912018-01-22 17:46:24 -0800373 if (DEBUG)
374 Slog.d(TAG, "Time to poll something.");
375 synchronized (sStatsdLock) {
376 if (sStatsd == null) {
377 Slog.w(TAG, "Could not access statsd to inform it of pulling alarm firing.");
378 return;
379 }
380 try {
381 // Two-way call to statsd to retain AlarmManager wakelock
382 sStatsd.informPollAlarmFired();
383 } catch (RemoteException e) {
384 Slog.w(TAG, "Failed to inform statsd of pulling alarm firing.", e);
385 }
386 }
Bookatzb487b552017-09-18 11:26:01 -0700387 }
David Chen1481fe12017-10-16 13:16:34 -0700388 }
Bookatz94726412017-08-31 09:26:15 -0700389
Bookatz75158ac2018-05-18 15:55:23 -0700390 public final static class PeriodicAlarmListener implements OnAlarmListener {
Yangster-mac932ecec2018-02-01 10:23:52 -0800391 @Override
Bookatz75158ac2018-05-18 15:55:23 -0700392 public void onAlarm() {
Yangster-mac932ecec2018-02-01 10:23:52 -0800393 if (DEBUG)
Yangster-macc04feba2018-04-02 14:37:33 -0700394 Slog.d(TAG, "Time to trigger periodic alarm.");
Yangster-mac932ecec2018-02-01 10:23:52 -0800395 synchronized (sStatsdLock) {
396 if (sStatsd == null) {
397 Slog.w(TAG, "Could not access statsd to inform it of periodic alarm firing.");
398 return;
399 }
400 try {
401 // Two-way call to statsd to retain AlarmManager wakelock
402 sStatsd.informAlarmForSubscriberTriggeringFired();
403 } catch (RemoteException e) {
404 Slog.w(TAG, "Failed to inform statsd of periodic alarm firing.", e);
405 }
406 }
407 // AlarmManager releases its own wakelock here.
408 }
409 }
410
411 public final static class ShutdownEventReceiver extends BroadcastReceiver {
yro947fbce2017-11-15 22:50:23 -0800412 @Override
413 public void onReceive(Context context, Intent intent) {
414 /**
415 * Skip immediately if intent is not relevant to device shutdown.
416 */
417 if (!intent.getAction().equals(Intent.ACTION_REBOOT)
David Chen661f7912018-01-22 17:46:24 -0800418 && !(intent.getAction().equals(Intent.ACTION_SHUTDOWN)
419 && (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0)) {
420 return;
yro947fbce2017-11-15 22:50:23 -0800421 }
yrof7a3bcb2018-01-24 17:18:55 -0800422
yro947fbce2017-11-15 22:50:23 -0800423 Slog.i(TAG, "StatsCompanionService noticed a shutdown.");
424 synchronized (sStatsdLock) {
425 if (sStatsd == null) {
426 Slog.w(TAG, "Could not access statsd to inform it of a shutdown event.");
427 return;
428 }
429 try {
Yangster-mac892f3d32018-05-02 14:16:48 -0700430 sStatsd.informDeviceShutdown();
yro947fbce2017-11-15 22:50:23 -0800431 } catch (Exception e) {
432 Slog.w(TAG, "Failed to inform statsd of a shutdown event.", e);
433 }
434 }
435 }
436 }
437
Bookatz94726412017-08-31 09:26:15 -0700438 @Override // Binder call
439 public void setAnomalyAlarm(long timestampMs) {
440 enforceCallingPermission();
441 if (DEBUG) Slog.d(TAG, "Setting anomaly alarm for " + timestampMs);
442 final long callingToken = Binder.clearCallingIdentity();
443 try {
Yangster-mac330af582018-02-08 15:24:38 -0800444 // using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will
445 // only fire when it awakens.
Bookatz75158ac2018-05-18 15:55:23 -0700446 // AlarmManager will automatically cancel any previous mAnomalyAlarmListener alarm.
447 mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, timestampMs, TAG + ".anomaly",
448 mAnomalyAlarmListener, null);
Bookatz94726412017-08-31 09:26:15 -0700449 } finally {
450 Binder.restoreCallingIdentity(callingToken);
451 }
452 }
453
454 @Override // Binder call
455 public void cancelAnomalyAlarm() {
456 enforceCallingPermission();
457 if (DEBUG) Slog.d(TAG, "Cancelling anomaly alarm");
458 final long callingToken = Binder.clearCallingIdentity();
459 try {
Bookatz75158ac2018-05-18 15:55:23 -0700460 mAlarmManager.cancel(mAnomalyAlarmListener);
Bookatz94726412017-08-31 09:26:15 -0700461 } finally {
462 Binder.restoreCallingIdentity(callingToken);
463 }
464 }
465
466 @Override // Binder call
Yangster-mac932ecec2018-02-01 10:23:52 -0800467 public void setAlarmForSubscriberTriggering(long timestampMs) {
468 enforceCallingPermission();
469 if (DEBUG)
Yangster-macc04feba2018-04-02 14:37:33 -0700470 Slog.d(TAG, "Setting periodic alarm in about " +
471 (timestampMs - SystemClock.elapsedRealtime()));
Yangster-mac932ecec2018-02-01 10:23:52 -0800472 final long callingToken = Binder.clearCallingIdentity();
473 try {
474 // using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will
475 // only fire when it awakens.
Bookatz75158ac2018-05-18 15:55:23 -0700476 mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, timestampMs, TAG + ".periodic",
477 mPeriodicAlarmListener, null);
Yangster-mac932ecec2018-02-01 10:23:52 -0800478 } finally {
479 Binder.restoreCallingIdentity(callingToken);
480 }
481 }
482
483 @Override // Binder call
484 public void cancelAlarmForSubscriberTriggering() {
485 enforceCallingPermission();
486 if (DEBUG)
487 Slog.d(TAG, "Cancelling periodic alarm");
488 final long callingToken = Binder.clearCallingIdentity();
489 try {
Bookatz75158ac2018-05-18 15:55:23 -0700490 mAlarmManager.cancel(mPeriodicAlarmListener);
Yangster-mac932ecec2018-02-01 10:23:52 -0800491 } finally {
492 Binder.restoreCallingIdentity(callingToken);
493 }
494 }
495
496 @Override // Binder call
Chenjie Yu1a0a9412018-03-28 10:07:22 -0700497 public void setPullingAlarm(long nextPullTimeMs) {
Bookatz75158ac2018-05-18 15:55:23 -0700498 enforceCallingPermission();
499 if (DEBUG) {
500 Slog.d(TAG, "Setting pulling alarm in about "
501 + (nextPullTimeMs - SystemClock.elapsedRealtime()));
502 }
503 final long callingToken = Binder.clearCallingIdentity();
504 try {
505 // using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will
506 // only fire when it awakens.
507 mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, nextPullTimeMs, TAG + ".pull",
508 mPullingAlarmListener, null);
509 } finally {
510 Binder.restoreCallingIdentity(callingToken);
511 }
Bookatz94726412017-08-31 09:26:15 -0700512 }
513
514 @Override // Binder call
Chenjie Yu1a0a9412018-03-28 10:07:22 -0700515 public void cancelPullingAlarm() {
Bookatz75158ac2018-05-18 15:55:23 -0700516 enforceCallingPermission();
517 if (DEBUG)
518 Slog.d(TAG, "Cancelling pulling alarm");
519 final long callingToken = Binder.clearCallingIdentity();
520 try {
521 mAlarmManager.cancel(mPullingAlarmListener);
522 } finally {
523 Binder.restoreCallingIdentity(callingToken);
524 }
Bookatz94726412017-08-31 09:26:15 -0700525 }
526
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800527 private void addNetworkStats(
David Chen661f7912018-01-22 17:46:24 -0800528 int tag, List<StatsLogEventWrapper> ret, NetworkStats stats, boolean withFGBG) {
529 int size = stats.size();
Yangster-macc552b352018-02-22 10:00:45 -0800530 long elapsedNanos = SystemClock.elapsedRealtimeNanos();
David Chen661f7912018-01-22 17:46:24 -0800531 NetworkStats.Entry entry = new NetworkStats.Entry(); // For recycling
532 for (int j = 0; j < size; j++) {
533 stats.getValues(j, entry);
Yangster-macc552b352018-02-22 10:00:45 -0800534 StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tag, withFGBG ? 6 : 5);
David Chen661f7912018-01-22 17:46:24 -0800535 e.writeInt(entry.uid);
536 if (withFGBG) {
537 e.writeInt(entry.set);
538 }
539 e.writeLong(entry.rxBytes);
540 e.writeLong(entry.rxPackets);
541 e.writeLong(entry.txBytes);
542 e.writeLong(entry.txPackets);
543 ret.add(e);
David Chenc8a43242017-10-17 16:23:28 -0700544 }
David Chenc8a43242017-10-17 16:23:28 -0700545 }
546
547 /**
548 * Allows rollups per UID but keeping the set (foreground/background) slicing.
549 * Adapted from groupedByUid in frameworks/base/core/java/android/net/NetworkStats.java
550 */
551 private NetworkStats rollupNetworkStatsByFGBG(NetworkStats stats) {
552 final NetworkStats ret = new NetworkStats(stats.getElapsedRealtime(), 1);
553
554 final NetworkStats.Entry entry = new NetworkStats.Entry();
555 entry.iface = NetworkStats.IFACE_ALL;
556 entry.tag = NetworkStats.TAG_NONE;
557 entry.metered = NetworkStats.METERED_ALL;
558 entry.roaming = NetworkStats.ROAMING_ALL;
559
560 int size = stats.size();
561 NetworkStats.Entry recycle = new NetworkStats.Entry(); // Used for retrieving values
562 for (int i = 0; i < size; i++) {
563 stats.getValues(i, recycle);
564
565 // Skip specific tags, since already counted in TAG_NONE
566 if (recycle.tag != NetworkStats.TAG_NONE) continue;
567
568 entry.set = recycle.set; // Allows slicing by background/foreground
569 entry.uid = recycle.uid;
570 entry.rxBytes = recycle.rxBytes;
571 entry.rxPackets = recycle.rxPackets;
572 entry.txBytes = recycle.txBytes;
573 entry.txPackets = recycle.txPackets;
574 // Operations purposefully omitted since we don't use them for statsd.
575 ret.combineValues(entry);
576 }
577 return ret;
578 }
579
Chenjie Yu05013b32017-11-21 10:21:41 -0800580 /**
581 * Helper method to extract the Parcelable controller info from a
582 * SynchronousResultReceiver.
583 */
584 private static <T extends Parcelable> T awaitControllerInfo(
585 @Nullable SynchronousResultReceiver receiver) {
586 if (receiver == null) {
587 return null;
588 }
589
590 try {
591 final SynchronousResultReceiver.Result result =
592 receiver.awaitResult(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS);
593 if (result.bundle != null) {
594 // This is the final destination for the Bundle.
595 result.bundle.setDefusable(true);
596
597 final T data = result.bundle.getParcelable(
598 RESULT_RECEIVER_CONTROLLER_KEY);
599 if (data != null) {
600 return data;
601 }
602 }
603 Slog.e(TAG, "no controller energy info supplied for " + receiver.getName());
604 } catch (TimeoutException e) {
605 Slog.w(TAG, "timeout reading " + receiver.getName() + " stats");
606 }
607 return null;
608 }
609
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800610 private void pullKernelWakelock(int tagId, List<StatsLogEventWrapper> pulledData) {
David Chen661f7912018-01-22 17:46:24 -0800611 final KernelWakelockStats wakelockStats =
612 mKernelWakelockReader.readKernelWakelockStats(mTmpWakelockStats);
Yangster-macc552b352018-02-22 10:00:45 -0800613 long elapsedNanos = SystemClock.elapsedRealtimeNanos();
David Chen661f7912018-01-22 17:46:24 -0800614 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) {
615 String name = ent.getKey();
616 KernelWakelockStats.Entry kws = ent.getValue();
Yangster-macc552b352018-02-22 10:00:45 -0800617 StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 4);
David Chen661f7912018-01-22 17:46:24 -0800618 e.writeString(name);
619 e.writeInt(kws.mCount);
620 e.writeInt(kws.mVersion);
621 e.writeLong(kws.mTotalTime);
622 pulledData.add(e);
623 }
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800624 }
625
626 private void pullWifiBytesTransfer(int tagId, List<StatsLogEventWrapper> pulledData) {
David Chen661f7912018-01-22 17:46:24 -0800627 long token = Binder.clearCallingIdentity();
628 try {
629 // TODO: Consider caching the following call to get BatteryStatsInternal.
630 BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class);
631 String[] ifaces = bs.getWifiIfaces();
632 if (ifaces.length == 0) {
633 return;
634 }
635 NetworkStatsFactory nsf = new NetworkStatsFactory();
636 // Combine all the metrics per Uid into one record.
637 NetworkStats stats =
638 nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null)
639 .groupedByUid();
640 addNetworkStats(tagId, pulledData, stats, false);
641 } catch (java.io.IOException e) {
642 Slog.e(TAG, "Pulling netstats for wifi bytes has error", e);
643 } finally {
644 Binder.restoreCallingIdentity(token);
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800645 }
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800646 }
647
648 private void pullWifiBytesTransferByFgBg(int tagId, List<StatsLogEventWrapper> pulledData) {
David Chen661f7912018-01-22 17:46:24 -0800649 long token = Binder.clearCallingIdentity();
650 try {
651 BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class);
652 String[] ifaces = bs.getWifiIfaces();
653 if (ifaces.length == 0) {
654 return;
655 }
656 NetworkStatsFactory nsf = new NetworkStatsFactory();
657 NetworkStats stats = rollupNetworkStatsByFGBG(
658 nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null));
659 addNetworkStats(tagId, pulledData, stats, true);
660 } catch (java.io.IOException e) {
661 Slog.e(TAG, "Pulling netstats for wifi bytes w/ fg/bg has error", e);
662 } finally {
663 Binder.restoreCallingIdentity(token);
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800664 }
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800665 }
666
667 private void pullMobileBytesTransfer(int tagId, List<StatsLogEventWrapper> pulledData) {
David Chen661f7912018-01-22 17:46:24 -0800668 long token = Binder.clearCallingIdentity();
669 try {
670 BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class);
671 String[] ifaces = bs.getMobileIfaces();
672 if (ifaces.length == 0) {
673 return;
674 }
675 NetworkStatsFactory nsf = new NetworkStatsFactory();
676 // Combine all the metrics per Uid into one record.
677 NetworkStats stats =
678 nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null)
679 .groupedByUid();
680 addNetworkStats(tagId, pulledData, stats, false);
681 } catch (java.io.IOException e) {
682 Slog.e(TAG, "Pulling netstats for mobile bytes has error", e);
683 } finally {
684 Binder.restoreCallingIdentity(token);
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800685 }
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800686 }
687
688 private void pullBluetoothBytesTransfer(int tagId, List<StatsLogEventWrapper> pulledData) {
David Chen661f7912018-01-22 17:46:24 -0800689 BluetoothActivityEnergyInfo info = pullBluetoothData();
Yangster-macc552b352018-02-22 10:00:45 -0800690 long elapsedNanos = SystemClock.elapsedRealtimeNanos();
Chenjie Yu9e59f932018-03-30 16:41:38 -0700691 if (info.getUidTraffic() != null) {
692 for (UidTraffic traffic : info.getUidTraffic()) {
693 StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3);
694 e.writeInt(traffic.getUid());
695 e.writeLong(traffic.getRxBytes());
696 e.writeLong(traffic.getTxBytes());
697 pulledData.add(e);
698 }
David Chen661f7912018-01-22 17:46:24 -0800699 }
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800700 }
701
702 private void pullMobileBytesTransferByFgBg(int tagId, List<StatsLogEventWrapper> pulledData) {
David Chen661f7912018-01-22 17:46:24 -0800703 long token = Binder.clearCallingIdentity();
704 try {
705 BatteryStatsInternal bs = LocalServices.getService(BatteryStatsInternal.class);
706 String[] ifaces = bs.getMobileIfaces();
707 if (ifaces.length == 0) {
708 return;
709 }
710 NetworkStatsFactory nsf = new NetworkStatsFactory();
711 NetworkStats stats = rollupNetworkStatsByFGBG(
712 nsf.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces, NetworkStats.TAG_NONE, null));
713 addNetworkStats(tagId, pulledData, stats, true);
714 } catch (java.io.IOException e) {
715 Slog.e(TAG, "Pulling netstats for mobile bytes w/ fg/bg has error", e);
716 } finally {
717 Binder.restoreCallingIdentity(token);
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800718 }
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800719 }
720
721 private void pullCpuTimePerFreq(int tagId, List<StatsLogEventWrapper> pulledData) {
Yangster-macc552b352018-02-22 10:00:45 -0800722 long elapsedNanos = SystemClock.elapsedRealtimeNanos();
David Chen661f7912018-01-22 17:46:24 -0800723 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) {
724 long[] clusterTimeMs = mKernelCpuSpeedReaders[cluster].readAbsolute();
725 if (clusterTimeMs != null) {
726 for (int speed = clusterTimeMs.length - 1; speed >= 0; --speed) {
Yangster-macc552b352018-02-22 10:00:45 -0800727 StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3);
David Chen661f7912018-01-22 17:46:24 -0800728 e.writeInt(cluster);
729 e.writeInt(speed);
730 e.writeLong(clusterTimeMs[speed]);
731 pulledData.add(e);
732 }
733 }
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800734 }
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800735 }
736
Chenjie Yuec676612018-03-07 09:19:17 -0800737 private void pullKernelUidCpuTime(int tagId, List<StatsLogEventWrapper> pulledData) {
738 long elapsedNanos = SystemClock.elapsedRealtimeNanos();
739 mKernelUidCpuTimeReader.readAbsolute((uid, userTimeUs, systemTimeUs) -> {
740 StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3);
741 e.writeInt(uid);
742 e.writeLong(userTimeUs);
743 e.writeLong(systemTimeUs);
744 pulledData.add(e);
745 });
746 }
747
748 private void pullKernelUidCpuFreqTime(int tagId, List<StatsLogEventWrapper> pulledData) {
749 long elapsedNanos = SystemClock.elapsedRealtimeNanos();
750 mKernelUidCpuFreqTimeReader.readAbsolute((uid, cpuFreqTimeMs) -> {
751 for (int freqIndex = 0; freqIndex < cpuFreqTimeMs.length; ++freqIndex) {
Chenjie Yu4460e3c2018-03-14 17:12:59 -0700752 if(cpuFreqTimeMs[freqIndex] != 0) {
753 StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3);
754 e.writeInt(uid);
755 e.writeInt(freqIndex);
756 e.writeLong(cpuFreqTimeMs[freqIndex]);
757 pulledData.add(e);
758 }
Chenjie Yuec676612018-03-07 09:19:17 -0800759 }
760 });
761 }
762
763 private void pullKernelUidCpuClusterTime(int tagId, List<StatsLogEventWrapper> pulledData) {
764 long elapsedNanos = SystemClock.elapsedRealtimeNanos();
765 mKernelUidCpuClusterTimeReader.readAbsolute((uid, cpuClusterTimesMs) -> {
766 for (int i = 0; i < cpuClusterTimesMs.length; i++) {
767 StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3);
768 e.writeInt(uid);
769 e.writeInt(i);
770 e.writeLong(cpuClusterTimesMs[i]);
771 pulledData.add(e);
772 }
773 });
774 }
775
776 private void pullKernelUidCpuActiveTime(int tagId, List<StatsLogEventWrapper> pulledData) {
777 long elapsedNanos = SystemClock.elapsedRealtimeNanos();
778 mKernelUidCpuActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> {
779 StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 2);
780 e.writeInt(uid);
781 e.writeLong((long)cpuActiveTimesMs);
782 pulledData.add(e);
783 });
784 }
785
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800786 private void pullWifiActivityInfo(int tagId, List<StatsLogEventWrapper> pulledData) {
David Chen661f7912018-01-22 17:46:24 -0800787 long token = Binder.clearCallingIdentity();
788 if (mWifiManager == null) {
789 mWifiManager =
790 IWifiManager.Stub.asInterface(ServiceManager.getService(Context.WIFI_SERVICE));
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800791 }
David Chen661f7912018-01-22 17:46:24 -0800792 if (mWifiManager != null) {
793 try {
794 SynchronousResultReceiver wifiReceiver = new SynchronousResultReceiver("wifi");
795 mWifiManager.requestActivityInfo(wifiReceiver);
796 final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver);
Yangster-macc552b352018-02-22 10:00:45 -0800797 StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 6);
David Chen661f7912018-01-22 17:46:24 -0800798 e.writeLong(wifiInfo.getTimeStamp());
799 e.writeInt(wifiInfo.getStackState());
800 e.writeLong(wifiInfo.getControllerTxTimeMillis());
801 e.writeLong(wifiInfo.getControllerRxTimeMillis());
802 e.writeLong(wifiInfo.getControllerIdleTimeMillis());
803 e.writeLong(wifiInfo.getControllerEnergyUsed());
804 pulledData.add(e);
805 } catch (RemoteException e) {
806 Slog.e(TAG, "Pulling wifiManager for wifi controller activity energy info has error", e);
807 } finally {
808 Binder.restoreCallingIdentity(token);
809 }
810 }
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800811 }
812
813 private void pullModemActivityInfo(int tagId, List<StatsLogEventWrapper> pulledData) {
David Chen661f7912018-01-22 17:46:24 -0800814 long token = Binder.clearCallingIdentity();
815 if (mTelephony == null) {
816 mTelephony = TelephonyManager.from(mContext);
817 }
818 if (mTelephony != null) {
819 SynchronousResultReceiver modemReceiver = new SynchronousResultReceiver("telephony");
820 mTelephony.requestModemActivityInfo(modemReceiver);
821 final ModemActivityInfo modemInfo = awaitControllerInfo(modemReceiver);
David Chen56ae0d92018-05-11 16:00:22 -0700822 StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 10);
David Chen661f7912018-01-22 17:46:24 -0800823 e.writeLong(modemInfo.getTimestamp());
824 e.writeLong(modemInfo.getSleepTimeMillis());
825 e.writeLong(modemInfo.getIdleTimeMillis());
826 e.writeLong(modemInfo.getTxTimeMillis()[0]);
827 e.writeLong(modemInfo.getTxTimeMillis()[1]);
828 e.writeLong(modemInfo.getTxTimeMillis()[2]);
829 e.writeLong(modemInfo.getTxTimeMillis()[3]);
830 e.writeLong(modemInfo.getTxTimeMillis()[4]);
831 e.writeLong(modemInfo.getRxTimeMillis());
832 e.writeLong(modemInfo.getEnergyUsed());
833 pulledData.add(e);
834 }
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800835 }
836
837 private void pullBluetoothActivityInfo(int tagId, List<StatsLogEventWrapper> pulledData) {
David Chen661f7912018-01-22 17:46:24 -0800838 BluetoothActivityEnergyInfo info = pullBluetoothData();
Yangster-macc552b352018-02-22 10:00:45 -0800839 StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 6);
David Chen661f7912018-01-22 17:46:24 -0800840 e.writeLong(info.getTimeStamp());
841 e.writeInt(info.getBluetoothStackState());
842 e.writeLong(info.getControllerTxTimeMillis());
843 e.writeLong(info.getControllerRxTimeMillis());
844 e.writeLong(info.getControllerIdleTimeMillis());
845 e.writeLong(info.getControllerEnergyUsed());
846 pulledData.add(e);
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800847 }
848
849 private synchronized BluetoothActivityEnergyInfo pullBluetoothData() {
Chenjie Yuc2d65442018-02-01 22:27:17 -0800850 final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
David Chen661f7912018-01-22 17:46:24 -0800851 if (adapter != null) {
852 SynchronousResultReceiver bluetoothReceiver = new SynchronousResultReceiver("bluetooth");
853 adapter.requestControllerActivityEnergyInfo(bluetoothReceiver);
854 return awaitControllerInfo(bluetoothReceiver);
855 } else {
856 Slog.e(TAG, "Failed to get bluetooth adapter!");
857 return null;
858 }
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800859 }
860
861 private void pullSystemElapsedRealtime(int tagId, List<StatsLogEventWrapper> pulledData) {
Yangster-macc552b352018-02-22 10:00:45 -0800862 StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 1);
David Chen661f7912018-01-22 17:46:24 -0800863 e.writeLong(SystemClock.elapsedRealtime());
864 pulledData.add(e);
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800865 }
866
Tej Singh6188aa32018-08-29 00:21:07 +0000867 private void pullDiskSpace(int tagId, List<StatsLogEventWrapper> pulledData) {
868 StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 3);
869 e.writeLong(mStatFsData.getAvailableBytes());
870 e.writeLong(mStatFsSystem.getAvailableBytes());
871 e.writeLong(mStatFsTemp.getAvailableBytes());
872 pulledData.add(e);
873 }
874
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800875 private void pullSystemUpTime(int tagId, List<StatsLogEventWrapper> pulledData) {
Yangster-macc552b352018-02-22 10:00:45 -0800876 StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 1);
David Chen661f7912018-01-22 17:46:24 -0800877 e.writeLong(SystemClock.uptimeMillis());
878 pulledData.add(e);
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800879 }
880
Rajeev Kumar22d92b72018-02-07 18:38:36 -0800881 private void pullProcessMemoryState(int tagId, List<StatsLogEventWrapper> pulledData) {
882 List<ProcessMemoryState> processMemoryStates =
883 LocalServices.getService(ActivityManagerInternal.class)
884 .getMemoryStateForProcesses();
Yangster-macc552b352018-02-22 10:00:45 -0800885 long elapsedNanos = SystemClock.elapsedRealtimeNanos();
Rajeev Kumar22d92b72018-02-07 18:38:36 -0800886 for (ProcessMemoryState processMemoryState : processMemoryStates) {
Yangster-macc552b352018-02-22 10:00:45 -0800887 StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 8 /* fields */);
Rajeev Kumar22d92b72018-02-07 18:38:36 -0800888 e.writeInt(processMemoryState.uid);
889 e.writeString(processMemoryState.processName);
890 e.writeInt(processMemoryState.oomScore);
891 e.writeLong(processMemoryState.pgfault);
892 e.writeLong(processMemoryState.pgmajfault);
893 e.writeLong(processMemoryState.rssInBytes);
894 e.writeLong(processMemoryState.cacheInBytes);
895 e.writeLong(processMemoryState.swapInBytes);
896 pulledData.add(e);
897 }
898 }
899
Olivier Gaillard00bfb1b2018-07-10 11:25:09 +0100900 private void pullBinderCallsStats(int tagId, List<StatsLogEventWrapper> pulledData) {
Olivier Gaillard289ba402018-07-24 18:50:13 +0100901 BinderCallsStatsService.Internal binderStats =
902 LocalServices.getService(BinderCallsStatsService.Internal.class);
Olivier Gaillard44a60a92018-07-25 22:53:55 +0100903 if (binderStats == null) {
904 return;
905 }
906
Olivier Gaillard289ba402018-07-24 18:50:13 +0100907 List<ExportedCallStat> callStats = binderStats.getExportedCallStats();
Olivier Gaillard00bfb1b2018-07-10 11:25:09 +0100908 long elapsedNanos = SystemClock.elapsedRealtimeNanos();
909 for (ExportedCallStat callStat : callStats) {
Olivier Gaillard6f52d152018-07-25 12:13:12 +0100910 StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 13 /* fields */);
Olivier Gaillard00bfb1b2018-07-10 11:25:09 +0100911 e.writeInt(callStat.uid);
912 e.writeString(callStat.className);
913 e.writeString(callStat.methodName);
914 e.writeLong(callStat.callCount);
915 e.writeLong(callStat.exceptionCount);
916 e.writeLong(callStat.latencyMicros);
917 e.writeLong(callStat.maxLatencyMicros);
918 e.writeLong(callStat.cpuTimeMicros);
919 e.writeLong(callStat.maxCpuTimeMicros);
920 e.writeLong(callStat.maxReplySizeBytes);
921 e.writeLong(callStat.maxRequestSizeBytes);
Olivier Gaillard6f52d152018-07-25 12:13:12 +0100922 e.writeLong(callStat.recordedCallCount);
923 e.writeInt(callStat.screenInteractive ? 1 : 0);
924 pulledData.add(e);
925 }
926 }
927
928 private void pullBinderCallsStatsExceptions(int tagId, List<StatsLogEventWrapper> pulledData) {
929 BinderCallsStatsService.Internal binderStats =
930 LocalServices.getService(BinderCallsStatsService.Internal.class);
Olivier Gaillard44a60a92018-07-25 22:53:55 +0100931 if (binderStats == null) {
932 return;
933 }
934
Olivier Gaillard6f52d152018-07-25 12:13:12 +0100935 ArrayMap<String, Integer> exceptionStats = binderStats.getExportedExceptionStats();
936 long elapsedNanos = SystemClock.elapsedRealtimeNanos();
937 for (Entry<String, Integer> entry : exceptionStats.entrySet()) {
938 StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 2 /* fields */);
939 e.writeString(entry.getKey());
940 e.writeInt(entry.getValue());
Olivier Gaillard00bfb1b2018-07-10 11:25:09 +0100941 pulledData.add(e);
942 }
943 }
944
Chenjie Yu05013b32017-11-21 10:21:41 -0800945 /**
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800946 * Pulls various data.
Chenjie Yu05013b32017-11-21 10:21:41 -0800947 */
Bookatzc68a9d22017-09-27 14:09:55 -0700948 @Override // Binder call
Chenjie Yu5305e1d2017-10-31 13:49:36 -0700949 public StatsLogEventWrapper[] pullData(int tagId) {
Bookatzc68a9d22017-09-27 14:09:55 -0700950 enforceCallingPermission();
David Chenc8a43242017-10-17 16:23:28 -0700951 if (DEBUG)
Chenjie Yu5305e1d2017-10-31 13:49:36 -0700952 Slog.d(TAG, "Pulling " + tagId);
Rajeev Kumar22d92b72018-02-07 18:38:36 -0800953 List<StatsLogEventWrapper> ret = new ArrayList<>();
Chenjie Yu5305e1d2017-10-31 13:49:36 -0700954 switch (tagId) {
Chenjie Yu31d14d72017-12-12 17:54:33 -0800955 case StatsLog.WIFI_BYTES_TRANSFER: {
David Chen661f7912018-01-22 17:46:24 -0800956 pullWifiBytesTransfer(tagId, ret);
957 break;
David Chenc8a43242017-10-17 16:23:28 -0700958 }
Chenjie Yu31d14d72017-12-12 17:54:33 -0800959 case StatsLog.MOBILE_BYTES_TRANSFER: {
David Chen661f7912018-01-22 17:46:24 -0800960 pullMobileBytesTransfer(tagId, ret);
961 break;
David Chenc8a43242017-10-17 16:23:28 -0700962 }
Chenjie Yu31d14d72017-12-12 17:54:33 -0800963 case StatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG: {
David Chen661f7912018-01-22 17:46:24 -0800964 pullWifiBytesTransferByFgBg(tagId, ret);
965 break;
David Chenc8a43242017-10-17 16:23:28 -0700966 }
Chenjie Yu31d14d72017-12-12 17:54:33 -0800967 case StatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG: {
David Chen661f7912018-01-22 17:46:24 -0800968 pullMobileBytesTransferByFgBg(tagId, ret);
969 break;
Chenjie Yu9d7720b2018-01-24 10:34:48 -0800970 }
971 case StatsLog.BLUETOOTH_BYTES_TRANSFER: {
David Chen661f7912018-01-22 17:46:24 -0800972 pullBluetoothBytesTransfer(tagId, ret);
973 break;
David Chenc8a43242017-10-17 16:23:28 -0700974 }
Chenjie Yu31d14d72017-12-12 17:54:33 -0800975 case StatsLog.KERNEL_WAKELOCK: {
David Chen661f7912018-01-22 17:46:24 -0800976 pullKernelWakelock(tagId, ret);
977 break;
David Chen1481fe12017-10-16 13:16:34 -0700978 }
Chenjie Yu31d14d72017-12-12 17:54:33 -0800979 case StatsLog.CPU_TIME_PER_FREQ: {
David Chen661f7912018-01-22 17:46:24 -0800980 pullCpuTimePerFreq(tagId, ret);
981 break;
Chenjie Yu7f8def92017-11-03 09:33:15 -0700982 }
Chenjie Yuec676612018-03-07 09:19:17 -0800983 case StatsLog.CPU_TIME_PER_UID: {
984 pullKernelUidCpuTime(tagId, ret);
985 break;
986 }
987 case StatsLog.CPU_TIME_PER_UID_FREQ: {
988 pullKernelUidCpuFreqTime(tagId, ret);
989 break;
990 }
991 case StatsLog.CPU_CLUSTER_TIME: {
992 pullKernelUidCpuClusterTime(tagId, ret);
993 break;
994 }
995 case StatsLog.CPU_ACTIVE_TIME: {
996 pullKernelUidCpuActiveTime(tagId, ret);
997 break;
998 }
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800999 case StatsLog.WIFI_ACTIVITY_INFO: {
1000 pullWifiActivityInfo(tagId, ret);
David Chen661f7912018-01-22 17:46:24 -08001001 break;
Chenjie Yu05013b32017-11-21 10:21:41 -08001002 }
Chenjie Yu31d14d72017-12-12 17:54:33 -08001003 case StatsLog.MODEM_ACTIVITY_INFO: {
David Chen661f7912018-01-22 17:46:24 -08001004 pullModemActivityInfo(tagId, ret);
1005 break;
Chenjie Yu05013b32017-11-21 10:21:41 -08001006 }
Chenjie Yu9d7720b2018-01-24 10:34:48 -08001007 case StatsLog.BLUETOOTH_ACTIVITY_INFO: {
David Chen661f7912018-01-22 17:46:24 -08001008 pullBluetoothActivityInfo(tagId, ret);
1009 break;
Chenjie Yu937d7422018-01-10 16:37:53 -08001010 }
1011 case StatsLog.SYSTEM_UPTIME: {
David Chen661f7912018-01-22 17:46:24 -08001012 pullSystemUpTime(tagId, ret);
1013 break;
Chenjie Yu9d7720b2018-01-24 10:34:48 -08001014 }
1015 case StatsLog.SYSTEM_ELAPSED_REALTIME: {
David Chen661f7912018-01-22 17:46:24 -08001016 pullSystemElapsedRealtime(tagId, ret);
1017 break;
Chenjie Yu9d7720b2018-01-24 10:34:48 -08001018 }
Tej Singh6188aa32018-08-29 00:21:07 +00001019 case StatsLog.DISK_SPACE: {
1020 pullDiskSpace(tagId, ret);
1021 break;
1022 }
Rajeev Kumar22d92b72018-02-07 18:38:36 -08001023 case StatsLog.PROCESS_MEMORY_STATE: {
1024 pullProcessMemoryState(tagId, ret);
1025 break;
1026 }
Olivier Gaillard00bfb1b2018-07-10 11:25:09 +01001027 case StatsLog.BINDER_CALLS: {
1028 pullBinderCallsStats(tagId, ret);
1029 break;
1030 }
Olivier Gaillard6f52d152018-07-25 12:13:12 +01001031 case StatsLog.BINDER_CALLS_EXCEPTIONS: {
1032 pullBinderCallsStatsExceptions(tagId, ret);
1033 break;
1034 }
Bookatzc68a9d22017-09-27 14:09:55 -07001035 default:
Chenjie Yu5305e1d2017-10-31 13:49:36 -07001036 Slog.w(TAG, "No such tagId data as " + tagId);
Bookatzc68a9d22017-09-27 14:09:55 -07001037 return null;
1038 }
Chenjie Yu9d7720b2018-01-24 10:34:48 -08001039 return ret.toArray(new StatsLogEventWrapper[ret.size()]);
Bookatzc68a9d22017-09-27 14:09:55 -07001040 }
1041
1042 @Override // Binder call
Bookatzb487b552017-09-18 11:26:01 -07001043 public void statsdReady() {
1044 enforceCallingPermission();
1045 if (DEBUG) Slog.d(TAG, "learned that statsdReady");
1046 sayHiToStatsd(); // tell statsd that we're ready too and link to it
Bookatz81784082018-02-09 14:26:42 -08001047 mContext.sendBroadcastAsUser(
1048 new Intent(StatsManager.ACTION_STATSD_STARTED)
1049 .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND),
Bookatz0eb58ae392018-01-25 15:49:26 -08001050 UserHandle.SYSTEM,
Bookatz5c800e32018-01-24 14:59:52 -08001051 android.Manifest.permission.DUMP);
Bookatzb487b552017-09-18 11:26:01 -07001052 }
1053
David Chenc136f452017-11-27 11:52:26 -08001054 @Override
1055 public void triggerUidSnapshot() {
David Chen661f7912018-01-22 17:46:24 -08001056 enforceCallingPermission();
1057 synchronized (sStatsdLock) {
David Chen35045cb2018-03-23 22:21:47 -07001058 final long token = Binder.clearCallingIdentity();
David Chen661f7912018-01-22 17:46:24 -08001059 try {
1060 informAllUidsLocked(mContext);
1061 } catch (RemoteException e) {
1062 Slog.e(TAG, "Failed to trigger uid snapshot.", e);
David Chen35045cb2018-03-23 22:21:47 -07001063 } finally {
1064 restoreCallingIdentity(token);
David Chen661f7912018-01-22 17:46:24 -08001065 }
David Chenc136f452017-11-27 11:52:26 -08001066 }
David Chenc136f452017-11-27 11:52:26 -08001067 }
1068
Bookatz94726412017-08-31 09:26:15 -07001069 private void enforceCallingPermission() {
1070 if (Binder.getCallingPid() == Process.myPid()) {
1071 return;
1072 }
1073 mContext.enforceCallingPermission(android.Manifest.permission.STATSCOMPANION, null);
1074 }
1075
Bookatzb487b552017-09-18 11:26:01 -07001076 // Lifecycle and related code
1077
David Chen1481fe12017-10-16 13:16:34 -07001078 /**
1079 * Fetches the statsd IBinder service
1080 */
Bookatzb487b552017-09-18 11:26:01 -07001081 private static IStatsManager fetchStatsdService() {
1082 return IStatsManager.Stub.asInterface(ServiceManager.getService("stats"));
1083 }
1084
1085 public static final class Lifecycle extends SystemService {
1086 private StatsCompanionService mStatsCompanionService;
1087
1088 public Lifecycle(Context context) {
1089 super(context);
1090 }
1091
1092 @Override
1093 public void onStart() {
1094 mStatsCompanionService = new StatsCompanionService(getContext());
1095 try {
1096 publishBinderService(Context.STATS_COMPANION_SERVICE, mStatsCompanionService);
1097 if (DEBUG) Slog.d(TAG, "Published " + Context.STATS_COMPANION_SERVICE);
1098 } catch (Exception e) {
1099 Slog.e(TAG, "Failed to publishBinderService", e);
1100 }
1101 }
1102
1103 @Override
1104 public void onBootPhase(int phase) {
1105 super.onBootPhase(phase);
1106 if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
1107 mStatsCompanionService.systemReady();
1108 }
1109 }
1110 }
1111
David Chen1481fe12017-10-16 13:16:34 -07001112 /**
1113 * Now that the android system is ready, StatsCompanion is ready too, so inform statsd.
1114 */
Bookatzb487b552017-09-18 11:26:01 -07001115 private void systemReady() {
1116 if (DEBUG) Slog.d(TAG, "Learned that systemReady");
1117 sayHiToStatsd();
1118 }
1119
David Chen1481fe12017-10-16 13:16:34 -07001120 /**
1121 * Tells statsd that statscompanion is ready. If the binder call returns, link to statsd.
1122 */
Bookatzb487b552017-09-18 11:26:01 -07001123 private void sayHiToStatsd() {
1124 synchronized (sStatsdLock) {
1125 if (sStatsd != null) {
1126 Slog.e(TAG, "Trying to fetch statsd, but it was already fetched",
1127 new IllegalStateException("sStatsd is not null when being fetched"));
1128 return;
1129 }
1130 sStatsd = fetchStatsdService();
1131 if (sStatsd == null) {
Bookatz111ed732018-02-16 15:54:05 -08001132 Slog.i(TAG, "Could not yet find statsd to tell it that StatsCompanion is alive.");
Bookatzb487b552017-09-18 11:26:01 -07001133 return;
1134 }
1135 if (DEBUG) Slog.d(TAG, "Saying hi to statsd");
1136 try {
1137 sStatsd.statsCompanionReady();
1138 // If the statsCompanionReady two-way binder call returns, link to statsd.
1139 try {
1140 sStatsd.asBinder().linkToDeath(new StatsdDeathRecipient(), 0);
1141 } catch (RemoteException e) {
1142 Slog.e(TAG, "linkToDeath(StatsdDeathRecipient) failed", e);
yroe26c97b2018-03-27 10:30:11 -07001143 forgetEverythingLocked();
Bookatzb487b552017-09-18 11:26:01 -07001144 }
yro947fbce2017-11-15 22:50:23 -08001145 // Setup broadcast receiver for updates.
David Chende701692017-10-05 13:16:02 -07001146 IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REPLACED);
1147 filter.addAction(Intent.ACTION_PACKAGE_ADDED);
1148 filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
1149 filter.addDataScheme("package");
1150 mContext.registerReceiverAsUser(mAppUpdateReceiver, UserHandle.ALL, filter, null,
David Chen1481fe12017-10-16 13:16:34 -07001151 null);
David Chen47e8f4d2017-10-11 15:34:13 -07001152
1153 // Setup receiver for user initialize (which happens once for a new user) and
1154 // if a user is removed.
1155 filter = new IntentFilter(Intent.ACTION_USER_INITIALIZE);
1156 filter.addAction(Intent.ACTION_USER_REMOVED);
1157 mContext.registerReceiverAsUser(mUserUpdateReceiver, UserHandle.ALL,
David Chen1481fe12017-10-16 13:16:34 -07001158 filter, null, null);
David Chen47e8f4d2017-10-11 15:34:13 -07001159
yro947fbce2017-11-15 22:50:23 -08001160 // Setup receiver for device reboots or shutdowns.
1161 filter = new IntentFilter(Intent.ACTION_REBOOT);
1162 filter.addAction(Intent.ACTION_SHUTDOWN);
1163 mContext.registerReceiverAsUser(
1164 mShutdownEventReceiver, UserHandle.ALL, filter, null, null);
Yao Chen0f217102018-01-09 10:33:15 -08001165 final long token = Binder.clearCallingIdentity();
1166 try {
1167 // Pull the latest state of UID->app name, version mapping when statsd starts.
1168 informAllUidsLocked(mContext);
1169 } finally {
1170 restoreCallingIdentity(token);
1171 }
Bookatz111ed732018-02-16 15:54:05 -08001172 Slog.i(TAG, "Told statsd that StatsCompanionService is alive.");
Bookatzb487b552017-09-18 11:26:01 -07001173 } catch (RemoteException e) {
1174 Slog.e(TAG, "Failed to inform statsd that statscompanion is ready", e);
yroe26c97b2018-03-27 10:30:11 -07001175 forgetEverythingLocked();
Bookatzb487b552017-09-18 11:26:01 -07001176 }
1177 }
1178 }
1179
1180 private class StatsdDeathRecipient implements IBinder.DeathRecipient {
1181 @Override
1182 public void binderDied() {
1183 Slog.i(TAG, "Statsd is dead - erase all my knowledge.");
yroe26c97b2018-03-27 10:30:11 -07001184 synchronized (sStatsdLock) {
1185 long now = SystemClock.elapsedRealtime();
1186 for (Long timeMillis : mDeathTimeMillis) {
1187 long ageMillis = now - timeMillis;
1188 if (ageMillis > MILLIS_IN_A_DAY) {
1189 mDeathTimeMillis.remove(timeMillis);
1190 }
1191 }
1192 for (Long timeMillis : mDeletedFiles.keySet()) {
1193 long ageMillis = now - timeMillis;
1194 if (ageMillis > MILLIS_IN_A_DAY * 7) {
1195 mDeletedFiles.remove(timeMillis);
1196 }
1197 }
1198 mDeathTimeMillis.add(now);
1199 if (mDeathTimeMillis.size() >= DEATH_THRESHOLD) {
1200 mDeathTimeMillis.clear();
1201 File[] configs = FileUtils.listFilesOrEmpty(new File(CONFIG_DIR));
1202 if (configs.length > 0) {
1203 String fileName = configs[0].getName();
1204 if (configs[0].delete()) {
1205 mDeletedFiles.put(now, fileName);
1206 }
1207 }
1208 }
1209 forgetEverythingLocked();
1210 }
Bookatzb487b552017-09-18 11:26:01 -07001211 }
1212 }
1213
Andreas Gampe29520212018-07-20 12:55:37 -07001214 @GuardedBy("StatsCompanionService.sStatsdLock")
yroe26c97b2018-03-27 10:30:11 -07001215 private void forgetEverythingLocked() {
1216 sStatsd = null;
1217 mContext.unregisterReceiver(mAppUpdateReceiver);
1218 mContext.unregisterReceiver(mUserUpdateReceiver);
1219 mContext.unregisterReceiver(mShutdownEventReceiver);
1220 cancelAnomalyAlarm();
1221 cancelPullingAlarm();
1222 }
1223
1224 @Override
1225 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
1226 if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
1227
Bookatzb487b552017-09-18 11:26:01 -07001228 synchronized (sStatsdLock) {
yroe26c97b2018-03-27 10:30:11 -07001229 writer.println("Number of configuration files deleted: " + mDeletedFiles.size());
1230 if (mDeletedFiles.size() > 0) {
1231 writer.println(" timestamp, deleted file name");
1232 }
1233 long lastBootMillis =
1234 SystemClock.currentThreadTimeMillis() - SystemClock.elapsedRealtime();
1235 for (Long elapsedMillis : mDeletedFiles.keySet()) {
1236 long deletionMillis = lastBootMillis + elapsedMillis;
1237 writer.println(" " + deletionMillis + ", " + mDeletedFiles.get(elapsedMillis));
1238 }
Bookatzb487b552017-09-18 11:26:01 -07001239 }
1240 }
1241
Bookatz94726412017-08-31 09:26:15 -07001242}