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

Commit b5a35e73 authored by alexbianchi's avatar alexbianchi
Browse files

Make Sure wouldBeReady() Works With Flexible Job Constraints

JobStatus.wouldBeReadyWithConstraint() is used by several controllers to
try and prevent unnecessary work, by ignoring the flexibility constraint
we can ensure it continues to provide the right value.

Bug: 238919127

Test: atest frameworks/base/services/tests/mockingservicestests/src/com/android/server/job
Test: atest frameworks/base/services/tests/servicestests/src/com/android/server/job
Test: atest CtsJobSchedulerTestCases
Change-Id: I9ae1565f44ea4ab3ce2e6e3d7be8e67243be12ea
parent ec5edadf
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import android.util.Slog;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.LocalServices;
@@ -1669,7 +1670,8 @@ public final class JobStatus {
        return readinessStatusWithConstraint(constraint, true);
    }

    private boolean readinessStatusWithConstraint(int constraint, boolean value) {
    @VisibleForTesting
    boolean readinessStatusWithConstraint(int constraint, boolean value) {
        boolean oldValue = false;
        int satisfied = mSatisfiedConstraintsOfInterest;
        switch (constraint) {
@@ -1705,6 +1707,15 @@ public final class JobStatus {
                break;
        }

        // The flexibility constraint relies on other constraints to be satisfied.
        // This function lacks the information to determine if flexibility will be satisfied.
        // But for the purposes of this function it is still useful to know the jobs' readiness
        // not including the flexibility constraint. If flexibility is the constraint in question
        // we can proceed as normal.
        if (constraint != CONSTRAINT_FLEXIBLE) {
            satisfied |= CONSTRAINT_FLEXIBLE;
        }

        boolean toReturn = isReady(satisfied);

        switch (constraint) {
+78 −1
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import static com.android.server.job.controllers.JobStatus.CONSTRAINT_CONNECTIVI
import static com.android.server.job.controllers.JobStatus.CONSTRAINT_CONTENT_TRIGGER;
import static com.android.server.job.controllers.JobStatus.CONSTRAINT_DEADLINE;
import static com.android.server.job.controllers.JobStatus.CONSTRAINT_DEVICE_NOT_DOZING;
import static com.android.server.job.controllers.JobStatus.CONSTRAINT_FLEXIBLE;
import static com.android.server.job.controllers.JobStatus.CONSTRAINT_IDLE;
import static com.android.server.job.controllers.JobStatus.CONSTRAINT_STORAGE_NOT_LOW;
import static com.android.server.job.controllers.JobStatus.CONSTRAINT_TIMING_DELAY;
@@ -790,6 +791,83 @@ public class JobStatusTest {
        assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_BACKGROUND_NOT_RESTRICTED));
    }

    @Test
    public void testWouldBeReadyWithConstraint_FlexibilityDoesNotAffectReadiness() {
        final JobStatus job = createJobStatus(
                new JobInfo.Builder(101, new ComponentName("foo", "bar")).build());

        markImplicitConstraintsSatisfied(job, false);
        job.setFlexibilityConstraintSatisfied(0, false);
        assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING));
        assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_IDLE));
        assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_BATTERY_NOT_LOW));
        assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_STORAGE_NOT_LOW));
        assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_TIMING_DELAY));
        assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_DEADLINE));
        assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONNECTIVITY));
        assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER));
        assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_FLEXIBLE));

        markImplicitConstraintsSatisfied(job, true);
        job.setFlexibilityConstraintSatisfied(0, false);
        assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING));
        assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_IDLE));
        assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_BATTERY_NOT_LOW));
        assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_STORAGE_NOT_LOW));
        assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_TIMING_DELAY));
        assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_DEADLINE));
        assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CONNECTIVITY));
        assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER));
        assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_FLEXIBLE));

        markImplicitConstraintsSatisfied(job, false);
        job.setFlexibilityConstraintSatisfied(0, true);
        assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING));
        assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_IDLE));
        assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_BATTERY_NOT_LOW));
        assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_STORAGE_NOT_LOW));
        assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_TIMING_DELAY));
        assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_DEADLINE));
        assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONNECTIVITY));
        assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER));
        assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_FLEXIBLE));

        markImplicitConstraintsSatisfied(job, true);
        job.setFlexibilityConstraintSatisfied(0, true);
        assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING));
        assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_IDLE));
        assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_BATTERY_NOT_LOW));
        assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_STORAGE_NOT_LOW));
        assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_TIMING_DELAY));
        assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_DEADLINE));
        assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CONNECTIVITY));
        assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER));
        assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_FLEXIBLE));
    }

    @Test
    public void testReadinessStatusWithConstraint_FlexibilityConstraint() {
        final JobStatus job = createJobStatus(
                new JobInfo.Builder(101, new ComponentName("foo", "bar")).build());
        job.setConstraintSatisfied(CONSTRAINT_FLEXIBLE, sElapsedRealtimeClock.millis(), false);
        markImplicitConstraintsSatisfied(job, true);
        assertTrue(job.readinessStatusWithConstraint(CONSTRAINT_FLEXIBLE, true));
        assertFalse(job.readinessStatusWithConstraint(CONSTRAINT_FLEXIBLE, false));

        markImplicitConstraintsSatisfied(job, false);
        assertFalse(job.readinessStatusWithConstraint(CONSTRAINT_FLEXIBLE, true));
        assertFalse(job.readinessStatusWithConstraint(CONSTRAINT_FLEXIBLE, false));

        job.setConstraintSatisfied(CONSTRAINT_FLEXIBLE, sElapsedRealtimeClock.millis(), true);
        markImplicitConstraintsSatisfied(job, true);
        assertTrue(job.readinessStatusWithConstraint(CONSTRAINT_FLEXIBLE, true));
        assertFalse(job.readinessStatusWithConstraint(CONSTRAINT_FLEXIBLE, false));

        markImplicitConstraintsSatisfied(job, false);
        assertFalse(job.readinessStatusWithConstraint(CONSTRAINT_FLEXIBLE, true));
        assertFalse(job.readinessStatusWithConstraint(CONSTRAINT_FLEXIBLE, false));
    }

    private void markImplicitConstraintsSatisfied(JobStatus job, boolean isSatisfied) {
        job.setQuotaConstraintSatisfied(sElapsedRealtimeClock.millis(), isSatisfied);
        job.setTareWealthConstraintSatisfied(sElapsedRealtimeClock.millis(), isSatisfied);
@@ -797,7 +875,6 @@ public class JobStatusTest {
                sElapsedRealtimeClock.millis(), isSatisfied, false);
        job.setBackgroundNotRestrictedConstraintSatisfied(
                sElapsedRealtimeClock.millis(), isSatisfied, false);
        job.setFlexibilityConstraintSatisfied(sElapsedRealtimeClock.millis(), isSatisfied);
    }

    private static JobStatus createJobStatus(long earliestRunTimeElapsedMillis,