summaryrefslogtreecommitdiff
path: root/services/usage/java
diff options
context:
space:
mode:
author Jeff Sharkey <jsharkey@android.com> 2017-01-17 18:31:03 -0700
committer Jeff Sharkey <jsharkey@android.com> 2017-01-17 18:41:03 -0700
commitf3b0ef2f40c01473710f5abfed4d2e911cd92372 (patch)
treeebdc7fbf14cf1caceb55a527e171e9337cf4b74c /services/usage/java
parentc70e581564c4500019b9f898713af96ec452fb08 (diff)
Write bg/fg status updates to kernel for stats.
New procfs file written by the system_server to communicate fg/bg state of UIDs to switch the statistics counter sets used. Test: builds, boots, counter sets updated Bug: 34360629 Change-Id: I3339a93bce6aec65779a4a4aee52f5328896bb29
Diffstat (limited to 'services/usage/java')
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java54
1 files changed, 53 insertions, 1 deletions
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 4bfc3df73568..d243bf23ac93 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -20,6 +20,7 @@ import android.Manifest;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.AppOpsManager;
+import android.app.IUidObserver;
import android.app.admin.DevicePolicyManager;
import android.app.usage.ConfigurationStats;
import android.app.usage.IUsageStatsManager;
@@ -38,9 +39,9 @@ import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ParceledListSlice;
import android.content.pm.UserInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.hardware.display.DisplayManager;
@@ -49,6 +50,7 @@ import android.os.BatteryManager;
import android.os.BatteryStats;
import android.os.Binder;
import android.os.Environment;
+import android.os.FileUtils;
import android.os.Handler;
import android.os.IDeviceIdleController;
import android.os.Looper;
@@ -80,6 +82,7 @@ import com.android.server.SystemService;
import java.io.File;
import java.io.FileDescriptor;
+import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -103,6 +106,8 @@ public class UsageStatsService extends SystemService implements
private static final long FLUSH_INTERVAL = COMPRESS_TIME ? TEN_SECONDS : TWENTY_MINUTES;
private static final long TIME_CHANGE_THRESHOLD_MILLIS = 2 * 1000; // Two seconds.
+ private static final File KERNEL_COUNTER_FILE = new File("/proc/uid_procstat/set");
+
long mAppIdleScreenThresholdMillis;
long mCheckIdleIntervalMillis;
long mAppIdleWallclockThresholdMillis;
@@ -134,6 +139,7 @@ public class UsageStatsService extends SystemService implements
private IBatteryStats mBatteryStats;
private final SparseArray<UserUsageStatsService> mUserState = new SparseArray<>();
+ private final SparseIntArray mUidToKernelCounter = new SparseIntArray();
private File mUsageStatsDir;
long mRealTimeSnapshot;
long mSystemTimeSnapshot;
@@ -235,6 +241,19 @@ public class UsageStatsService extends SystemService implements
postOneTimeCheckIdleStates();
}
+ if (KERNEL_COUNTER_FILE.exists()) {
+ try {
+ ActivityManager.getService().registerUidObserver(mUidObserver,
+ ActivityManager.UID_OBSERVER_PROCSTATE
+ | ActivityManager.UID_OBSERVER_GONE,
+ ActivityManager.PROCESS_STATE_UNKNOWN, null);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ Slog.w(TAG, "Missing procfs interface: " + KERNEL_COUNTER_FILE);
+ }
+
mSystemServicesReady = true;
} else if (phase == PHASE_BOOT_COMPLETED) {
setChargingState(getContext().getSystemService(BatteryManager.class).isCharging());
@@ -311,6 +330,39 @@ public class UsageStatsService extends SystemService implements
}
};
+ private final IUidObserver mUidObserver = new IUidObserver.Stub() {
+ @Override
+ public void onUidStateChanged(int uid, int procState) {
+ final int newCounter = (procState <= ActivityManager.PROCESS_STATE_TOP) ? 0 : 1;
+ synchronized (mUidToKernelCounter) {
+ final int oldCounter = mUidToKernelCounter.get(uid, 0);
+ if (newCounter != oldCounter) {
+ mUidToKernelCounter.put(uid, newCounter);
+ try {
+ FileUtils.stringToFile(KERNEL_COUNTER_FILE, uid + " " + newCounter);
+ } catch (IOException e) {
+ Slog.w(TAG, "Failed to update counter set: " + e);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onUidIdle(int uid, boolean disabled) throws RemoteException {
+ // Ignored
+ }
+
+ @Override
+ public void onUidGone(int uid, boolean disabled) throws RemoteException {
+ onUidStateChanged(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
+ }
+
+ @Override
+ public void onUidActive(int uid) throws RemoteException {
+ // Ignored
+ }
+ };
+
@Override
public void onStatsUpdated() {
mHandler.sendEmptyMessageDelayed(MSG_FLUSH_TO_DISK, FLUSH_INTERVAL);