Loading services/core/java/com/android/server/AppStateTracker.java +23 −0 Original line number Diff line number Diff line Loading @@ -261,6 +261,12 @@ public class AppStateTracker { // we need to deliver the allow-while-idle alarms for this uid, package unblockAllUnrestrictedAlarms(); } if (!sender.isRunAnyInBackgroundAppOpsAllowed(uid, packageName)) { Slog.v(TAG, "Package " + packageName + "/" + uid + " toggled into fg service restriction"); stopForegroundServicesForUidPackage(uid, packageName); } } /** Loading Loading @@ -353,6 +359,13 @@ public class AppStateTracker { public void updateJobsForUidPackage(int uid, String packageName, boolean isNowActive) { } /** * Called when an app goes into forced app standby and its foreground * services need to be removed from that state. */ public void stopForegroundServicesForUidPackage(int uid, String packageName) { } /** * Called when the job restrictions for multiple UIDs might have changed, so the alarm * manager should re-evaluate all restrictions for all blocked jobs. Loading Loading @@ -1056,6 +1069,16 @@ public class AppStateTracker { hasForegroundExemption); } /** * @return whether foreground services should be suppressed in the background * due to forced app standby for the given app */ public boolean areForegroundServicesRestricted(int uid, @NonNull String packageName) { synchronized (mLock) { return isRunAnyRestrictedLocked(uid, packageName); } } /** * @return whether force-app-standby is effective for a UID package-name. */ Loading services/core/java/com/android/server/am/ActiveServices.java +117 −39 Original line number Diff line number Diff line Loading @@ -56,6 +56,8 @@ import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.BatteryStatsImpl; import com.android.internal.os.TransferPipe; import com.android.internal.util.FastPrintWriter; import com.android.server.AppStateTracker; import com.android.server.LocalServices; import com.android.server.am.ActivityManagerService.ItemMatcher; import com.android.server.am.ActivityManagerService.NeededUriGrants; import com.android.server.am.proto.ActiveServicesProto; Loading Loading @@ -164,6 +166,44 @@ public final class ActiveServices { } }; /** * Watch for apps being put into forced app standby, so we can step their fg * services down. */ class ForcedStandbyListener extends AppStateTracker.Listener { @Override public void stopForegroundServicesForUidPackage(final int uid, final String packageName) { synchronized (mAm) { final ServiceMap smap = getServiceMapLocked(UserHandle.getUserId(uid)); final int N = smap.mServicesByName.size(); final ArrayList<ServiceRecord> toStop = new ArrayList<>(N); for (int i = 0; i < N; i++) { final ServiceRecord r = smap.mServicesByName.valueAt(i); if (uid == r.serviceInfo.applicationInfo.uid || packageName.equals(r.serviceInfo.packageName)) { if (r.isForeground) { toStop.add(r); } } } // Now stop them all final int numToStop = toStop.size(); if (numToStop > 0 && DEBUG_FOREGROUND_SERVICE) { Slog.i(TAG, "Package " + packageName + "/" + uid + " entering FAS with foreground services"); } for (int i = 0; i < numToStop; i++) { final ServiceRecord r = toStop.get(i); if (DEBUG_FOREGROUND_SERVICE) { Slog.i(TAG, " Stopping fg for service " + r); } setServiceForegroundInnerLocked(r, 0, null, 0); } } } } /** * Information about an app that is currently running one or more foreground services. * (This maps directly to the running apps we show in the notification.) Loading Loading @@ -302,6 +342,11 @@ public final class ActiveServices { ? maxBg : ActivityManager.isLowRamDeviceStatic() ? 1 : 8; } void systemServicesReady() { AppStateTracker ast = LocalServices.getService(AppStateTracker.class); ast.addListener(new ForcedStandbyListener()); } ServiceRecord getServiceByNameLocked(ComponentName name, int callingUser) { // TODO: Deal with global services if (DEBUG_MU) Loading @@ -327,6 +372,12 @@ public final class ActiveServices { return getServiceMapLocked(callingUser).mServicesByName; } private boolean appRestrictedAnyInBackground(final int uid, final String packageName) { final int mode = mAm.mAppOpsService.checkOperation( AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName); return (mode != AppOpsManager.MODE_ALLOWED); } ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId) throws TransactionTooLargeException { Loading Loading @@ -365,13 +416,24 @@ public final class ActiveServices { return null; } // If the app has strict background restrictions, we treat any service // start analogously to the legacy-app forced-restrictions case. boolean forcedStandby = false; if (appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) { if (DEBUG_FOREGROUND_SERVICE) { Slog.d(TAG, "Forcing bg-only service start only for " + r.name.flattenToShortString()); } forcedStandby = true; } // If this isn't a direct-to-foreground start, check our ability to kick off an // arbitrary service if (!r.startRequested && !fgRequired) { if (forcedStandby || (!r.startRequested && !fgRequired)) { // Before going further -- if this app is not allowed to start services in the // background, then at this point we aren't going to let it period. final int allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName, r.appInfo.targetSdkVersion, callingPid, false, false); r.appInfo.targetSdkVersion, callingPid, false, false, forcedStandby); if (allowed != ActivityManager.APP_START_MODE_NORMAL) { Slog.w(TAG, "Background start not allowed: service " + service + " to " + r.name.flattenToShortString() Loading Loading @@ -625,7 +687,7 @@ public final class ActiveServices { ServiceRecord service = services.mServicesByName.valueAt(i); if (service.appInfo.uid == uid && service.startRequested) { if (mAm.getAppStartModeLocked(service.appInfo.uid, service.packageName, service.appInfo.targetSdkVersion, -1, false, false) service.appInfo.targetSdkVersion, -1, false, false, false) != ActivityManager.APP_START_MODE_NORMAL) { if (stopping == null) { stopping = new ArrayList<>(); Loading Loading @@ -1019,7 +1081,10 @@ public final class ActiveServices { } } private void setServiceForegroundInnerLocked(ServiceRecord r, int id, /** * @param id Notification ID. Zero === exit foreground state for the given service. */ private void setServiceForegroundInnerLocked(final ServiceRecord r, int id, Notification notification, int flags) { if (id != 0) { if (notification == null) { Loading Loading @@ -1061,6 +1126,12 @@ public final class ActiveServices { mAm.mHandler.removeMessages( ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r); } // Apps under strict background restrictions simply don't get to have foreground // services, so now that we've enforced the startForegroundService() contract // we only do the machinery of making the service foreground when the app // is not restricted. if (!appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) { if (r.foregroundId != id) { cancelForegroundNotificationLocked(r); r.foregroundId = id; Loading Loading @@ -1089,7 +1160,8 @@ public final class ActiveServices { active.mNumActive++; } r.isForeground = true; StatsLog.write(StatsLog.FOREGROUND_SERVICE_STATE_CHANGED, r.appInfo.uid, r.shortName, StatsLog.write(StatsLog.FOREGROUND_SERVICE_STATE_CHANGED, r.appInfo.uid, r.shortName, StatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER); } r.postNotification(); Loading @@ -1099,6 +1171,11 @@ public final class ActiveServices { getServiceMapLocked(r.userId).ensureNotStartingBackgroundLocked(r); mAm.notifyPackageUse(r.serviceInfo.packageName, PackageManager.NOTIFY_PACKAGE_USE_FOREGROUND_SERVICE); } else { if (DEBUG_FOREGROUND_SERVICE) { Slog.d(TAG, "Suppressing startForeground() for FAS " + r); } } } else { if (r.isForeground) { final ServiceMap smap = getServiceMapLocked(r.userId); Loading @@ -1106,7 +1183,8 @@ public final class ActiveServices { decActiveForegroundAppLocked(smap, r); } r.isForeground = false; StatsLog.write(StatsLog.FOREGROUND_SERVICE_STATE_CHANGED, r.appInfo.uid, r.shortName, StatsLog.write(StatsLog.FOREGROUND_SERVICE_STATE_CHANGED, r.appInfo.uid, r.shortName, StatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT); if (r.app != null) { mAm.updateLruProcessLocked(r.app, false, null); Loading services/core/java/com/android/server/am/ActivityManagerService.java +5 −6 Original line number Diff line number Diff line Loading @@ -123,7 +123,6 @@ import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICAT import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static com.android.internal.util.XmlUtils.readBooleanAttribute; import static com.android.internal.util.XmlUtils.readIntAttribute; import static com.android.internal.util.XmlUtils.readLongAttribute; Loading Loading @@ -205,7 +204,6 @@ import static android.view.WindowManager.TRANSIT_NONE; import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE; import static android.view.WindowManager.TRANSIT_TASK_OPEN; import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.START_TAG; Loading Loading @@ -390,8 +388,8 @@ import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationDefinition; import android.view.View; import android.view.WindowManager; import android.view.autofill.AutofillManagerInternal; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -2853,6 +2851,7 @@ public class ActivityManagerService extends IActivityManager.Stub public void onBootPhase(int phase) { if (phase == PHASE_SYSTEM_SERVICES_READY) { mService.mBatteryStatsService.systemServicesReady(); mService.mServices.systemServicesReady(); } } Loading Loading @@ -9118,7 +9117,7 @@ public class ActivityManagerService extends IActivityManager.Stub public boolean isAppStartModeDisabled(int uid, String packageName) { synchronized (this) { return getAppStartModeLocked(uid, packageName, 0, -1, false, true) return getAppStartModeLocked(uid, packageName, 0, -1, false, true, false) == ActivityManager.APP_START_MODE_DISABLED; } } Loading Loading @@ -9194,12 +9193,12 @@ public class ActivityManagerService extends IActivityManager.Stub } int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk, int callingPid, boolean alwaysRestrict, boolean disabledOnly) { int callingPid, boolean alwaysRestrict, boolean disabledOnly, boolean forcedStandby) { UidRecord uidRec = mActiveUids.get(uid); if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg=" + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle=" + (uidRec != null ? uidRec.idle : false)); if (uidRec == null || alwaysRestrict || uidRec.idle) { if (uidRec == null || alwaysRestrict || forcedStandby || uidRec.idle) { boolean ephemeral; if (uidRec == null) { ephemeral = getPackageManagerInternalLocked().isPackageEphemeral( services/core/java/com/android/server/am/BroadcastQueue.java +1 −1 Original line number Diff line number Diff line Loading @@ -1258,7 +1258,7 @@ public final class BroadcastQueue { if (!skip) { final int allowed = mService.getAppStartModeLocked( info.activityInfo.applicationInfo.uid, info.activityInfo.packageName, info.activityInfo.applicationInfo.targetSdkVersion, -1, true, false); info.activityInfo.applicationInfo.targetSdkVersion, -1, true, false, false); if (allowed != ActivityManager.APP_START_MODE_NORMAL) { // We won't allow this receiver to be launched if the app has been // completely disabled from launches, or it was not explicitly sent Loading Loading
services/core/java/com/android/server/AppStateTracker.java +23 −0 Original line number Diff line number Diff line Loading @@ -261,6 +261,12 @@ public class AppStateTracker { // we need to deliver the allow-while-idle alarms for this uid, package unblockAllUnrestrictedAlarms(); } if (!sender.isRunAnyInBackgroundAppOpsAllowed(uid, packageName)) { Slog.v(TAG, "Package " + packageName + "/" + uid + " toggled into fg service restriction"); stopForegroundServicesForUidPackage(uid, packageName); } } /** Loading Loading @@ -353,6 +359,13 @@ public class AppStateTracker { public void updateJobsForUidPackage(int uid, String packageName, boolean isNowActive) { } /** * Called when an app goes into forced app standby and its foreground * services need to be removed from that state. */ public void stopForegroundServicesForUidPackage(int uid, String packageName) { } /** * Called when the job restrictions for multiple UIDs might have changed, so the alarm * manager should re-evaluate all restrictions for all blocked jobs. Loading Loading @@ -1056,6 +1069,16 @@ public class AppStateTracker { hasForegroundExemption); } /** * @return whether foreground services should be suppressed in the background * due to forced app standby for the given app */ public boolean areForegroundServicesRestricted(int uid, @NonNull String packageName) { synchronized (mLock) { return isRunAnyRestrictedLocked(uid, packageName); } } /** * @return whether force-app-standby is effective for a UID package-name. */ Loading
services/core/java/com/android/server/am/ActiveServices.java +117 −39 Original line number Diff line number Diff line Loading @@ -56,6 +56,8 @@ import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.BatteryStatsImpl; import com.android.internal.os.TransferPipe; import com.android.internal.util.FastPrintWriter; import com.android.server.AppStateTracker; import com.android.server.LocalServices; import com.android.server.am.ActivityManagerService.ItemMatcher; import com.android.server.am.ActivityManagerService.NeededUriGrants; import com.android.server.am.proto.ActiveServicesProto; Loading Loading @@ -164,6 +166,44 @@ public final class ActiveServices { } }; /** * Watch for apps being put into forced app standby, so we can step their fg * services down. */ class ForcedStandbyListener extends AppStateTracker.Listener { @Override public void stopForegroundServicesForUidPackage(final int uid, final String packageName) { synchronized (mAm) { final ServiceMap smap = getServiceMapLocked(UserHandle.getUserId(uid)); final int N = smap.mServicesByName.size(); final ArrayList<ServiceRecord> toStop = new ArrayList<>(N); for (int i = 0; i < N; i++) { final ServiceRecord r = smap.mServicesByName.valueAt(i); if (uid == r.serviceInfo.applicationInfo.uid || packageName.equals(r.serviceInfo.packageName)) { if (r.isForeground) { toStop.add(r); } } } // Now stop them all final int numToStop = toStop.size(); if (numToStop > 0 && DEBUG_FOREGROUND_SERVICE) { Slog.i(TAG, "Package " + packageName + "/" + uid + " entering FAS with foreground services"); } for (int i = 0; i < numToStop; i++) { final ServiceRecord r = toStop.get(i); if (DEBUG_FOREGROUND_SERVICE) { Slog.i(TAG, " Stopping fg for service " + r); } setServiceForegroundInnerLocked(r, 0, null, 0); } } } } /** * Information about an app that is currently running one or more foreground services. * (This maps directly to the running apps we show in the notification.) Loading Loading @@ -302,6 +342,11 @@ public final class ActiveServices { ? maxBg : ActivityManager.isLowRamDeviceStatic() ? 1 : 8; } void systemServicesReady() { AppStateTracker ast = LocalServices.getService(AppStateTracker.class); ast.addListener(new ForcedStandbyListener()); } ServiceRecord getServiceByNameLocked(ComponentName name, int callingUser) { // TODO: Deal with global services if (DEBUG_MU) Loading @@ -327,6 +372,12 @@ public final class ActiveServices { return getServiceMapLocked(callingUser).mServicesByName; } private boolean appRestrictedAnyInBackground(final int uid, final String packageName) { final int mode = mAm.mAppOpsService.checkOperation( AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName); return (mode != AppOpsManager.MODE_ALLOWED); } ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId) throws TransactionTooLargeException { Loading Loading @@ -365,13 +416,24 @@ public final class ActiveServices { return null; } // If the app has strict background restrictions, we treat any service // start analogously to the legacy-app forced-restrictions case. boolean forcedStandby = false; if (appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) { if (DEBUG_FOREGROUND_SERVICE) { Slog.d(TAG, "Forcing bg-only service start only for " + r.name.flattenToShortString()); } forcedStandby = true; } // If this isn't a direct-to-foreground start, check our ability to kick off an // arbitrary service if (!r.startRequested && !fgRequired) { if (forcedStandby || (!r.startRequested && !fgRequired)) { // Before going further -- if this app is not allowed to start services in the // background, then at this point we aren't going to let it period. final int allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName, r.appInfo.targetSdkVersion, callingPid, false, false); r.appInfo.targetSdkVersion, callingPid, false, false, forcedStandby); if (allowed != ActivityManager.APP_START_MODE_NORMAL) { Slog.w(TAG, "Background start not allowed: service " + service + " to " + r.name.flattenToShortString() Loading Loading @@ -625,7 +687,7 @@ public final class ActiveServices { ServiceRecord service = services.mServicesByName.valueAt(i); if (service.appInfo.uid == uid && service.startRequested) { if (mAm.getAppStartModeLocked(service.appInfo.uid, service.packageName, service.appInfo.targetSdkVersion, -1, false, false) service.appInfo.targetSdkVersion, -1, false, false, false) != ActivityManager.APP_START_MODE_NORMAL) { if (stopping == null) { stopping = new ArrayList<>(); Loading Loading @@ -1019,7 +1081,10 @@ public final class ActiveServices { } } private void setServiceForegroundInnerLocked(ServiceRecord r, int id, /** * @param id Notification ID. Zero === exit foreground state for the given service. */ private void setServiceForegroundInnerLocked(final ServiceRecord r, int id, Notification notification, int flags) { if (id != 0) { if (notification == null) { Loading Loading @@ -1061,6 +1126,12 @@ public final class ActiveServices { mAm.mHandler.removeMessages( ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r); } // Apps under strict background restrictions simply don't get to have foreground // services, so now that we've enforced the startForegroundService() contract // we only do the machinery of making the service foreground when the app // is not restricted. if (!appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) { if (r.foregroundId != id) { cancelForegroundNotificationLocked(r); r.foregroundId = id; Loading Loading @@ -1089,7 +1160,8 @@ public final class ActiveServices { active.mNumActive++; } r.isForeground = true; StatsLog.write(StatsLog.FOREGROUND_SERVICE_STATE_CHANGED, r.appInfo.uid, r.shortName, StatsLog.write(StatsLog.FOREGROUND_SERVICE_STATE_CHANGED, r.appInfo.uid, r.shortName, StatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER); } r.postNotification(); Loading @@ -1099,6 +1171,11 @@ public final class ActiveServices { getServiceMapLocked(r.userId).ensureNotStartingBackgroundLocked(r); mAm.notifyPackageUse(r.serviceInfo.packageName, PackageManager.NOTIFY_PACKAGE_USE_FOREGROUND_SERVICE); } else { if (DEBUG_FOREGROUND_SERVICE) { Slog.d(TAG, "Suppressing startForeground() for FAS " + r); } } } else { if (r.isForeground) { final ServiceMap smap = getServiceMapLocked(r.userId); Loading @@ -1106,7 +1183,8 @@ public final class ActiveServices { decActiveForegroundAppLocked(smap, r); } r.isForeground = false; StatsLog.write(StatsLog.FOREGROUND_SERVICE_STATE_CHANGED, r.appInfo.uid, r.shortName, StatsLog.write(StatsLog.FOREGROUND_SERVICE_STATE_CHANGED, r.appInfo.uid, r.shortName, StatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT); if (r.app != null) { mAm.updateLruProcessLocked(r.app, false, null); Loading
services/core/java/com/android/server/am/ActivityManagerService.java +5 −6 Original line number Diff line number Diff line Loading @@ -123,7 +123,6 @@ import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICAT import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static com.android.internal.util.XmlUtils.readBooleanAttribute; import static com.android.internal.util.XmlUtils.readIntAttribute; import static com.android.internal.util.XmlUtils.readLongAttribute; Loading Loading @@ -205,7 +204,6 @@ import static android.view.WindowManager.TRANSIT_NONE; import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE; import static android.view.WindowManager.TRANSIT_TASK_OPEN; import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.START_TAG; Loading Loading @@ -390,8 +388,8 @@ import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationDefinition; import android.view.View; import android.view.WindowManager; import android.view.autofill.AutofillManagerInternal; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -2853,6 +2851,7 @@ public class ActivityManagerService extends IActivityManager.Stub public void onBootPhase(int phase) { if (phase == PHASE_SYSTEM_SERVICES_READY) { mService.mBatteryStatsService.systemServicesReady(); mService.mServices.systemServicesReady(); } } Loading Loading @@ -9118,7 +9117,7 @@ public class ActivityManagerService extends IActivityManager.Stub public boolean isAppStartModeDisabled(int uid, String packageName) { synchronized (this) { return getAppStartModeLocked(uid, packageName, 0, -1, false, true) return getAppStartModeLocked(uid, packageName, 0, -1, false, true, false) == ActivityManager.APP_START_MODE_DISABLED; } } Loading Loading @@ -9194,12 +9193,12 @@ public class ActivityManagerService extends IActivityManager.Stub } int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk, int callingPid, boolean alwaysRestrict, boolean disabledOnly) { int callingPid, boolean alwaysRestrict, boolean disabledOnly, boolean forcedStandby) { UidRecord uidRec = mActiveUids.get(uid); if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg=" + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle=" + (uidRec != null ? uidRec.idle : false)); if (uidRec == null || alwaysRestrict || uidRec.idle) { if (uidRec == null || alwaysRestrict || forcedStandby || uidRec.idle) { boolean ephemeral; if (uidRec == null) { ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
services/core/java/com/android/server/am/BroadcastQueue.java +1 −1 Original line number Diff line number Diff line Loading @@ -1258,7 +1258,7 @@ public final class BroadcastQueue { if (!skip) { final int allowed = mService.getAppStartModeLocked( info.activityInfo.applicationInfo.uid, info.activityInfo.packageName, info.activityInfo.applicationInfo.targetSdkVersion, -1, true, false); info.activityInfo.applicationInfo.targetSdkVersion, -1, true, false, false); if (allowed != ActivityManager.APP_START_MODE_NORMAL) { // We won't allow this receiver to be launched if the app has been // completely disabled from launches, or it was not explicitly sent Loading