Loading apex/jobscheduler/framework/java/com/android/server/AppStateTracker.java +14 −8 Original line number Diff line number Diff line Loading @@ -25,19 +25,25 @@ public interface AppStateTracker { String TAG = "AppStateTracker"; /** * Register a {@link ServiceStateListener} to listen for forced-app-standby changes that should * affect services. * Register a {@link BackgroundRestrictedAppListener} to listen for background restricted mode * changes that should affect services etc. */ void addServiceStateListener(@NonNull ServiceStateListener listener); void addBackgroundRestrictedAppListener(@NonNull BackgroundRestrictedAppListener listener); /** * A listener to listen to forced-app-standby changes that should affect services. * @return {code true} if the given UID/package has been in background restricted mode, * it does NOT include the case where the "force app background restricted" is enabled. */ interface ServiceStateListener { boolean isAppBackgroundRestricted(int uid, @NonNull String packageName); /** * A listener to listen to background restricted mode changes that should affect services etc. */ interface BackgroundRestrictedAppListener { /** * Called when an app goes into forced app standby and its foreground * services need to be removed from that state. * Called when an app goes in/out of background restricted mode. */ void stopForegroundServicesForUidPackage(int uid, String packageName); void updateBackgroundRestrictedForUidPackage(int uid, String packageName, boolean restricted); } } apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java +62 −10 Original line number Diff line number Diff line Loading @@ -60,8 +60,10 @@ import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener; import java.io.PrintWriter; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; /** * Class to keep track of the information related to "force app standby", which includes: Loading Loading @@ -160,16 +162,34 @@ public class AppStateTrackerImpl implements AppStateTracker { @GuardedBy("mLock") boolean mForcedAppStandbyEnabled; /** * A lock-free set of (uid, packageName) pairs in background restricted mode. * * <p> * It's bascially shadowing the {@link #mRunAnyRestrictedPackages} together with * the {@link #mForcedAppStandbyEnabled} - mutations on them would result in copy-on-write. * </p> */ volatile Set<Pair<Integer, String>> mBackgroundRestrictedUidPackages = Collections.emptySet(); @Override public void addServiceStateListener(@NonNull ServiceStateListener listener) { public void addBackgroundRestrictedAppListener( @NonNull BackgroundRestrictedAppListener listener) { addListener(new Listener() { @Override public void stopForegroundServicesForUidPackage(int uid, String packageName) { listener.stopForegroundServicesForUidPackage(uid, packageName); public void updateBackgroundRestrictedForUidPackage(int uid, String packageName, boolean restricted) { listener.updateBackgroundRestrictedForUidPackage(uid, packageName, restricted); } }); } @Override public boolean isAppBackgroundRestricted(int uid, @NonNull String packageName) { final Set<Pair<Integer, String>> bgRestrictedUidPkgs = mBackgroundRestrictedUidPackages; return bgRestrictedUidPkgs.contains(Pair.create(uid, packageName)); } interface Stats { int UID_FG_STATE_CHANGED = 0; int UID_ACTIVE_STATE_CHANGED = 1; Loading Loading @@ -233,6 +253,7 @@ public class AppStateTrackerImpl implements AppStateTracker { return; } mForcedAppStandbyEnabled = enabled; updateBackgroundRestrictedUidPackagesLocked(); if (DEBUG) { Slog.d(TAG, "Forced app standby feature flag changed: " + mForcedAppStandbyEnabled); Loading Loading @@ -277,7 +298,11 @@ public class AppStateTrackerImpl implements AppStateTracker { if (!sender.isRunAnyInBackgroundAppOpsAllowed(uid, packageName)) { Slog.v(TAG, "Package " + packageName + "/" + uid + " toggled into fg service restriction"); stopForegroundServicesForUidPackage(uid, packageName); updateBackgroundRestrictedForUidPackage(uid, packageName, true); } else { Slog.v(TAG, "Package " + packageName + "/" + uid + " toggled out of fg service restriction"); updateBackgroundRestrictedForUidPackage(uid, packageName, false); } } Loading Loading @@ -366,10 +391,10 @@ public class AppStateTrackerImpl implements AppStateTracker { } /** * Called when an app goes into forced app standby and its foreground * services need to be removed from that state. * Called when an app goes in/out of background restricted mode. */ public void stopForegroundServicesForUidPackage(int uid, String packageName) { public void updateBackgroundRestrictedForUidPackage(int uid, String packageName, boolean restricted) { } /** Loading Loading @@ -438,10 +463,13 @@ public class AppStateTrackerImpl implements AppStateTracker { final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); // No need to notify for state change as all the alarms and jobs should be // removed too. synchronized (mLock) { mExemptedBucketPackages.remove(userId, pkgName); mRunAnyRestrictedPackages.remove(Pair.create(uid, pkgName)); updateBackgroundRestrictedUidPackagesLocked(); mActiveUids.delete(uid); } } break; } } Loading Loading @@ -580,6 +608,28 @@ public class AppStateTrackerImpl implements AppStateTracker { } } } updateBackgroundRestrictedUidPackagesLocked(); } /** * Update the {@link #mBackgroundRestrictedUidPackages} upon mutations on * {@link #mRunAnyRestrictedPackages} or {@link #mForcedAppStandbyEnabled}. */ @GuardedBy("mLock") private void updateBackgroundRestrictedUidPackagesLocked() { if (!mForcedAppStandbyEnabled) { mBackgroundRestrictedUidPackages = Collections.emptySet(); return; } if (mForceAllAppsStandby) { mBackgroundRestrictedUidPackages = null; return; } Set<Pair<Integer, String>> fasUidPkgs = new ArraySet<>(); for (int i = 0, size = mRunAnyRestrictedPackages.size(); i < size; i++) { fasUidPkgs.add(mRunAnyRestrictedPackages.valueAt(i)); } mBackgroundRestrictedUidPackages = Collections.unmodifiableSet(fasUidPkgs); } private void updateForceAllAppStandbyState() { Loading Loading @@ -645,6 +695,7 @@ public class AppStateTrackerImpl implements AppStateTracker { } else { mRunAnyRestrictedPackages.removeAt(index); } updateBackgroundRestrictedUidPackagesLocked(); return true; } Loading Loading @@ -966,6 +1017,7 @@ public class AppStateTrackerImpl implements AppStateTracker { mRunAnyRestrictedPackages.removeAt(i); } } updateBackgroundRestrictedUidPackagesLocked(); cleanUpArrayForUser(mActiveUids, removedUserId); mExemptedBucketPackages.remove(removedUserId); } Loading services/core/java/com/android/server/am/ActiveServices.java +25 −8 Original line number Diff line number Diff line Loading @@ -329,16 +329,25 @@ public final class ActiveServices { }; /** * Watch for apps being put into forced app standby, so we can step their fg * Reference to the AppStateTracker service. No lock is needed as we'll assign with the same * instance to it always. */ AppStateTracker mAppStateTracker; /** * Watch for apps being put into background restricted, so we can step their fg * services down. */ class ForcedStandbyListener implements AppStateTracker.ServiceStateListener { class BackgroundRestrictedListener implements AppStateTracker.BackgroundRestrictedAppListener { @Override public void stopForegroundServicesForUidPackage(final int uid, final String packageName) { public void updateBackgroundRestrictedForUidPackage(int uid, String packageName, boolean restricted) { synchronized (mAm) { if (!isForegroundServiceAllowedInBackgroundRestricted(uid, packageName)) { stopAllForegroundServicesLocked(uid, packageName); } mAm.mProcessList.updateBackgroundRestrictedForUidPackageLocked( uid, packageName, restricted); } } } Loading Loading @@ -523,12 +532,18 @@ public final class ActiveServices { } void systemServicesReady() { AppStateTracker ast = LocalServices.getService(AppStateTracker.class); ast.addServiceStateListener(new ForcedStandbyListener()); getAppStateTracker().addBackgroundRestrictedAppListener(new BackgroundRestrictedListener()); mAppWidgetManagerInternal = LocalServices.getService(AppWidgetManagerInternal.class); setAllowListWhileInUsePermissionInFgs(); } private AppStateTracker getAppStateTracker() { if (mAppStateTracker == null) { mAppStateTracker = LocalServices.getService(AppStateTracker.class); } return mAppStateTracker; } private void setAllowListWhileInUsePermissionInFgs() { final String attentionServicePackageName = mAm.mContext.getPackageManager().getAttentionServicePackageName(); Loading Loading @@ -607,9 +622,11 @@ public final class ActiveServices { } private boolean appRestrictedAnyInBackground(final int uid, final String packageName) { final int mode = mAm.getAppOpsManager().checkOpNoThrow( AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName); return (mode != AppOpsManager.MODE_ALLOWED); final AppStateTracker appStateTracker = getAppStateTracker(); if (appStateTracker != null) { return appStateTracker.isAppBackgroundRestricted(uid, packageName); } return false; } void updateAppRestrictedAnyInBackgroundLocked(final int uid, final String packageName) { Loading services/core/java/com/android/server/am/ActivityManagerConstants.java +51 −2 Original line number Diff line number Diff line Loading @@ -56,7 +56,8 @@ final class ActivityManagerConstants extends ContentObserver { private static final String TAG = "ActivityManagerConstants"; // Key names stored in the settings value. private static final String KEY_BACKGROUND_SETTLE_TIME = "background_settle_time"; static final String KEY_BACKGROUND_SETTLE_TIME = "background_settle_time"; private static final String KEY_FGSERVICE_MIN_SHOWN_TIME = "fgservice_min_shown_time"; private static final String KEY_FGSERVICE_MIN_REPORT_TIME Loading Loading @@ -119,9 +120,11 @@ final class ActivityManagerConstants extends ContentObserver { "extra_delay_svc_restart_mem_pressure"; static final String KEY_ENABLE_EXTRA_SERVICE_RESTART_DELAY_ON_MEM_PRESSURE = "enable_extra_delay_svc_restart_mem_pressure"; static final String KEY_KILL_BG_RESTRICTED_CACHED_IDLE = "kill_bg_restricted_cached_idle"; static final String KEY_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME = "kill_bg_restricted_cached_idle_settle_time"; private static final int DEFAULT_MAX_CACHED_PROCESSES = 32; private static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60*1000; private static final long DEFAULT_FGSERVICE_MIN_SHOWN_TIME = 2*1000; private static final long DEFAULT_FGSERVICE_MIN_REPORT_TIME = 3*1000; private static final long DEFAULT_FGSERVICE_SCREEN_ON_BEFORE_TIME = 1*1000; Loading Loading @@ -164,6 +167,11 @@ final class ActivityManagerConstants extends ContentObserver { private static final float DEFAULT_FGS_ATOM_SAMPLE_RATE = 1; // 100 % private static final float DEFAULT_FGS_START_ALLOWED_LOG_SAMPLE_RATE = 0.25f; // 25% private static final float DEFAULT_FGS_START_DENIED_LOG_SAMPLE_RATE = 1; // 100% static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60 * 1000; static final long DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME_MS = 60 * 1000; static final boolean DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE = true; /** * Same as {@link TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED} */ Loading Loading @@ -540,6 +548,19 @@ final class ActivityManagerConstants extends ContentObserver { */ volatile float mFgsStartDeniedLogSampleRate = DEFAULT_FGS_START_DENIED_LOG_SAMPLE_RATE; /** * Whether or not to kill apps in background restricted mode and it's cached, its UID state is * idle. */ volatile boolean mKillBgRestrictedAndCachedIdle = DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE; /** * The amount of time we allow an app in background restricted mode to settle after it goes * into the cached & UID idle, before we decide to kill it. */ volatile long mKillBgRestrictedAndCachedIdleSettleTimeMs = DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME_MS; /** * Whether to allow "opt-out" from the foreground service restrictions. * (https://developer.android.com/about/versions/12/foreground-services) Loading Loading @@ -776,6 +797,12 @@ final class ActivityManagerConstants extends ContentObserver { case KEY_FGS_START_DENIED_LOG_SAMPLE_RATE: updateFgsStartDeniedLogSamplePercent(); break; case KEY_KILL_BG_RESTRICTED_CACHED_IDLE: updateKillBgRestrictedCachedIdle(); break; case KEY_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME: updateKillBgRestrictedCachedIdleSettleTime(); break; case KEY_FGS_ALLOW_OPT_OUT: updateFgsAllowOptOut(); break; Loading Loading @@ -1142,6 +1169,28 @@ final class ActivityManagerConstants extends ContentObserver { DEFAULT_FGS_START_DENIED_LOG_SAMPLE_RATE); } private void updateKillBgRestrictedCachedIdle() { mKillBgRestrictedAndCachedIdle = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_KILL_BG_RESTRICTED_CACHED_IDLE, DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE); } private void updateKillBgRestrictedCachedIdleSettleTime() { final long currentSettleTime = mKillBgRestrictedAndCachedIdleSettleTimeMs; mKillBgRestrictedAndCachedIdleSettleTimeMs = DeviceConfig.getLong( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME, DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME_MS); if (mKillBgRestrictedAndCachedIdleSettleTimeMs != currentSettleTime) { mService.mHandler.removeMessages( ActivityManagerService.IDLE_UIDS_MSG); mService.mHandler.sendEmptyMessageDelayed( ActivityManagerService.IDLE_UIDS_MSG, mKillBgRestrictedAndCachedIdleSettleTimeMs); } } private void updateFgsAllowOptOut() { mFgsAllowOptOut = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, Loading services/core/java/com/android/server/am/ActivityManagerService.java +13 −12 Original line number Diff line number Diff line Loading @@ -1832,18 +1832,6 @@ public class ActivityManagerService extends IActivityManager.Stub } }); mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, null, new IAppOpsCallback.Stub() { @Override public void opChanged(int op, int uid, String packageName) { if (op == AppOpsManager.OP_RUN_ANY_IN_BACKGROUND && packageName != null) { synchronized (ActivityManagerService.this) { mServices.updateAppRestrictedAnyInBackgroundLocked( uid, packageName); } } } }); final int[] cameraOp = {AppOpsManager.OP_CAMERA}; mAppOpsService.startWatchingActive(cameraOp, new IAppOpsActiveCallback.Stub() { @Override Loading Loading @@ -9495,6 +9483,15 @@ public class ActivityManagerService extends IActivityManager.Stub TimeUtils.dumpTimeWithDelta(pw, expirationInCurrentTime, currentTimeNow); pw.println(); }); if (!mProcessList.mAppsInBackgroundRestricted.isEmpty()) { pw.println(" Processes that are in background restricted:"); for (int i = 0, size = mProcessList.mAppsInBackgroundRestricted.size(); i < size; i++) { pw.println(String.format("%s #%2d: %s", " ", i, mProcessList.mAppsInBackgroundRestricted.valueAt(i).toString())); } } } if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient || mOrigWaitForDebugger) { Loading Loading @@ -14441,6 +14438,10 @@ public class ActivityManagerService extends IActivityManager.Stub final int capability = uidRec != null ? uidRec.getSetCapability() : 0; final boolean ephemeral = uidRec != null ? uidRec.isEphemeral() : isEphemeralLocked(uid); if (uidRec != null && uidRec.isIdle() && (change & UidRecord.CHANGE_IDLE) != 0) { mProcessList.killAppIfBgRestrictedAndCachedIdleLocked(uidRec); } if (uidRec != null && !uidRec.isIdle() && (change & UidRecord.CHANGE_GONE) != 0) { // If this uid is going away, and we haven't yet reported it is gone, // then do so now. Loading
apex/jobscheduler/framework/java/com/android/server/AppStateTracker.java +14 −8 Original line number Diff line number Diff line Loading @@ -25,19 +25,25 @@ public interface AppStateTracker { String TAG = "AppStateTracker"; /** * Register a {@link ServiceStateListener} to listen for forced-app-standby changes that should * affect services. * Register a {@link BackgroundRestrictedAppListener} to listen for background restricted mode * changes that should affect services etc. */ void addServiceStateListener(@NonNull ServiceStateListener listener); void addBackgroundRestrictedAppListener(@NonNull BackgroundRestrictedAppListener listener); /** * A listener to listen to forced-app-standby changes that should affect services. * @return {code true} if the given UID/package has been in background restricted mode, * it does NOT include the case where the "force app background restricted" is enabled. */ interface ServiceStateListener { boolean isAppBackgroundRestricted(int uid, @NonNull String packageName); /** * A listener to listen to background restricted mode changes that should affect services etc. */ interface BackgroundRestrictedAppListener { /** * Called when an app goes into forced app standby and its foreground * services need to be removed from that state. * Called when an app goes in/out of background restricted mode. */ void stopForegroundServicesForUidPackage(int uid, String packageName); void updateBackgroundRestrictedForUidPackage(int uid, String packageName, boolean restricted); } }
apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java +62 −10 Original line number Diff line number Diff line Loading @@ -60,8 +60,10 @@ import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener; import java.io.PrintWriter; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; /** * Class to keep track of the information related to "force app standby", which includes: Loading Loading @@ -160,16 +162,34 @@ public class AppStateTrackerImpl implements AppStateTracker { @GuardedBy("mLock") boolean mForcedAppStandbyEnabled; /** * A lock-free set of (uid, packageName) pairs in background restricted mode. * * <p> * It's bascially shadowing the {@link #mRunAnyRestrictedPackages} together with * the {@link #mForcedAppStandbyEnabled} - mutations on them would result in copy-on-write. * </p> */ volatile Set<Pair<Integer, String>> mBackgroundRestrictedUidPackages = Collections.emptySet(); @Override public void addServiceStateListener(@NonNull ServiceStateListener listener) { public void addBackgroundRestrictedAppListener( @NonNull BackgroundRestrictedAppListener listener) { addListener(new Listener() { @Override public void stopForegroundServicesForUidPackage(int uid, String packageName) { listener.stopForegroundServicesForUidPackage(uid, packageName); public void updateBackgroundRestrictedForUidPackage(int uid, String packageName, boolean restricted) { listener.updateBackgroundRestrictedForUidPackage(uid, packageName, restricted); } }); } @Override public boolean isAppBackgroundRestricted(int uid, @NonNull String packageName) { final Set<Pair<Integer, String>> bgRestrictedUidPkgs = mBackgroundRestrictedUidPackages; return bgRestrictedUidPkgs.contains(Pair.create(uid, packageName)); } interface Stats { int UID_FG_STATE_CHANGED = 0; int UID_ACTIVE_STATE_CHANGED = 1; Loading Loading @@ -233,6 +253,7 @@ public class AppStateTrackerImpl implements AppStateTracker { return; } mForcedAppStandbyEnabled = enabled; updateBackgroundRestrictedUidPackagesLocked(); if (DEBUG) { Slog.d(TAG, "Forced app standby feature flag changed: " + mForcedAppStandbyEnabled); Loading Loading @@ -277,7 +298,11 @@ public class AppStateTrackerImpl implements AppStateTracker { if (!sender.isRunAnyInBackgroundAppOpsAllowed(uid, packageName)) { Slog.v(TAG, "Package " + packageName + "/" + uid + " toggled into fg service restriction"); stopForegroundServicesForUidPackage(uid, packageName); updateBackgroundRestrictedForUidPackage(uid, packageName, true); } else { Slog.v(TAG, "Package " + packageName + "/" + uid + " toggled out of fg service restriction"); updateBackgroundRestrictedForUidPackage(uid, packageName, false); } } Loading Loading @@ -366,10 +391,10 @@ public class AppStateTrackerImpl implements AppStateTracker { } /** * Called when an app goes into forced app standby and its foreground * services need to be removed from that state. * Called when an app goes in/out of background restricted mode. */ public void stopForegroundServicesForUidPackage(int uid, String packageName) { public void updateBackgroundRestrictedForUidPackage(int uid, String packageName, boolean restricted) { } /** Loading Loading @@ -438,10 +463,13 @@ public class AppStateTrackerImpl implements AppStateTracker { final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); // No need to notify for state change as all the alarms and jobs should be // removed too. synchronized (mLock) { mExemptedBucketPackages.remove(userId, pkgName); mRunAnyRestrictedPackages.remove(Pair.create(uid, pkgName)); updateBackgroundRestrictedUidPackagesLocked(); mActiveUids.delete(uid); } } break; } } Loading Loading @@ -580,6 +608,28 @@ public class AppStateTrackerImpl implements AppStateTracker { } } } updateBackgroundRestrictedUidPackagesLocked(); } /** * Update the {@link #mBackgroundRestrictedUidPackages} upon mutations on * {@link #mRunAnyRestrictedPackages} or {@link #mForcedAppStandbyEnabled}. */ @GuardedBy("mLock") private void updateBackgroundRestrictedUidPackagesLocked() { if (!mForcedAppStandbyEnabled) { mBackgroundRestrictedUidPackages = Collections.emptySet(); return; } if (mForceAllAppsStandby) { mBackgroundRestrictedUidPackages = null; return; } Set<Pair<Integer, String>> fasUidPkgs = new ArraySet<>(); for (int i = 0, size = mRunAnyRestrictedPackages.size(); i < size; i++) { fasUidPkgs.add(mRunAnyRestrictedPackages.valueAt(i)); } mBackgroundRestrictedUidPackages = Collections.unmodifiableSet(fasUidPkgs); } private void updateForceAllAppStandbyState() { Loading Loading @@ -645,6 +695,7 @@ public class AppStateTrackerImpl implements AppStateTracker { } else { mRunAnyRestrictedPackages.removeAt(index); } updateBackgroundRestrictedUidPackagesLocked(); return true; } Loading Loading @@ -966,6 +1017,7 @@ public class AppStateTrackerImpl implements AppStateTracker { mRunAnyRestrictedPackages.removeAt(i); } } updateBackgroundRestrictedUidPackagesLocked(); cleanUpArrayForUser(mActiveUids, removedUserId); mExemptedBucketPackages.remove(removedUserId); } Loading
services/core/java/com/android/server/am/ActiveServices.java +25 −8 Original line number Diff line number Diff line Loading @@ -329,16 +329,25 @@ public final class ActiveServices { }; /** * Watch for apps being put into forced app standby, so we can step their fg * Reference to the AppStateTracker service. No lock is needed as we'll assign with the same * instance to it always. */ AppStateTracker mAppStateTracker; /** * Watch for apps being put into background restricted, so we can step their fg * services down. */ class ForcedStandbyListener implements AppStateTracker.ServiceStateListener { class BackgroundRestrictedListener implements AppStateTracker.BackgroundRestrictedAppListener { @Override public void stopForegroundServicesForUidPackage(final int uid, final String packageName) { public void updateBackgroundRestrictedForUidPackage(int uid, String packageName, boolean restricted) { synchronized (mAm) { if (!isForegroundServiceAllowedInBackgroundRestricted(uid, packageName)) { stopAllForegroundServicesLocked(uid, packageName); } mAm.mProcessList.updateBackgroundRestrictedForUidPackageLocked( uid, packageName, restricted); } } } Loading Loading @@ -523,12 +532,18 @@ public final class ActiveServices { } void systemServicesReady() { AppStateTracker ast = LocalServices.getService(AppStateTracker.class); ast.addServiceStateListener(new ForcedStandbyListener()); getAppStateTracker().addBackgroundRestrictedAppListener(new BackgroundRestrictedListener()); mAppWidgetManagerInternal = LocalServices.getService(AppWidgetManagerInternal.class); setAllowListWhileInUsePermissionInFgs(); } private AppStateTracker getAppStateTracker() { if (mAppStateTracker == null) { mAppStateTracker = LocalServices.getService(AppStateTracker.class); } return mAppStateTracker; } private void setAllowListWhileInUsePermissionInFgs() { final String attentionServicePackageName = mAm.mContext.getPackageManager().getAttentionServicePackageName(); Loading Loading @@ -607,9 +622,11 @@ public final class ActiveServices { } private boolean appRestrictedAnyInBackground(final int uid, final String packageName) { final int mode = mAm.getAppOpsManager().checkOpNoThrow( AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName); return (mode != AppOpsManager.MODE_ALLOWED); final AppStateTracker appStateTracker = getAppStateTracker(); if (appStateTracker != null) { return appStateTracker.isAppBackgroundRestricted(uid, packageName); } return false; } void updateAppRestrictedAnyInBackgroundLocked(final int uid, final String packageName) { Loading
services/core/java/com/android/server/am/ActivityManagerConstants.java +51 −2 Original line number Diff line number Diff line Loading @@ -56,7 +56,8 @@ final class ActivityManagerConstants extends ContentObserver { private static final String TAG = "ActivityManagerConstants"; // Key names stored in the settings value. private static final String KEY_BACKGROUND_SETTLE_TIME = "background_settle_time"; static final String KEY_BACKGROUND_SETTLE_TIME = "background_settle_time"; private static final String KEY_FGSERVICE_MIN_SHOWN_TIME = "fgservice_min_shown_time"; private static final String KEY_FGSERVICE_MIN_REPORT_TIME Loading Loading @@ -119,9 +120,11 @@ final class ActivityManagerConstants extends ContentObserver { "extra_delay_svc_restart_mem_pressure"; static final String KEY_ENABLE_EXTRA_SERVICE_RESTART_DELAY_ON_MEM_PRESSURE = "enable_extra_delay_svc_restart_mem_pressure"; static final String KEY_KILL_BG_RESTRICTED_CACHED_IDLE = "kill_bg_restricted_cached_idle"; static final String KEY_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME = "kill_bg_restricted_cached_idle_settle_time"; private static final int DEFAULT_MAX_CACHED_PROCESSES = 32; private static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60*1000; private static final long DEFAULT_FGSERVICE_MIN_SHOWN_TIME = 2*1000; private static final long DEFAULT_FGSERVICE_MIN_REPORT_TIME = 3*1000; private static final long DEFAULT_FGSERVICE_SCREEN_ON_BEFORE_TIME = 1*1000; Loading Loading @@ -164,6 +167,11 @@ final class ActivityManagerConstants extends ContentObserver { private static final float DEFAULT_FGS_ATOM_SAMPLE_RATE = 1; // 100 % private static final float DEFAULT_FGS_START_ALLOWED_LOG_SAMPLE_RATE = 0.25f; // 25% private static final float DEFAULT_FGS_START_DENIED_LOG_SAMPLE_RATE = 1; // 100% static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60 * 1000; static final long DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME_MS = 60 * 1000; static final boolean DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE = true; /** * Same as {@link TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED} */ Loading Loading @@ -540,6 +548,19 @@ final class ActivityManagerConstants extends ContentObserver { */ volatile float mFgsStartDeniedLogSampleRate = DEFAULT_FGS_START_DENIED_LOG_SAMPLE_RATE; /** * Whether or not to kill apps in background restricted mode and it's cached, its UID state is * idle. */ volatile boolean mKillBgRestrictedAndCachedIdle = DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE; /** * The amount of time we allow an app in background restricted mode to settle after it goes * into the cached & UID idle, before we decide to kill it. */ volatile long mKillBgRestrictedAndCachedIdleSettleTimeMs = DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME_MS; /** * Whether to allow "opt-out" from the foreground service restrictions. * (https://developer.android.com/about/versions/12/foreground-services) Loading Loading @@ -776,6 +797,12 @@ final class ActivityManagerConstants extends ContentObserver { case KEY_FGS_START_DENIED_LOG_SAMPLE_RATE: updateFgsStartDeniedLogSamplePercent(); break; case KEY_KILL_BG_RESTRICTED_CACHED_IDLE: updateKillBgRestrictedCachedIdle(); break; case KEY_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME: updateKillBgRestrictedCachedIdleSettleTime(); break; case KEY_FGS_ALLOW_OPT_OUT: updateFgsAllowOptOut(); break; Loading Loading @@ -1142,6 +1169,28 @@ final class ActivityManagerConstants extends ContentObserver { DEFAULT_FGS_START_DENIED_LOG_SAMPLE_RATE); } private void updateKillBgRestrictedCachedIdle() { mKillBgRestrictedAndCachedIdle = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_KILL_BG_RESTRICTED_CACHED_IDLE, DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE); } private void updateKillBgRestrictedCachedIdleSettleTime() { final long currentSettleTime = mKillBgRestrictedAndCachedIdleSettleTimeMs; mKillBgRestrictedAndCachedIdleSettleTimeMs = DeviceConfig.getLong( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME, DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME_MS); if (mKillBgRestrictedAndCachedIdleSettleTimeMs != currentSettleTime) { mService.mHandler.removeMessages( ActivityManagerService.IDLE_UIDS_MSG); mService.mHandler.sendEmptyMessageDelayed( ActivityManagerService.IDLE_UIDS_MSG, mKillBgRestrictedAndCachedIdleSettleTimeMs); } } private void updateFgsAllowOptOut() { mFgsAllowOptOut = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, Loading
services/core/java/com/android/server/am/ActivityManagerService.java +13 −12 Original line number Diff line number Diff line Loading @@ -1832,18 +1832,6 @@ public class ActivityManagerService extends IActivityManager.Stub } }); mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, null, new IAppOpsCallback.Stub() { @Override public void opChanged(int op, int uid, String packageName) { if (op == AppOpsManager.OP_RUN_ANY_IN_BACKGROUND && packageName != null) { synchronized (ActivityManagerService.this) { mServices.updateAppRestrictedAnyInBackgroundLocked( uid, packageName); } } } }); final int[] cameraOp = {AppOpsManager.OP_CAMERA}; mAppOpsService.startWatchingActive(cameraOp, new IAppOpsActiveCallback.Stub() { @Override Loading Loading @@ -9495,6 +9483,15 @@ public class ActivityManagerService extends IActivityManager.Stub TimeUtils.dumpTimeWithDelta(pw, expirationInCurrentTime, currentTimeNow); pw.println(); }); if (!mProcessList.mAppsInBackgroundRestricted.isEmpty()) { pw.println(" Processes that are in background restricted:"); for (int i = 0, size = mProcessList.mAppsInBackgroundRestricted.size(); i < size; i++) { pw.println(String.format("%s #%2d: %s", " ", i, mProcessList.mAppsInBackgroundRestricted.valueAt(i).toString())); } } } if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient || mOrigWaitForDebugger) { Loading Loading @@ -14441,6 +14438,10 @@ public class ActivityManagerService extends IActivityManager.Stub final int capability = uidRec != null ? uidRec.getSetCapability() : 0; final boolean ephemeral = uidRec != null ? uidRec.isEphemeral() : isEphemeralLocked(uid); if (uidRec != null && uidRec.isIdle() && (change & UidRecord.CHANGE_IDLE) != 0) { mProcessList.killAppIfBgRestrictedAndCachedIdleLocked(uidRec); } if (uidRec != null && !uidRec.isIdle() && (change & UidRecord.CHANGE_GONE) != 0) { // If this uid is going away, and we haven't yet reported it is gone, // then do so now.