Loading apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +6 −3 Original line number Diff line number Diff line Loading @@ -1978,9 +1978,12 @@ public class JobSchedulerService extends com.android.server.SystemService JobStatus runNow = (JobStatus) message.obj; // runNow can be null, which is a controller's way of indicating that its // state is such that all ready jobs should be run immediately. if (runNow != null && isReadyToBeExecutedLocked(runNow)) { if (runNow != null) { if (!isCurrentlyActiveLocked(runNow) && isReadyToBeExecutedLocked(runNow)) { mJobPackageTracker.notePending(runNow); addOrderedItem(mPendingJobs, runNow, sPendingJobComparator); } } else { queueReadyJobsForExecutionLocked(); } Loading apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java +15 −19 Original line number Diff line number Diff line Loading @@ -157,31 +157,27 @@ public final class TimeController extends StateController { && !job.isConstraintSatisfied(JobStatus.CONSTRAINT_DEADLINE) && job.getLatestRunTimeElapsed() <= mNextJobExpiredElapsedMillis) { if (evaluateDeadlineConstraint(job, nowElapsedMillis)) { checkExpiredDeadlinesAndResetAlarm(); checkExpiredDelaysAndResetAlarm(); } else { final boolean isAlarmForJob = job.getLatestRunTimeElapsed() == mNextJobExpiredElapsedMillis; final boolean wouldBeReady = wouldBeReadyWithConstraintLocked( job, JobStatus.CONSTRAINT_DEADLINE); if ((isAlarmForJob && !wouldBeReady) || (!isAlarmForJob && wouldBeReady)) { checkExpiredDeadlinesAndResetAlarm(); if (job.isReady()) { // If the job still isn't ready, there's no point trying to rush the // Scheduler. mStateChangedListener.onRunJobNow(job); } } else if (wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_DEADLINE)) { // This job's deadline is earlier than the current set alarm. Update the alarm. setDeadlineExpiredAlarmLocked(job.getLatestRunTimeElapsed(), deriveWorkSource(job.getSourceUid(), job.getSourcePackageName())); } } if (job.hasTimingDelayConstraint() && !job.isConstraintSatisfied(JobStatus.CONSTRAINT_TIMING_DELAY) && job.getEarliestRunTime() <= mNextDelayExpiredElapsedMillis) { if (evaluateTimingDelayConstraint(job, nowElapsedMillis)) { checkExpiredDelaysAndResetAlarm(); } else { final boolean isAlarmForJob = job.getEarliestRunTime() == mNextDelayExpiredElapsedMillis; final boolean wouldBeReady = wouldBeReadyWithConstraintLocked( job, JobStatus.CONSTRAINT_TIMING_DELAY); if ((isAlarmForJob && !wouldBeReady) || (!isAlarmForJob && wouldBeReady)) { checkExpiredDelaysAndResetAlarm(); } // Since this is just the delay, we don't need to rush the Scheduler to run the job // immediately if the constraint is satisfied here. if (!evaluateTimingDelayConstraint(job, nowElapsedMillis) && wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_TIMING_DELAY)) { // This job's delay is earlier than the current set alarm. Update the alarm. setDelayExpiredAlarmLocked(job.getEarliestRunTime(), deriveWorkSource(job.getSourceUid(), job.getSourcePackageName())); } } } Loading services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java +25 −12 Original line number Diff line number Diff line Loading @@ -711,25 +711,31 @@ public class TimeControllerTest { .set(anyInt(), anyLong(), anyLong(), anyLong(), anyString(), any(), any(), any()); // Test evaluating something before the current deadline. doReturn(false).when(mTimeController) .wouldBeReadyWithConstraintLocked(eq(jobEarliest), anyInt()); mTimeController.evaluateStateLocked(jobEarliest); inOrder.verify(mAlarmManager, never()) .set(anyInt(), anyLong(), anyLong(), anyLong(), eq(TAG_DELAY), any(), any(), any()); doReturn(true).when(mTimeController) .wouldBeReadyWithConstraintLocked(eq(jobEarliest), anyInt()); mTimeController.evaluateStateLocked(jobEarliest); inOrder.verify(mAlarmManager, times(1)) .set(anyInt(), eq(now + 5 * MINUTE_IN_MILLIS), anyLong(), anyLong(), eq(TAG_DELAY), any(), any(), any()); // Job goes back to not being ready. Middle is still true, so use that alarm. // Job goes back to not being ready. Middle is still true, but we don't check and actively // defer alarm. doReturn(false).when(mTimeController) .wouldBeReadyWithConstraintLocked(eq(jobEarliest), anyInt()); mTimeController.evaluateStateLocked(jobEarliest); inOrder.verify(mAlarmManager, times(1)) .set(anyInt(), eq(now + 30 * MINUTE_IN_MILLIS), anyLong(), anyLong(), inOrder.verify(mAlarmManager, never()) .set(anyInt(), anyLong(), anyLong(), anyLong(), eq(TAG_DELAY), any(), any(), any()); // Turn middle off. Latest is true, so use that alarm. // Turn middle off. Latest is true, but we don't check and actively defer alarm. doReturn(false).when(mTimeController) .wouldBeReadyWithConstraintLocked(eq(jobMiddle), anyInt()); mTimeController.evaluateStateLocked(jobMiddle); inOrder.verify(mAlarmManager, times(1)) .set(anyInt(), eq(now + HOUR_IN_MILLIS), anyLong(), anyLong(), inOrder.verify(mAlarmManager, never()) .set(anyInt(), anyLong(), anyLong(), anyLong(), eq(TAG_DELAY), any(), any(), any()); } Loading Loading @@ -768,25 +774,32 @@ public class TimeControllerTest { .set(anyInt(), anyLong(), anyLong(), anyLong(), anyString(), any(), any(), any()); // Test evaluating something before the current deadline. doReturn(false).when(mTimeController) .wouldBeReadyWithConstraintLocked(eq(jobEarliest), anyInt()); mTimeController.evaluateStateLocked(jobEarliest); inOrder.verify(mAlarmManager, never()) .set(anyInt(), anyLong(), anyLong(), anyLong(), eq(TAG_DEADLINE), any(), any(), any()); doReturn(true).when(mTimeController) .wouldBeReadyWithConstraintLocked(eq(jobEarliest), anyInt()); mTimeController.evaluateStateLocked(jobEarliest); inOrder.verify(mAlarmManager, times(1)) .set(anyInt(), eq(now + 5 * MINUTE_IN_MILLIS), anyLong(), anyLong(), eq(TAG_DEADLINE), any(), any(), any()); // Job goes back to not being ready. Middle is still true, so use that alarm. // Job goes back to not being ready. Middle is still true, but we don't check and actively // defer alarm. doReturn(false).when(mTimeController) .wouldBeReadyWithConstraintLocked(eq(jobEarliest), anyInt()); mTimeController.evaluateStateLocked(jobEarliest); inOrder.verify(mAlarmManager, times(1)) .set(anyInt(), eq(now + 30 * MINUTE_IN_MILLIS), anyLong(), anyLong(), inOrder.verify(mAlarmManager, never()) .set(anyInt(), anyLong(), anyLong(), anyLong(), eq(TAG_DEADLINE), any(), any(), any()); // Turn middle off. Latest is true, so use that alarm. // Turn middle off. Latest is true, but we don't check and actively defer alarm. doReturn(false).when(mTimeController) .wouldBeReadyWithConstraintLocked(eq(jobMiddle), anyInt()); mTimeController.evaluateStateLocked(jobMiddle); inOrder.verify(mAlarmManager, times(1)) .set(anyInt(), eq(now + HOUR_IN_MILLIS), anyLong(), anyLong(), inOrder.verify(mAlarmManager, never()) .set(anyInt(), anyLong(), anyLong(), anyLong(), eq(TAG_DEADLINE), any(), any(), any()); } } Loading
apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +6 −3 Original line number Diff line number Diff line Loading @@ -1978,9 +1978,12 @@ public class JobSchedulerService extends com.android.server.SystemService JobStatus runNow = (JobStatus) message.obj; // runNow can be null, which is a controller's way of indicating that its // state is such that all ready jobs should be run immediately. if (runNow != null && isReadyToBeExecutedLocked(runNow)) { if (runNow != null) { if (!isCurrentlyActiveLocked(runNow) && isReadyToBeExecutedLocked(runNow)) { mJobPackageTracker.notePending(runNow); addOrderedItem(mPendingJobs, runNow, sPendingJobComparator); } } else { queueReadyJobsForExecutionLocked(); } Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java +15 −19 Original line number Diff line number Diff line Loading @@ -157,31 +157,27 @@ public final class TimeController extends StateController { && !job.isConstraintSatisfied(JobStatus.CONSTRAINT_DEADLINE) && job.getLatestRunTimeElapsed() <= mNextJobExpiredElapsedMillis) { if (evaluateDeadlineConstraint(job, nowElapsedMillis)) { checkExpiredDeadlinesAndResetAlarm(); checkExpiredDelaysAndResetAlarm(); } else { final boolean isAlarmForJob = job.getLatestRunTimeElapsed() == mNextJobExpiredElapsedMillis; final boolean wouldBeReady = wouldBeReadyWithConstraintLocked( job, JobStatus.CONSTRAINT_DEADLINE); if ((isAlarmForJob && !wouldBeReady) || (!isAlarmForJob && wouldBeReady)) { checkExpiredDeadlinesAndResetAlarm(); if (job.isReady()) { // If the job still isn't ready, there's no point trying to rush the // Scheduler. mStateChangedListener.onRunJobNow(job); } } else if (wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_DEADLINE)) { // This job's deadline is earlier than the current set alarm. Update the alarm. setDeadlineExpiredAlarmLocked(job.getLatestRunTimeElapsed(), deriveWorkSource(job.getSourceUid(), job.getSourcePackageName())); } } if (job.hasTimingDelayConstraint() && !job.isConstraintSatisfied(JobStatus.CONSTRAINT_TIMING_DELAY) && job.getEarliestRunTime() <= mNextDelayExpiredElapsedMillis) { if (evaluateTimingDelayConstraint(job, nowElapsedMillis)) { checkExpiredDelaysAndResetAlarm(); } else { final boolean isAlarmForJob = job.getEarliestRunTime() == mNextDelayExpiredElapsedMillis; final boolean wouldBeReady = wouldBeReadyWithConstraintLocked( job, JobStatus.CONSTRAINT_TIMING_DELAY); if ((isAlarmForJob && !wouldBeReady) || (!isAlarmForJob && wouldBeReady)) { checkExpiredDelaysAndResetAlarm(); } // Since this is just the delay, we don't need to rush the Scheduler to run the job // immediately if the constraint is satisfied here. if (!evaluateTimingDelayConstraint(job, nowElapsedMillis) && wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_TIMING_DELAY)) { // This job's delay is earlier than the current set alarm. Update the alarm. setDelayExpiredAlarmLocked(job.getEarliestRunTime(), deriveWorkSource(job.getSourceUid(), job.getSourcePackageName())); } } } Loading
services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java +25 −12 Original line number Diff line number Diff line Loading @@ -711,25 +711,31 @@ public class TimeControllerTest { .set(anyInt(), anyLong(), anyLong(), anyLong(), anyString(), any(), any(), any()); // Test evaluating something before the current deadline. doReturn(false).when(mTimeController) .wouldBeReadyWithConstraintLocked(eq(jobEarliest), anyInt()); mTimeController.evaluateStateLocked(jobEarliest); inOrder.verify(mAlarmManager, never()) .set(anyInt(), anyLong(), anyLong(), anyLong(), eq(TAG_DELAY), any(), any(), any()); doReturn(true).when(mTimeController) .wouldBeReadyWithConstraintLocked(eq(jobEarliest), anyInt()); mTimeController.evaluateStateLocked(jobEarliest); inOrder.verify(mAlarmManager, times(1)) .set(anyInt(), eq(now + 5 * MINUTE_IN_MILLIS), anyLong(), anyLong(), eq(TAG_DELAY), any(), any(), any()); // Job goes back to not being ready. Middle is still true, so use that alarm. // Job goes back to not being ready. Middle is still true, but we don't check and actively // defer alarm. doReturn(false).when(mTimeController) .wouldBeReadyWithConstraintLocked(eq(jobEarliest), anyInt()); mTimeController.evaluateStateLocked(jobEarliest); inOrder.verify(mAlarmManager, times(1)) .set(anyInt(), eq(now + 30 * MINUTE_IN_MILLIS), anyLong(), anyLong(), inOrder.verify(mAlarmManager, never()) .set(anyInt(), anyLong(), anyLong(), anyLong(), eq(TAG_DELAY), any(), any(), any()); // Turn middle off. Latest is true, so use that alarm. // Turn middle off. Latest is true, but we don't check and actively defer alarm. doReturn(false).when(mTimeController) .wouldBeReadyWithConstraintLocked(eq(jobMiddle), anyInt()); mTimeController.evaluateStateLocked(jobMiddle); inOrder.verify(mAlarmManager, times(1)) .set(anyInt(), eq(now + HOUR_IN_MILLIS), anyLong(), anyLong(), inOrder.verify(mAlarmManager, never()) .set(anyInt(), anyLong(), anyLong(), anyLong(), eq(TAG_DELAY), any(), any(), any()); } Loading Loading @@ -768,25 +774,32 @@ public class TimeControllerTest { .set(anyInt(), anyLong(), anyLong(), anyLong(), anyString(), any(), any(), any()); // Test evaluating something before the current deadline. doReturn(false).when(mTimeController) .wouldBeReadyWithConstraintLocked(eq(jobEarliest), anyInt()); mTimeController.evaluateStateLocked(jobEarliest); inOrder.verify(mAlarmManager, never()) .set(anyInt(), anyLong(), anyLong(), anyLong(), eq(TAG_DEADLINE), any(), any(), any()); doReturn(true).when(mTimeController) .wouldBeReadyWithConstraintLocked(eq(jobEarliest), anyInt()); mTimeController.evaluateStateLocked(jobEarliest); inOrder.verify(mAlarmManager, times(1)) .set(anyInt(), eq(now + 5 * MINUTE_IN_MILLIS), anyLong(), anyLong(), eq(TAG_DEADLINE), any(), any(), any()); // Job goes back to not being ready. Middle is still true, so use that alarm. // Job goes back to not being ready. Middle is still true, but we don't check and actively // defer alarm. doReturn(false).when(mTimeController) .wouldBeReadyWithConstraintLocked(eq(jobEarliest), anyInt()); mTimeController.evaluateStateLocked(jobEarliest); inOrder.verify(mAlarmManager, times(1)) .set(anyInt(), eq(now + 30 * MINUTE_IN_MILLIS), anyLong(), anyLong(), inOrder.verify(mAlarmManager, never()) .set(anyInt(), anyLong(), anyLong(), anyLong(), eq(TAG_DEADLINE), any(), any(), any()); // Turn middle off. Latest is true, so use that alarm. // Turn middle off. Latest is true, but we don't check and actively defer alarm. doReturn(false).when(mTimeController) .wouldBeReadyWithConstraintLocked(eq(jobMiddle), anyInt()); mTimeController.evaluateStateLocked(jobMiddle); inOrder.verify(mAlarmManager, times(1)) .set(anyInt(), eq(now + HOUR_IN_MILLIS), anyLong(), anyLong(), inOrder.verify(mAlarmManager, never()) .set(anyInt(), anyLong(), anyLong(), anyLong(), eq(TAG_DEADLINE), any(), any(), any()); } }