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