Loading services/core/java/com/android/server/am/ActiveServices.java +22 −1 Original line number Diff line number Diff line Loading @@ -73,6 +73,7 @@ import static android.os.PowerExemptionManager.REASON_SYSTEM_MODULE; import static android.os.PowerExemptionManager.REASON_SYSTEM_UID; import static android.os.PowerExemptionManager.REASON_TEMP_ALLOWED_WHILE_IN_USE; import static android.os.PowerExemptionManager.REASON_UID_VISIBLE; import static android.os.PowerExemptionManager.REASON_UNKNOWN; import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED; import static android.os.PowerExemptionManager.getReasonCodeFromProcState; import static android.os.PowerExemptionManager.reasonCodeToString; Loading Loading @@ -7319,9 +7320,10 @@ public final class ActiveServices { r.mAllowWhileInUsePermissionInFgs = true; } final @ReasonCode int allowWhileInUse; if (!r.mAllowWhileInUsePermissionInFgs || (r.mAllowStartForeground == REASON_DENIED)) { final @ReasonCode int allowWhileInUse = shouldAllowFgsWhileInUsePermissionLocked( allowWhileInUse = shouldAllowFgsWhileInUsePermissionLocked( callingPackage, callingPid, callingUid, r.app, backgroundStartPrivileges, isBindService); if (!r.mAllowWhileInUsePermissionInFgs) { Loading @@ -7332,6 +7334,24 @@ public final class ActiveServices { allowWhileInUse, callingPackage, callingPid, callingUid, intent, r, backgroundStartPrivileges, isBindService); } } else { allowWhileInUse = REASON_UNKNOWN; } // We want to allow scheduling user-initiated jobs when the app is running a // foreground service that was started in the same conditions that allows for scheduling // UI jobs. More explicitly, we want to allow scheduling UI jobs when the app is running // an FGS that started when the app was in the TOP or a BAL-approved state. // As of Android UDC, the conditions required for the while-in-use permissions // are the same conditions that we want, so we piggyback on that logic. // We use that as a shortcut if possible so we don't have to recheck all the conditions. final boolean isFgs = r.isForeground || r.fgRequired; if (isFgs) { r.updateAllowUiJobScheduling(ActivityManagerService .doesReasonCodeAllowSchedulingUserInitiatedJobs(allowWhileInUse) || mAm.canScheduleUserInitiatedJobs( callingUid, callingPid, callingPackage, true)); } else { r.updateAllowUiJobScheduling(false); } } Loading @@ -7342,6 +7362,7 @@ public final class ActiveServices { r.mInfoTempFgsAllowListReason = null; r.mLoggedInfoAllowStartForeground = false; r.mLastSetFgsRestrictionTime = 0; r.updateAllowUiJobScheduling(r.mAllowWhileInUsePermissionInFgs); } boolean canStartForegroundServiceLocked(int callingPid, int callingUid, String callingPackage) { Loading services/core/java/com/android/server/am/ActivityManagerService.java +17 −2 Original line number Diff line number Diff line Loading @@ -6563,7 +6563,7 @@ public class ActivityManagerService extends IActivityManager.Stub * This is a shortcut and <b>DOES NOT</b> include all reasons. * Use {@link #canScheduleUserInitiatedJobs(int, int, String)} to cover all cases. */ private boolean doesReasonCodeAllowSchedulingUserInitiatedJobs(int reasonCode) { static boolean doesReasonCodeAllowSchedulingUserInitiatedJobs(int reasonCode) { switch (reasonCode) { case REASON_PROC_STATE_PERSISTENT: case REASON_PROC_STATE_PERSISTENT_UI: Loading Loading @@ -6621,6 +6621,16 @@ public class ActivityManagerService extends IActivityManager.Stub } } final ProcessServiceRecord psr = pr.mServices; if (psr != null && psr.hasForegroundServices()) { for (int s = psr.numberOfExecutingServices() - 1; s >= 0; --s) { final ServiceRecord sr = psr.getExecutingServiceAt(s); if (sr.isForeground && sr.mAllowUiJobScheduling) { return true; } } } return false; } Loading @@ -6630,6 +6640,11 @@ public class ActivityManagerService extends IActivityManager.Stub */ // TODO(262260570): log allow reason to an atom private boolean canScheduleUserInitiatedJobs(int uid, int pid, String pkgName) { return canScheduleUserInitiatedJobs(uid, pid, pkgName, false); } boolean canScheduleUserInitiatedJobs(int uid, int pid, String pkgName, boolean skipWhileInUseCheck) { synchronized (this) { final ProcessRecord processRecord; synchronized (mPidsSelfLocked) { Loading Loading @@ -6659,7 +6674,7 @@ public class ActivityManagerService extends IActivityManager.Stub // As of Android UDC, the conditions required to grant a while-in-use permission // covers the majority of those cases, and so we piggyback on that logic as the base. // Missing cases are added after. if (mServices.canAllowWhileInUsePermissionInFgsLocked( if (!skipWhileInUseCheck && mServices.canAllowWhileInUsePermissionInFgsLocked( pid, uid, pkgName, processRecord, backgroundStartPrivileges)) { return true; } Loading services/core/java/com/android/server/am/ServiceRecord.java +13 −0 Original line number Diff line number Diff line Loading @@ -176,6 +176,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN boolean mAllowWhileInUsePermissionInFgs; // A copy of mAllowWhileInUsePermissionInFgs's value when the service is entering FGS state. boolean mAllowWhileInUsePermissionInFgsAtEntering; /** Allow scheduling user-initiated jobs from the background. */ boolean mAllowUiJobScheduling; // the most recent package that start/bind this service. String mRecentCallingPackage; Loading Loading @@ -607,6 +609,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN } pw.print(prefix); pw.print("allowWhileInUsePermissionInFgs="); pw.println(mAllowWhileInUsePermissionInFgs); pw.print(prefix); pw.print("allowUiJobScheduling="); pw.println(mAllowUiJobScheduling); pw.print(prefix); pw.print("recentCallingPackage="); pw.println(mRecentCallingPackage); pw.print(prefix); pw.print("recentCallingUid="); Loading Loading @@ -1024,7 +1027,17 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN ams.mConstants.SERVICE_BG_ACTIVITY_START_TIMEOUT); } void updateAllowUiJobScheduling(boolean allowUiJobScheduling) { if (mAllowUiJobScheduling == allowUiJobScheduling) { return; } mAllowUiJobScheduling = allowUiJobScheduling; } private void setAllowedBgActivityStartsByStart(BackgroundStartPrivileges newValue) { if (mBackgroundStartPrivilegesByStartMerged == newValue) { return; } mBackgroundStartPrivilegesByStartMerged = newValue; updateParentProcessBgActivityStartsToken(); } Loading Loading
services/core/java/com/android/server/am/ActiveServices.java +22 −1 Original line number Diff line number Diff line Loading @@ -73,6 +73,7 @@ import static android.os.PowerExemptionManager.REASON_SYSTEM_MODULE; import static android.os.PowerExemptionManager.REASON_SYSTEM_UID; import static android.os.PowerExemptionManager.REASON_TEMP_ALLOWED_WHILE_IN_USE; import static android.os.PowerExemptionManager.REASON_UID_VISIBLE; import static android.os.PowerExemptionManager.REASON_UNKNOWN; import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED; import static android.os.PowerExemptionManager.getReasonCodeFromProcState; import static android.os.PowerExemptionManager.reasonCodeToString; Loading Loading @@ -7319,9 +7320,10 @@ public final class ActiveServices { r.mAllowWhileInUsePermissionInFgs = true; } final @ReasonCode int allowWhileInUse; if (!r.mAllowWhileInUsePermissionInFgs || (r.mAllowStartForeground == REASON_DENIED)) { final @ReasonCode int allowWhileInUse = shouldAllowFgsWhileInUsePermissionLocked( allowWhileInUse = shouldAllowFgsWhileInUsePermissionLocked( callingPackage, callingPid, callingUid, r.app, backgroundStartPrivileges, isBindService); if (!r.mAllowWhileInUsePermissionInFgs) { Loading @@ -7332,6 +7334,24 @@ public final class ActiveServices { allowWhileInUse, callingPackage, callingPid, callingUid, intent, r, backgroundStartPrivileges, isBindService); } } else { allowWhileInUse = REASON_UNKNOWN; } // We want to allow scheduling user-initiated jobs when the app is running a // foreground service that was started in the same conditions that allows for scheduling // UI jobs. More explicitly, we want to allow scheduling UI jobs when the app is running // an FGS that started when the app was in the TOP or a BAL-approved state. // As of Android UDC, the conditions required for the while-in-use permissions // are the same conditions that we want, so we piggyback on that logic. // We use that as a shortcut if possible so we don't have to recheck all the conditions. final boolean isFgs = r.isForeground || r.fgRequired; if (isFgs) { r.updateAllowUiJobScheduling(ActivityManagerService .doesReasonCodeAllowSchedulingUserInitiatedJobs(allowWhileInUse) || mAm.canScheduleUserInitiatedJobs( callingUid, callingPid, callingPackage, true)); } else { r.updateAllowUiJobScheduling(false); } } Loading @@ -7342,6 +7362,7 @@ public final class ActiveServices { r.mInfoTempFgsAllowListReason = null; r.mLoggedInfoAllowStartForeground = false; r.mLastSetFgsRestrictionTime = 0; r.updateAllowUiJobScheduling(r.mAllowWhileInUsePermissionInFgs); } boolean canStartForegroundServiceLocked(int callingPid, int callingUid, String callingPackage) { Loading
services/core/java/com/android/server/am/ActivityManagerService.java +17 −2 Original line number Diff line number Diff line Loading @@ -6563,7 +6563,7 @@ public class ActivityManagerService extends IActivityManager.Stub * This is a shortcut and <b>DOES NOT</b> include all reasons. * Use {@link #canScheduleUserInitiatedJobs(int, int, String)} to cover all cases. */ private boolean doesReasonCodeAllowSchedulingUserInitiatedJobs(int reasonCode) { static boolean doesReasonCodeAllowSchedulingUserInitiatedJobs(int reasonCode) { switch (reasonCode) { case REASON_PROC_STATE_PERSISTENT: case REASON_PROC_STATE_PERSISTENT_UI: Loading Loading @@ -6621,6 +6621,16 @@ public class ActivityManagerService extends IActivityManager.Stub } } final ProcessServiceRecord psr = pr.mServices; if (psr != null && psr.hasForegroundServices()) { for (int s = psr.numberOfExecutingServices() - 1; s >= 0; --s) { final ServiceRecord sr = psr.getExecutingServiceAt(s); if (sr.isForeground && sr.mAllowUiJobScheduling) { return true; } } } return false; } Loading @@ -6630,6 +6640,11 @@ public class ActivityManagerService extends IActivityManager.Stub */ // TODO(262260570): log allow reason to an atom private boolean canScheduleUserInitiatedJobs(int uid, int pid, String pkgName) { return canScheduleUserInitiatedJobs(uid, pid, pkgName, false); } boolean canScheduleUserInitiatedJobs(int uid, int pid, String pkgName, boolean skipWhileInUseCheck) { synchronized (this) { final ProcessRecord processRecord; synchronized (mPidsSelfLocked) { Loading Loading @@ -6659,7 +6674,7 @@ public class ActivityManagerService extends IActivityManager.Stub // As of Android UDC, the conditions required to grant a while-in-use permission // covers the majority of those cases, and so we piggyback on that logic as the base. // Missing cases are added after. if (mServices.canAllowWhileInUsePermissionInFgsLocked( if (!skipWhileInUseCheck && mServices.canAllowWhileInUsePermissionInFgsLocked( pid, uid, pkgName, processRecord, backgroundStartPrivileges)) { return true; } Loading
services/core/java/com/android/server/am/ServiceRecord.java +13 −0 Original line number Diff line number Diff line Loading @@ -176,6 +176,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN boolean mAllowWhileInUsePermissionInFgs; // A copy of mAllowWhileInUsePermissionInFgs's value when the service is entering FGS state. boolean mAllowWhileInUsePermissionInFgsAtEntering; /** Allow scheduling user-initiated jobs from the background. */ boolean mAllowUiJobScheduling; // the most recent package that start/bind this service. String mRecentCallingPackage; Loading Loading @@ -607,6 +609,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN } pw.print(prefix); pw.print("allowWhileInUsePermissionInFgs="); pw.println(mAllowWhileInUsePermissionInFgs); pw.print(prefix); pw.print("allowUiJobScheduling="); pw.println(mAllowUiJobScheduling); pw.print(prefix); pw.print("recentCallingPackage="); pw.println(mRecentCallingPackage); pw.print(prefix); pw.print("recentCallingUid="); Loading Loading @@ -1024,7 +1027,17 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN ams.mConstants.SERVICE_BG_ACTIVITY_START_TIMEOUT); } void updateAllowUiJobScheduling(boolean allowUiJobScheduling) { if (mAllowUiJobScheduling == allowUiJobScheduling) { return; } mAllowUiJobScheduling = allowUiJobScheduling; } private void setAllowedBgActivityStartsByStart(BackgroundStartPrivileges newValue) { if (mBackgroundStartPrivilegesByStartMerged == newValue) { return; } mBackgroundStartPrivilegesByStartMerged = newValue; updateParentProcessBgActivityStartsToken(); } Loading