From b5a35e730db32c1a2a6dbda2431fe8b99696831d Mon Sep 17 00:00:00 2001 From: alexbianchi Date: Wed, 10 Aug 2022 18:19:44 +0000 Subject: [PATCH] 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 --- .../server/job/controllers/JobStatus.java | 13 ++- .../server/job/controllers/JobStatusTest.java | 79 ++++++++++++++++++- 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java index 52882fe5d5650..ff19bedcbf208 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java @@ -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) { diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java index f15e60f32fb73..df523fedc917d 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java @@ -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,