diff --git a/apex/jobscheduler/service/java/com/android/server/job/PendingJobQueue.java b/apex/jobscheduler/service/java/com/android/server/job/PendingJobQueue.java index 0a305a2633639..4f4096f69ad5e 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/PendingJobQueue.java +++ b/apex/jobscheduler/service/java/com/android/server/job/PendingJobQueue.java @@ -219,6 +219,8 @@ class PendingJobQueue { ajq.clear(); mAppJobQueuePool.release(ajq); } else if (prevTimestamp != ajq.peekNextTimestamp()) { + // Removing the job changed the "next timestamp" in the queue, so we need to reinsert + // it to fix the ordering. mOrderedQueues.remove(ajq); mOrderedQueues.offer(ajq); } diff --git a/services/tests/servicestests/src/com/android/server/job/PendingJobQueueTest.java b/services/tests/servicestests/src/com/android/server/job/PendingJobQueueTest.java index 8c3838b939ece..23d708227e4f2 100644 --- a/services/tests/servicestests/src/com/android/server/job/PendingJobQueueTest.java +++ b/services/tests/servicestests/src/com/android/server/job/PendingJobQueueTest.java @@ -201,6 +201,32 @@ public class PendingJobQueueTest { } } assertNull(jobQueue.next()); + assertEquals(0, jobQueue.size()); + } + + @Test + public void testRemove_duringIteration() { + List jobs = new ArrayList<>(); + jobs.add(createJobStatus("testRemove", createJobInfo(1), 1)); + jobs.add(createJobStatus("testRemove", createJobInfo(2), 2)); + jobs.add(createJobStatus("testRemove", createJobInfo(3).setExpedited(true), 3)); + jobs.add(createJobStatus("testRemove", createJobInfo(4), 4)); + jobs.add(createJobStatus("testRemove", createJobInfo(5).setExpedited(true), 5)); + + PendingJobQueue jobQueue = new PendingJobQueue(); + jobQueue.addAll(jobs); + + ArraySet removed = new ArraySet<>(); + JobStatus job; + jobQueue.resetIterator(); + while ((job = jobQueue.next()) != null) { + jobQueue.remove(job); + removed.add(job); + assertFalse("Queue retained a removed job " + testJobToString(job), + jobQueue.contains(job)); + } + assertNull(jobQueue.next()); + assertEquals(0, jobQueue.size()); } @Test