Loading core/java/android/app/ActivityManagerInternal.java +5 −0 Original line number Diff line number Diff line Loading @@ -348,4 +348,9 @@ public abstract class ActivityManagerInternal { * Returns is the caller has the same uid as the Recents component */ public abstract boolean isCallerRecents(int callingUid); /** * Whether an UID is active or idle. */ public abstract boolean isUidActive(int uid); } services/core/java/com/android/server/AlarmManagerService.java +22 −15 Original line number Diff line number Diff line Loading @@ -100,7 +100,8 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.LocalLog; import com.android.server.ForceAppStandbyTracker.Listener; import com.android.internal.util.Preconditions; import com.android.server.AppStateTracker.Listener; /** * Alarm manager implementaion. Loading Loading @@ -252,7 +253,7 @@ class AlarmManagerService extends SystemService { private final SparseArray<AlarmManager.AlarmClockInfo> mHandlerSparseAlarmClockArray = new SparseArray<>(); private final ForceAppStandbyTracker mForceAppStandbyTracker; private AppStateTracker mAppStateTracker; private boolean mAppStandbyParole; private ArrayMap<Pair<String, Integer>, Long> mLastAlarmDeliveredForPackage = new ArrayMap<>(); Loading Loading @@ -710,9 +711,6 @@ class AlarmManagerService extends SystemService { super(context); mConstants = new Constants(mHandler); mForceAppStandbyTracker = ForceAppStandbyTracker.getInstance(context); mForceAppStandbyTracker.addListener(mForceAppStandbyListener); publishLocalService(AlarmManagerInternal.class, new LocalService()); } Loading Loading @@ -1332,13 +1330,15 @@ class AlarmManagerService extends SystemService { @Override public void onBootPhase(int phase) { if (phase == PHASE_SYSTEM_SERVICES_READY) { mForceAppStandbyTracker.start(); mConstants.start(getContext().getContentResolver()); mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE); mLocalDeviceIdleController = LocalServices.getService(DeviceIdleController.LocalService.class); mUsageStatsManagerInternal = LocalServices.getService(UsageStatsManagerInternal.class); mUsageStatsManagerInternal.addAppIdleStateChangeListener(new AppStandbyTracker()); mAppStateTracker = LocalServices.getService(AppStateTracker.class); mAppStateTracker.addListener(mForceAppStandbyListener); } } Loading Loading @@ -1727,7 +1727,8 @@ class AlarmManagerService extends SystemService { // timing restrictions. } else if (workSource == null && (callingUid < Process.FIRST_APPLICATION_UID || UserHandle.isSameApp(callingUid, mSystemUiUid) || mForceAppStandbyTracker.isUidPowerSaveWhitelisted(callingUid))) { || ((mAppStateTracker != null) && mAppStateTracker.isUidPowerSaveWhitelisted(callingUid)))) { flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED; flags &= ~AlarmManager.FLAG_ALLOW_WHILE_IDLE; } Loading Loading @@ -1810,8 +1811,10 @@ class AlarmManagerService extends SystemService { mConstants.dump(pw); pw.println(); mForceAppStandbyTracker.dump(pw, " "); if (mAppStateTracker != null) { mAppStateTracker.dump(pw, " "); pw.println(); } pw.println(" App Standby Parole: " + mAppStandbyParole); pw.println(); Loading Loading @@ -2164,8 +2167,10 @@ class AlarmManagerService extends SystemService { mConstants.dumpProto(proto, AlarmManagerServiceProto.SETTINGS); mForceAppStandbyTracker.dumpProto(proto, if (mAppStateTracker != null) { mAppStateTracker.dumpProto(proto, AlarmManagerServiceProto.FORCE_APP_STANDBY_TRACKER); } proto.write(AlarmManagerServiceProto.IS_INTERACTIVE, mInteractive); if (!mInteractive) { Loading Loading @@ -2952,8 +2957,8 @@ class AlarmManagerService extends SystemService { } final String sourcePackage = alarm.sourcePackage; final int sourceUid = alarm.creatorUid; return mForceAppStandbyTracker.areAlarmsRestricted(sourceUid, sourcePackage, allowWhileIdle); return (mAppStateTracker != null) && mAppStateTracker.areAlarmsRestricted(sourceUid, sourcePackage, allowWhileIdle); } private native long init(); Loading @@ -2965,7 +2970,8 @@ class AlarmManagerService extends SystemService { private long getWhileIdleMinIntervalLocked(int uid) { final boolean dozing = mPendingIdleUntil != null; final boolean ebs = mForceAppStandbyTracker.isForceAllAppsStandbyEnabled(); final boolean ebs = (mAppStateTracker != null) && mAppStateTracker.isForceAllAppsStandbyEnabled(); if (!dozing && !ebs) { return mConstants.ALLOW_WHILE_IDLE_SHORT_TIME; } Loading Loading @@ -4156,7 +4162,8 @@ class AlarmManagerService extends SystemService { if (allowWhileIdle) { // Record the last time this uid handled an ALLOW_WHILE_IDLE alarm. mLastAllowWhileIdleDispatch.put(alarm.creatorUid, nowELAPSED); if (mForceAppStandbyTracker.isUidInForeground(alarm.creatorUid)) { if ((mAppStateTracker == null) || mAppStateTracker.isUidInForeground(alarm.creatorUid)) { mUseAllowWhileIdleShortTime.put(alarm.creatorUid, true); } else { mUseAllowWhileIdleShortTime.put(alarm.creatorUid, false); Loading services/core/java/com/android/server/ForceAppStandbyTracker.java→services/core/java/com/android/server/AppStateTracker.java +47 −33 Original line number Diff line number Diff line Loading @@ -54,7 +54,6 @@ import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsService; import com.android.internal.util.ArrayUtils; import com.android.internal.util.Preconditions; import com.android.server.DeviceIdleController.LocalService; import com.android.server.ForceAppStandbyTrackerProto.ExemptedPackage; import com.android.server.ForceAppStandbyTrackerProto.RunAnyInBackgroundRestrictedPackages; Loading @@ -73,14 +72,14 @@ import java.util.List; * TODO: Make it a LocalService. * * Test: atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/ForceAppStandbyTrackerTest.java atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java */ public class ForceAppStandbyTracker { public class AppStateTracker { private static final String TAG = "ForceAppStandbyTracker"; private static final boolean DEBUG = true; @GuardedBy("ForceAppStandbyTracker.class") private static ForceAppStandbyTracker sInstance; @GuardedBy("AppStateTracker.class") private static AppStateTracker sInstance; private final Object mLock = new Object(); private final Context mContext; Loading @@ -89,6 +88,7 @@ public class ForceAppStandbyTracker { static final int TARGET_OP = AppOpsManager.OP_RUN_ANY_IN_BACKGROUND; IActivityManager mIActivityManager; ActivityManagerInternal mActivityManagerInternal; AppOpsManager mAppOpsManager; IAppOpsService mAppOpsService; PowerManagerInternal mPowerManagerInternal; Loading Loading @@ -172,6 +172,9 @@ public class ForceAppStandbyTracker { int EXEMPT_CHANGED = 6; int FORCE_ALL_CHANGED = 7; int FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 8; int IS_UID_ACTIVE_CACHED = 9; int IS_UID_ACTIVE_RAW = 10; } private final StatLogger mStatLogger = new StatLogger(new String[] { Loading @@ -184,6 +187,9 @@ public class ForceAppStandbyTracker { "EXEMPT_CHANGED", "FORCE_ALL_CHANGED", "FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED", "IS_UID_ACTIVE_CACHED", "IS_UID_ACTIVE_RAW", }); @VisibleForTesting Loading Loading @@ -249,7 +255,7 @@ public class ForceAppStandbyTracker { /** * This is called when the OP_RUN_ANY_IN_BACKGROUND appops changed for a package. */ private void onRunAnyAppOpsChanged(ForceAppStandbyTracker sender, private void onRunAnyAppOpsChanged(AppStateTracker sender, int uid, @NonNull String packageName) { updateJobsForUidPackage(uid, packageName); Loading @@ -264,14 +270,14 @@ public class ForceAppStandbyTracker { /** * This is called when the foreground state changed for a UID. */ private void onUidForegroundStateChanged(ForceAppStandbyTracker sender, int uid) { private void onUidForegroundStateChanged(AppStateTracker sender, int uid) { onUidForeground(uid, sender.isUidInForeground(uid)); } /** * This is called when the active/idle state changed for a UID. */ private void onUidActiveStateChanged(ForceAppStandbyTracker sender, int uid) { private void onUidActiveStateChanged(AppStateTracker sender, int uid) { updateJobsForUid(uid); if (sender.isUidActive(uid)) { Loading @@ -282,7 +288,7 @@ public class ForceAppStandbyTracker { /** * This is called when an app-id(s) is removed from the power save whitelist. */ private void onPowerSaveUnwhitelisted(ForceAppStandbyTracker sender) { private void onPowerSaveUnwhitelisted(AppStateTracker sender) { updateAllJobs(); unblockAllUnrestrictedAlarms(); } Loading @@ -291,14 +297,14 @@ public class ForceAppStandbyTracker { * This is called when the power save whitelist changes, excluding the * {@link #onPowerSaveUnwhitelisted} case. */ private void onPowerSaveWhitelistedChanged(ForceAppStandbyTracker sender) { private void onPowerSaveWhitelistedChanged(AppStateTracker sender) { updateAllJobs(); } /** * This is called when the temp whitelist changes. */ private void onTempPowerSaveWhitelistChanged(ForceAppStandbyTracker sender) { private void onTempPowerSaveWhitelistChanged(AppStateTracker sender) { // TODO This case happens rather frequently; consider optimizing and update jobs // only for affected app-ids. Loading @@ -311,7 +317,7 @@ public class ForceAppStandbyTracker { /** * This is called when the EXEMPT bucket is updated. */ private void onExemptChanged(ForceAppStandbyTracker sender) { private void onExemptChanged(AppStateTracker sender) { // This doesn't happen very often, so just re-evaluate all jobs / alarms. updateAllJobs(); unblockAllUnrestrictedAlarms(); Loading @@ -320,7 +326,7 @@ public class ForceAppStandbyTracker { /** * This is called when the global "force all apps standby" flag changes. */ private void onForceAllAppsStandbyChanged(ForceAppStandbyTracker sender) { private void onForceAllAppsStandbyChanged(AppStateTracker sender) { updateAllJobs(); if (!sender.isForceAllAppsStandbyEnabled()) { Loading Loading @@ -377,30 +383,15 @@ public class ForceAppStandbyTracker { } } @VisibleForTesting ForceAppStandbyTracker(Context context, Looper looper) { public AppStateTracker(Context context, Looper looper) { mContext = context; mHandler = new MyHandler(looper); } private ForceAppStandbyTracker(Context context) { this(context, FgThread.get().getLooper()); } /** * Get the singleton instance. */ public static synchronized ForceAppStandbyTracker getInstance(Context context) { if (sInstance == null) { sInstance = new ForceAppStandbyTracker(context); } return sInstance; } /** * Call it when the system is ready. */ public void start() { public void onSystemServicesReady() { synchronized (mLock) { if (mStarted) { return; Loading @@ -408,6 +399,7 @@ public class ForceAppStandbyTracker { mStarted = true; mIActivityManager = Preconditions.checkNotNull(injectIActivityManager()); mActivityManagerInternal = Preconditions.checkNotNull(injectActivityManagerInternal()); mAppOpsManager = Preconditions.checkNotNull(injectAppOpsManager()); mAppOpsService = Preconditions.checkNotNull(injectIAppOpsService()); mPowerManagerInternal = Preconditions.checkNotNull(injectPowerManagerInternal()); Loading Loading @@ -474,6 +466,11 @@ public class ForceAppStandbyTracker { return ActivityManager.getService(); } @VisibleForTesting ActivityManagerInternal injectActivityManagerInternal() { return LocalServices.getService(ActivityManagerInternal.class); } @VisibleForTesting PowerManagerInternal injectPowerManagerInternal() { return LocalServices.getService(PowerManagerInternal.class); Loading Loading @@ -804,7 +801,7 @@ public class ForceAppStandbyTracker { return; } } final ForceAppStandbyTracker sender = ForceAppStandbyTracker.this; final AppStateTracker sender = AppStateTracker.this; long start = mStatLogger.getTime(); switch (msg.what) { Loading Loading @@ -1094,11 +1091,11 @@ public class ForceAppStandbyTracker { } /** * @return whether a UID is in active or not. * @return whether a UID is in active or not *based on cached information.* * * Note this information is based on the UID proc state callback, meaning it's updated * asynchronously and may subtly be stale. If the fresh data is needed, use * {@link ActivityManagerInternal#getUidProcessState} instead. * {@link #isUidActiveSynced} instead. */ public boolean isUidActive(int uid) { if (UserHandle.isCore(uid)) { Loading @@ -1109,6 +1106,23 @@ public class ForceAppStandbyTracker { } } /** * @return whether a UID is in active or not *right now.* * * This gives the fresh information, but may access the activity manager so is slower. */ public boolean isUidActiveSynced(int uid) { if (isUidActive(uid)) { // Use the cached one first. return true; } final long start = mStatLogger.getTime(); final boolean ret = mActivityManagerInternal.isUidActive(uid); mStatLogger.logDurationStat(Stats.IS_UID_ACTIVE_RAW, start); return ret; } /** * @return whether a UID is in the foreground or not. * Loading services/core/java/com/android/server/DeviceIdleController.java +7 −1 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ import com.android.internal.os.AtomicFile; import com.android.internal.os.BackgroundThread; import com.android.internal.util.DumpUtils; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.Preconditions; import com.android.internal.util.XmlUtils; import com.android.server.am.BatteryStatsService; import com.android.server.net.NetworkPolicyManagerInternal; Loading Loading @@ -128,6 +129,7 @@ public class DeviceIdleController extends SystemService private Intent mIdleIntent; private Intent mLightIdleIntent; private AnyMotionDetector mAnyMotionDetector; private final AppStateTracker mAppStateTracker; private boolean mLightEnabled; private boolean mDeepEnabled; private boolean mForceIdle; Loading Loading @@ -1371,6 +1373,8 @@ public class DeviceIdleController extends SystemService super(context); mConfigFile = new AtomicFile(new File(getSystemDir(), "deviceidle.xml")); mHandler = new MyHandler(BackgroundThread.getHandler().getLooper()); mAppStateTracker = new AppStateTracker(context, FgThread.get().getLooper()); LocalServices.addService(AppStateTracker.class, mAppStateTracker); } boolean isAppOnWhitelistInternal(int appid) { Loading Loading @@ -1501,6 +1505,8 @@ public class DeviceIdleController extends SystemService (PowerManager) getContext().getSystemService(Context.POWER_SERVICE), mHandler, mSensorManager, this, angleThreshold); mAppStateTracker.onSystemServicesReady(); mIdleIntent = new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); Loading Loading @@ -2615,7 +2621,7 @@ public class DeviceIdleController extends SystemService } private void passWhiteListToForceAppStandbyTrackerLocked() { ForceAppStandbyTracker.getInstance(getContext()).setPowerSaveWhitelistAppIds( mAppStateTracker.setPowerSaveWhitelistAppIds( mPowerSaveWhitelistExceptIdleAppIdArray, mTempWhitelistAppIdArray); } Loading services/core/java/com/android/server/StatLogger.java +9 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server; import android.os.SystemClock; import android.util.Slog; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; Loading @@ -33,6 +34,8 @@ import java.io.PrintWriter; * @hide */ public class StatLogger { private static final String TAG = "StatLogger"; private final Object mLock = new Object(); private final int SIZE; Loading Loading @@ -66,8 +69,12 @@ public class StatLogger { */ public void logDurationStat(int eventId, long start) { synchronized (mLock) { if (eventId >= 0 && eventId < SIZE) { mCountStats[eventId]++; mDurationStats[eventId] += (getTime() - start); } else { Slog.wtf(TAG, "Invalid event ID: " + eventId); } } } Loading Loading
core/java/android/app/ActivityManagerInternal.java +5 −0 Original line number Diff line number Diff line Loading @@ -348,4 +348,9 @@ public abstract class ActivityManagerInternal { * Returns is the caller has the same uid as the Recents component */ public abstract boolean isCallerRecents(int callingUid); /** * Whether an UID is active or idle. */ public abstract boolean isUidActive(int uid); }
services/core/java/com/android/server/AlarmManagerService.java +22 −15 Original line number Diff line number Diff line Loading @@ -100,7 +100,8 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.LocalLog; import com.android.server.ForceAppStandbyTracker.Listener; import com.android.internal.util.Preconditions; import com.android.server.AppStateTracker.Listener; /** * Alarm manager implementaion. Loading Loading @@ -252,7 +253,7 @@ class AlarmManagerService extends SystemService { private final SparseArray<AlarmManager.AlarmClockInfo> mHandlerSparseAlarmClockArray = new SparseArray<>(); private final ForceAppStandbyTracker mForceAppStandbyTracker; private AppStateTracker mAppStateTracker; private boolean mAppStandbyParole; private ArrayMap<Pair<String, Integer>, Long> mLastAlarmDeliveredForPackage = new ArrayMap<>(); Loading Loading @@ -710,9 +711,6 @@ class AlarmManagerService extends SystemService { super(context); mConstants = new Constants(mHandler); mForceAppStandbyTracker = ForceAppStandbyTracker.getInstance(context); mForceAppStandbyTracker.addListener(mForceAppStandbyListener); publishLocalService(AlarmManagerInternal.class, new LocalService()); } Loading Loading @@ -1332,13 +1330,15 @@ class AlarmManagerService extends SystemService { @Override public void onBootPhase(int phase) { if (phase == PHASE_SYSTEM_SERVICES_READY) { mForceAppStandbyTracker.start(); mConstants.start(getContext().getContentResolver()); mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE); mLocalDeviceIdleController = LocalServices.getService(DeviceIdleController.LocalService.class); mUsageStatsManagerInternal = LocalServices.getService(UsageStatsManagerInternal.class); mUsageStatsManagerInternal.addAppIdleStateChangeListener(new AppStandbyTracker()); mAppStateTracker = LocalServices.getService(AppStateTracker.class); mAppStateTracker.addListener(mForceAppStandbyListener); } } Loading Loading @@ -1727,7 +1727,8 @@ class AlarmManagerService extends SystemService { // timing restrictions. } else if (workSource == null && (callingUid < Process.FIRST_APPLICATION_UID || UserHandle.isSameApp(callingUid, mSystemUiUid) || mForceAppStandbyTracker.isUidPowerSaveWhitelisted(callingUid))) { || ((mAppStateTracker != null) && mAppStateTracker.isUidPowerSaveWhitelisted(callingUid)))) { flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED; flags &= ~AlarmManager.FLAG_ALLOW_WHILE_IDLE; } Loading Loading @@ -1810,8 +1811,10 @@ class AlarmManagerService extends SystemService { mConstants.dump(pw); pw.println(); mForceAppStandbyTracker.dump(pw, " "); if (mAppStateTracker != null) { mAppStateTracker.dump(pw, " "); pw.println(); } pw.println(" App Standby Parole: " + mAppStandbyParole); pw.println(); Loading Loading @@ -2164,8 +2167,10 @@ class AlarmManagerService extends SystemService { mConstants.dumpProto(proto, AlarmManagerServiceProto.SETTINGS); mForceAppStandbyTracker.dumpProto(proto, if (mAppStateTracker != null) { mAppStateTracker.dumpProto(proto, AlarmManagerServiceProto.FORCE_APP_STANDBY_TRACKER); } proto.write(AlarmManagerServiceProto.IS_INTERACTIVE, mInteractive); if (!mInteractive) { Loading Loading @@ -2952,8 +2957,8 @@ class AlarmManagerService extends SystemService { } final String sourcePackage = alarm.sourcePackage; final int sourceUid = alarm.creatorUid; return mForceAppStandbyTracker.areAlarmsRestricted(sourceUid, sourcePackage, allowWhileIdle); return (mAppStateTracker != null) && mAppStateTracker.areAlarmsRestricted(sourceUid, sourcePackage, allowWhileIdle); } private native long init(); Loading @@ -2965,7 +2970,8 @@ class AlarmManagerService extends SystemService { private long getWhileIdleMinIntervalLocked(int uid) { final boolean dozing = mPendingIdleUntil != null; final boolean ebs = mForceAppStandbyTracker.isForceAllAppsStandbyEnabled(); final boolean ebs = (mAppStateTracker != null) && mAppStateTracker.isForceAllAppsStandbyEnabled(); if (!dozing && !ebs) { return mConstants.ALLOW_WHILE_IDLE_SHORT_TIME; } Loading Loading @@ -4156,7 +4162,8 @@ class AlarmManagerService extends SystemService { if (allowWhileIdle) { // Record the last time this uid handled an ALLOW_WHILE_IDLE alarm. mLastAllowWhileIdleDispatch.put(alarm.creatorUid, nowELAPSED); if (mForceAppStandbyTracker.isUidInForeground(alarm.creatorUid)) { if ((mAppStateTracker == null) || mAppStateTracker.isUidInForeground(alarm.creatorUid)) { mUseAllowWhileIdleShortTime.put(alarm.creatorUid, true); } else { mUseAllowWhileIdleShortTime.put(alarm.creatorUid, false); Loading
services/core/java/com/android/server/ForceAppStandbyTracker.java→services/core/java/com/android/server/AppStateTracker.java +47 −33 Original line number Diff line number Diff line Loading @@ -54,7 +54,6 @@ import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsService; import com.android.internal.util.ArrayUtils; import com.android.internal.util.Preconditions; import com.android.server.DeviceIdleController.LocalService; import com.android.server.ForceAppStandbyTrackerProto.ExemptedPackage; import com.android.server.ForceAppStandbyTrackerProto.RunAnyInBackgroundRestrictedPackages; Loading @@ -73,14 +72,14 @@ import java.util.List; * TODO: Make it a LocalService. * * Test: atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/ForceAppStandbyTrackerTest.java atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java */ public class ForceAppStandbyTracker { public class AppStateTracker { private static final String TAG = "ForceAppStandbyTracker"; private static final boolean DEBUG = true; @GuardedBy("ForceAppStandbyTracker.class") private static ForceAppStandbyTracker sInstance; @GuardedBy("AppStateTracker.class") private static AppStateTracker sInstance; private final Object mLock = new Object(); private final Context mContext; Loading @@ -89,6 +88,7 @@ public class ForceAppStandbyTracker { static final int TARGET_OP = AppOpsManager.OP_RUN_ANY_IN_BACKGROUND; IActivityManager mIActivityManager; ActivityManagerInternal mActivityManagerInternal; AppOpsManager mAppOpsManager; IAppOpsService mAppOpsService; PowerManagerInternal mPowerManagerInternal; Loading Loading @@ -172,6 +172,9 @@ public class ForceAppStandbyTracker { int EXEMPT_CHANGED = 6; int FORCE_ALL_CHANGED = 7; int FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED = 8; int IS_UID_ACTIVE_CACHED = 9; int IS_UID_ACTIVE_RAW = 10; } private final StatLogger mStatLogger = new StatLogger(new String[] { Loading @@ -184,6 +187,9 @@ public class ForceAppStandbyTracker { "EXEMPT_CHANGED", "FORCE_ALL_CHANGED", "FORCE_APP_STANDBY_FEATURE_FLAG_CHANGED", "IS_UID_ACTIVE_CACHED", "IS_UID_ACTIVE_RAW", }); @VisibleForTesting Loading Loading @@ -249,7 +255,7 @@ public class ForceAppStandbyTracker { /** * This is called when the OP_RUN_ANY_IN_BACKGROUND appops changed for a package. */ private void onRunAnyAppOpsChanged(ForceAppStandbyTracker sender, private void onRunAnyAppOpsChanged(AppStateTracker sender, int uid, @NonNull String packageName) { updateJobsForUidPackage(uid, packageName); Loading @@ -264,14 +270,14 @@ public class ForceAppStandbyTracker { /** * This is called when the foreground state changed for a UID. */ private void onUidForegroundStateChanged(ForceAppStandbyTracker sender, int uid) { private void onUidForegroundStateChanged(AppStateTracker sender, int uid) { onUidForeground(uid, sender.isUidInForeground(uid)); } /** * This is called when the active/idle state changed for a UID. */ private void onUidActiveStateChanged(ForceAppStandbyTracker sender, int uid) { private void onUidActiveStateChanged(AppStateTracker sender, int uid) { updateJobsForUid(uid); if (sender.isUidActive(uid)) { Loading @@ -282,7 +288,7 @@ public class ForceAppStandbyTracker { /** * This is called when an app-id(s) is removed from the power save whitelist. */ private void onPowerSaveUnwhitelisted(ForceAppStandbyTracker sender) { private void onPowerSaveUnwhitelisted(AppStateTracker sender) { updateAllJobs(); unblockAllUnrestrictedAlarms(); } Loading @@ -291,14 +297,14 @@ public class ForceAppStandbyTracker { * This is called when the power save whitelist changes, excluding the * {@link #onPowerSaveUnwhitelisted} case. */ private void onPowerSaveWhitelistedChanged(ForceAppStandbyTracker sender) { private void onPowerSaveWhitelistedChanged(AppStateTracker sender) { updateAllJobs(); } /** * This is called when the temp whitelist changes. */ private void onTempPowerSaveWhitelistChanged(ForceAppStandbyTracker sender) { private void onTempPowerSaveWhitelistChanged(AppStateTracker sender) { // TODO This case happens rather frequently; consider optimizing and update jobs // only for affected app-ids. Loading @@ -311,7 +317,7 @@ public class ForceAppStandbyTracker { /** * This is called when the EXEMPT bucket is updated. */ private void onExemptChanged(ForceAppStandbyTracker sender) { private void onExemptChanged(AppStateTracker sender) { // This doesn't happen very often, so just re-evaluate all jobs / alarms. updateAllJobs(); unblockAllUnrestrictedAlarms(); Loading @@ -320,7 +326,7 @@ public class ForceAppStandbyTracker { /** * This is called when the global "force all apps standby" flag changes. */ private void onForceAllAppsStandbyChanged(ForceAppStandbyTracker sender) { private void onForceAllAppsStandbyChanged(AppStateTracker sender) { updateAllJobs(); if (!sender.isForceAllAppsStandbyEnabled()) { Loading Loading @@ -377,30 +383,15 @@ public class ForceAppStandbyTracker { } } @VisibleForTesting ForceAppStandbyTracker(Context context, Looper looper) { public AppStateTracker(Context context, Looper looper) { mContext = context; mHandler = new MyHandler(looper); } private ForceAppStandbyTracker(Context context) { this(context, FgThread.get().getLooper()); } /** * Get the singleton instance. */ public static synchronized ForceAppStandbyTracker getInstance(Context context) { if (sInstance == null) { sInstance = new ForceAppStandbyTracker(context); } return sInstance; } /** * Call it when the system is ready. */ public void start() { public void onSystemServicesReady() { synchronized (mLock) { if (mStarted) { return; Loading @@ -408,6 +399,7 @@ public class ForceAppStandbyTracker { mStarted = true; mIActivityManager = Preconditions.checkNotNull(injectIActivityManager()); mActivityManagerInternal = Preconditions.checkNotNull(injectActivityManagerInternal()); mAppOpsManager = Preconditions.checkNotNull(injectAppOpsManager()); mAppOpsService = Preconditions.checkNotNull(injectIAppOpsService()); mPowerManagerInternal = Preconditions.checkNotNull(injectPowerManagerInternal()); Loading Loading @@ -474,6 +466,11 @@ public class ForceAppStandbyTracker { return ActivityManager.getService(); } @VisibleForTesting ActivityManagerInternal injectActivityManagerInternal() { return LocalServices.getService(ActivityManagerInternal.class); } @VisibleForTesting PowerManagerInternal injectPowerManagerInternal() { return LocalServices.getService(PowerManagerInternal.class); Loading Loading @@ -804,7 +801,7 @@ public class ForceAppStandbyTracker { return; } } final ForceAppStandbyTracker sender = ForceAppStandbyTracker.this; final AppStateTracker sender = AppStateTracker.this; long start = mStatLogger.getTime(); switch (msg.what) { Loading Loading @@ -1094,11 +1091,11 @@ public class ForceAppStandbyTracker { } /** * @return whether a UID is in active or not. * @return whether a UID is in active or not *based on cached information.* * * Note this information is based on the UID proc state callback, meaning it's updated * asynchronously and may subtly be stale. If the fresh data is needed, use * {@link ActivityManagerInternal#getUidProcessState} instead. * {@link #isUidActiveSynced} instead. */ public boolean isUidActive(int uid) { if (UserHandle.isCore(uid)) { Loading @@ -1109,6 +1106,23 @@ public class ForceAppStandbyTracker { } } /** * @return whether a UID is in active or not *right now.* * * This gives the fresh information, but may access the activity manager so is slower. */ public boolean isUidActiveSynced(int uid) { if (isUidActive(uid)) { // Use the cached one first. return true; } final long start = mStatLogger.getTime(); final boolean ret = mActivityManagerInternal.isUidActive(uid); mStatLogger.logDurationStat(Stats.IS_UID_ACTIVE_RAW, start); return ret; } /** * @return whether a UID is in the foreground or not. * Loading
services/core/java/com/android/server/DeviceIdleController.java +7 −1 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ import com.android.internal.os.AtomicFile; import com.android.internal.os.BackgroundThread; import com.android.internal.util.DumpUtils; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.Preconditions; import com.android.internal.util.XmlUtils; import com.android.server.am.BatteryStatsService; import com.android.server.net.NetworkPolicyManagerInternal; Loading Loading @@ -128,6 +129,7 @@ public class DeviceIdleController extends SystemService private Intent mIdleIntent; private Intent mLightIdleIntent; private AnyMotionDetector mAnyMotionDetector; private final AppStateTracker mAppStateTracker; private boolean mLightEnabled; private boolean mDeepEnabled; private boolean mForceIdle; Loading Loading @@ -1371,6 +1373,8 @@ public class DeviceIdleController extends SystemService super(context); mConfigFile = new AtomicFile(new File(getSystemDir(), "deviceidle.xml")); mHandler = new MyHandler(BackgroundThread.getHandler().getLooper()); mAppStateTracker = new AppStateTracker(context, FgThread.get().getLooper()); LocalServices.addService(AppStateTracker.class, mAppStateTracker); } boolean isAppOnWhitelistInternal(int appid) { Loading Loading @@ -1501,6 +1505,8 @@ public class DeviceIdleController extends SystemService (PowerManager) getContext().getSystemService(Context.POWER_SERVICE), mHandler, mSensorManager, this, angleThreshold); mAppStateTracker.onSystemServicesReady(); mIdleIntent = new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); Loading Loading @@ -2615,7 +2621,7 @@ public class DeviceIdleController extends SystemService } private void passWhiteListToForceAppStandbyTrackerLocked() { ForceAppStandbyTracker.getInstance(getContext()).setPowerSaveWhitelistAppIds( mAppStateTracker.setPowerSaveWhitelistAppIds( mPowerSaveWhitelistExceptIdleAppIdArray, mTempWhitelistAppIdArray); } Loading
services/core/java/com/android/server/StatLogger.java +9 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server; import android.os.SystemClock; import android.util.Slog; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; Loading @@ -33,6 +34,8 @@ import java.io.PrintWriter; * @hide */ public class StatLogger { private static final String TAG = "StatLogger"; private final Object mLock = new Object(); private final int SIZE; Loading Loading @@ -66,8 +69,12 @@ public class StatLogger { */ public void logDurationStat(int eventId, long start) { synchronized (mLock) { if (eventId >= 0 && eventId < SIZE) { mCountStats[eventId]++; mDurationStats[eventId] += (getTime() - start); } else { Slog.wtf(TAG, "Invalid event ID: " + eventId); } } } Loading