Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 514337c7 authored by Kweku Adams's avatar Kweku Adams
Browse files

Fix Doze FGS job handling.

While in Doze, jobs of apps the Foreground Service proc state or higher
are only exempted if they're expedited or have the
important-while-foreground bit set. We were accidentally considering all
uidActive jobs as exempt, letting the device exit the Doze maintenance
window early, and then stopping the uidActive app's jobs if they weren't
exempted or had the important-while-foreground bit set. This meant that
if only the app running a foreground service had jobs to run and the app
didn't ask for the jobs to be exempted from Doze, the maintenance window
would last for 30 seconds and the jobs would be stopped, but if there
were other background jobs to be run, the maintenance window could last
for the full time (10 minutes or whatever it would be). Fixing the
inconsistency so that we don't exit a maintenance window early when
there are non-exempt jobs running.

Bug: 216150579
Test: atest frameworks/base/services/tests/servicestests/src/com/android/server/job
Test: atest frameworks/base/services/tests/mockingservicestests/src/com/android/server/job
Test: atest CtsJobSchedulerTestCases
Change-Id: I07de57b364c9fee995eca020153622ba85d17c96
parent 8b22e7b7
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -1633,12 +1633,9 @@ public class JobSchedulerService extends com.android.server.SystemService
            for (int i=0; i<mActiveServices.size(); i++) {
                final JobServiceContext jsc = mActiveServices.get(i);
                final JobStatus job = jsc.getRunningJobLocked();
                if (job != null
                        && !job.canRunInDoze()
                        && !job.dozeWhitelisted
                        && !job.uidActive) {
                    // We will report active if we have a job running and it is not an exception
                    // due to being in the foreground or whitelisted.
                if (job != null && !job.canRunInDoze()) {
                    // We will report active if we have a job running and it does not have an
                    // exception that allows it to run in Doze.
                    active = true;
                    break;
                }
+2 −2
Original line number Diff line number Diff line
@@ -246,7 +246,7 @@ public final class DeviceIdleJobsController extends StateController {
            pw.print((jobStatus.satisfiedConstraints
                    & JobStatus.CONSTRAINT_DEVICE_NOT_DOZING) != 0
                            ? " RUNNABLE" : " WAITING");
            if (jobStatus.dozeWhitelisted) {
            if (jobStatus.appHasDozeExemption) {
                pw.print(" WHITELISTED");
            }
            if (mAllowInIdleJobs.contains(jobStatus)) {
@@ -273,7 +273,7 @@ public final class DeviceIdleJobsController extends StateController {
            proto.write(TrackedJob.SOURCE_PACKAGE_NAME, jobStatus.getSourcePackageName());
            proto.write(TrackedJob.ARE_CONSTRAINTS_SATISFIED,
                    (jobStatus.satisfiedConstraints & JobStatus.CONSTRAINT_DEVICE_NOT_DOZING) != 0);
            proto.write(TrackedJob.IS_DOZE_WHITELISTED, jobStatus.dozeWhitelisted);
            proto.write(TrackedJob.IS_DOZE_WHITELISTED, jobStatus.appHasDozeExemption);
            proto.write(TrackedJob.IS_ALLOWED_IN_DOZE, mAllowInIdleJobs.contains(jobStatus));

            proto.end(jsToken);
+6 −5
Original line number Diff line number Diff line
@@ -267,7 +267,7 @@ public final class JobStatus {
    private final boolean mHasMediaBackupExemption;

    // Set to true if doze constraint was satisfied due to app being whitelisted.
    public boolean dozeWhitelisted;
    boolean appHasDozeExemption;

    // Set to true when the app is "active" per AppStateTracker
    public boolean uidActive;
@@ -1179,7 +1179,8 @@ public final class JobStatus {
     * in Doze.
     */
    public boolean canRunInDoze() {
        return (getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0
        return appHasDozeExemption
                || (getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0
                || ((shouldTreatAsExpeditedJob() || startedAsExpeditedJob)
                && (mDynamicConstraints & CONSTRAINT_DEVICE_NOT_DOZING) == 0);
    }
@@ -1243,7 +1244,7 @@ public final class JobStatus {
    /** @return true if the constraint was changed, false otherwise. */
    boolean setDeviceNotDozingConstraintSatisfied(final long nowElapsed,
            boolean state, boolean whitelisted) {
        dozeWhitelisted = whitelisted;
        appHasDozeExemption = whitelisted;
        if (setConstraintSatisfied(CONSTRAINT_DEVICE_NOT_DOZING, nowElapsed, state)) {
            // The constraint was changed. Update the ready flag.
            mReadyNotDozing = state || canRunInDoze();
@@ -2110,7 +2111,7 @@ public final class JobStatus {
            }
            pw.decreaseIndent();

            if (dozeWhitelisted) {
            if (appHasDozeExemption) {
                pw.println("Doze whitelisted: true");
            }
            if (uidActive) {
@@ -2323,7 +2324,7 @@ public final class JobStatus {
            dumpConstraints(proto, JobStatusDumpProto.SATISFIED_CONSTRAINTS, satisfiedConstraints);
            dumpConstraints(proto, JobStatusDumpProto.UNSATISFIED_CONSTRAINTS,
                    ((requiredConstraints | CONSTRAINT_WITHIN_QUOTA) & ~satisfiedConstraints));
            proto.write(JobStatusDumpProto.IS_DOZE_WHITELISTED, dozeWhitelisted);
            proto.write(JobStatusDumpProto.IS_DOZE_WHITELISTED, appHasDozeExemption);
            proto.write(JobStatusDumpProto.IS_UID_ACTIVE, uidActive);
            proto.write(JobStatusDumpProto.IS_EXEMPTED_FROM_APP_STANDBY,
                    job.isExemptedFromAppStandby());