Merge "Remove demotion flags when a JobWorkItem is enqueued." into udc-dev
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 65f496a..3f552b6 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -1503,6 +1503,16 @@
}
toCancel.enqueueWorkLocked(work);
+ if (toCancel.getJob().isUserInitiated()) {
+ // The app is in a state to successfully schedule a UI job. Presumably, the
+ // user has asked for this additional bit of work, so remove any demotion
+ // flags. Only do this for UI jobs since they have strict scheduling
+ // requirements; it's harder to assume other jobs were scheduled due to
+ // user interaction/request.
+ toCancel.removeInternalFlags(
+ JobStatus.INTERNAL_FLAG_DEMOTED_BY_USER
+ | JobStatus.INTERNAL_FLAG_DEMOTED_BY_SYSTEM_UIJ);
+ }
mJobs.touchJob(toCancel);
sEnqueuedJwiHighWaterMarkLogger.logSampleWithUid(uId, toCancel.getWorkCount());
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 6445c3b..b5d763c 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
@@ -1177,6 +1177,10 @@
mInternalFlags |= flags;
}
+ public void removeInternalFlags(int flags) {
+ mInternalFlags = mInternalFlags & ~flags;
+ }
+
int getPreferredConstraintFlags() {
return mPreferredConstraints;
}
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 c040b19..05780eb 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
@@ -582,6 +582,49 @@
}
@Test
+ public void testModifyingInternalFlags() {
+ final JobInfo jobInfo =
+ new JobInfo.Builder(101, new ComponentName("foo", "bar"))
+ .setExpedited(true)
+ .build();
+ JobStatus job = createJobStatus(jobInfo);
+
+ assertEquals(0, job.getInternalFlags());
+
+ // Add single flag
+ job.addInternalFlags(JobStatus.INTERNAL_FLAG_HAS_FOREGROUND_EXEMPTION);
+ assertEquals(JobStatus.INTERNAL_FLAG_HAS_FOREGROUND_EXEMPTION, job.getInternalFlags());
+
+ // Add multiple flags
+ job.addInternalFlags(JobStatus.INTERNAL_FLAG_DEMOTED_BY_USER
+ | JobStatus.INTERNAL_FLAG_DEMOTED_BY_SYSTEM_UIJ);
+ assertEquals(JobStatus.INTERNAL_FLAG_HAS_FOREGROUND_EXEMPTION
+ | JobStatus.INTERNAL_FLAG_DEMOTED_BY_USER
+ | JobStatus.INTERNAL_FLAG_DEMOTED_BY_SYSTEM_UIJ,
+ job.getInternalFlags());
+
+ // Add flag that's already set
+ job.addInternalFlags(JobStatus.INTERNAL_FLAG_DEMOTED_BY_SYSTEM_UIJ);
+ assertEquals(JobStatus.INTERNAL_FLAG_HAS_FOREGROUND_EXEMPTION
+ | JobStatus.INTERNAL_FLAG_DEMOTED_BY_USER
+ | JobStatus.INTERNAL_FLAG_DEMOTED_BY_SYSTEM_UIJ,
+ job.getInternalFlags());
+
+ // Remove multiple
+ job.removeInternalFlags(JobStatus.INTERNAL_FLAG_HAS_FOREGROUND_EXEMPTION
+ | JobStatus.INTERNAL_FLAG_DEMOTED_BY_USER);
+ assertEquals(JobStatus.INTERNAL_FLAG_DEMOTED_BY_SYSTEM_UIJ, job.getInternalFlags());
+
+ // Remove one that isn't set
+ job.removeInternalFlags(JobStatus.INTERNAL_FLAG_DEMOTED_BY_USER);
+ assertEquals(JobStatus.INTERNAL_FLAG_DEMOTED_BY_SYSTEM_UIJ, job.getInternalFlags());
+
+ // Remove final flag.
+ job.removeInternalFlags(JobStatus.INTERNAL_FLAG_DEMOTED_BY_SYSTEM_UIJ);
+ assertEquals(0, job.getInternalFlags());
+ }
+
+ @Test
public void testShouldTreatAsUserInitiated() {
JobInfo jobInfo = new JobInfo.Builder(101, new ComponentName("foo", "bar"))
.setUserInitiated(false)
@@ -619,6 +662,9 @@
rescheduledJob = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME,
0, 0, 0, 0, 0);
assertFalse(rescheduledJob.shouldTreatAsUserInitiatedJob());
+
+ rescheduledJob.removeInternalFlags(JobStatus.INTERNAL_FLAG_DEMOTED_BY_USER);
+ assertTrue(rescheduledJob.shouldTreatAsUserInitiatedJob());
}
@Test
@@ -641,6 +687,9 @@
rescheduledJob = new JobStatus(job, NO_EARLIEST_RUNTIME, NO_LATEST_RUNTIME,
0, 0, 0, 0, 0);
assertFalse(rescheduledJob.shouldTreatAsUserInitiatedJob());
+
+ rescheduledJob.removeInternalFlags(JobStatus.INTERNAL_FLAG_DEMOTED_BY_SYSTEM_UIJ);
+ assertTrue(rescheduledJob.shouldTreatAsUserInitiatedJob());
}
/**