Merge "Fix allow-UIJ-scheduling determination." into udc-dev

This commit is contained in:
Treehugger Robot
2023-04-12 16:19:11 +00:00
committed by Android (Google) Code Review
3 changed files with 28 additions and 25 deletions

View File

@@ -1019,6 +1019,24 @@ public final class ActiveServices {
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
service, neededGrants, callingUid, callingProcessName, callingPackage));
// 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.
final boolean isFgs = r.isForeground || r.fgRequired;
if (isFgs) {
// 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.
// Use that as a shortcut if possible to avoid having to recheck all the conditions.
final boolean whileInUseAllowsUiJobScheduling =
ActivityManagerService.doesReasonCodeAllowSchedulingUserInitiatedJobs(
r.mAllowWhileInUsePermissionInFgsReason);
r.updateAllowUiJobScheduling(whileInUseAllowsUiJobScheduling
|| mAm.canScheduleUserInitiatedJobs(callingUid, callingPid, callingPackage));
} else {
r.updateAllowUiJobScheduling(false);
}
if (fgRequired) {
// We are now effectively running a foreground service.
synchronized (mAm.mProcessStats.mLock) {
@@ -7362,26 +7380,12 @@ public final class ActiveServices {
} 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);
}
r.mAllowWhileInUsePermissionInFgsReason = allowWhileInUse;
}
void resetFgsRestrictionLocked(ServiceRecord r) {
r.mAllowWhileInUsePermissionInFgs = false;
r.mAllowWhileInUsePermissionInFgsReason = REASON_DENIED;
r.mAllowStartForeground = REASON_DENIED;
r.mInfoAllowStartForeground = null;
r.mInfoTempFgsAllowListReason = null;

View File

@@ -6189,8 +6189,8 @@ 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);
for (int s = psr.numberOfRunningServices() - 1; s >= 0; --s) {
final ServiceRecord sr = psr.getRunningServiceAt(s);
if (sr.isForeground && sr.mAllowUiJobScheduling) {
return true;
}
@@ -6205,12 +6205,7 @@ public class ActivityManagerService extends IActivityManager.Stub
* {@link android.app.job.JobInfo.Builder#setUserInitiated(boolean) user-initiated job}.
*/
// 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) {
boolean canScheduleUserInitiatedJobs(int uid, int pid, String pkgName) {
synchronized (this) {
final ProcessRecord processRecord;
synchronized (mPidsSelfLocked) {
@@ -6240,7 +6235,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 (!skipWhileInUseCheck && mServices.canAllowWhileInUsePermissionInFgsLocked(
if (mServices.canAllowWhileInUsePermissionInFgsLocked(
pid, uid, pkgName, processRecord, backgroundStartPrivileges)) {
return true;
}

View File

@@ -174,6 +174,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
// allow while-in-use permissions in foreground service or not.
// while-in-use permissions in FGS started from background might be restricted.
boolean mAllowWhileInUsePermissionInFgs;
@PowerExemptionManager.ReasonCode
int mAllowWhileInUsePermissionInFgsReason;
// A copy of mAllowWhileInUsePermissionInFgs's value when the service is entering FGS state.
boolean mAllowWhileInUsePermissionInFgsAtEntering;
/** Allow scheduling user-initiated jobs from the background. */
@@ -609,6 +611,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
}
pw.print(prefix); pw.print("allowWhileInUsePermissionInFgs=");
pw.println(mAllowWhileInUsePermissionInFgs);
pw.print(prefix); pw.print("mAllowWhileInUsePermissionInFgsReason=");
pw.println(mAllowWhileInUsePermissionInFgsReason);
pw.print(prefix); pw.print("allowUiJobScheduling="); pw.println(mAllowUiJobScheduling);
pw.print(prefix); pw.print("recentCallingPackage=");
pw.println(mRecentCallingPackage);