Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f3b0ef2f authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

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
parent c70e5815
Loading
Loading
Loading
Loading
+53 −1
Original line number Diff line number Diff line
@@ -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);