Check readiness of override-scheduled jobs.

Check the readiness of any jobs that were scheduled to override an
already running job once the running job has finished so that we can run
the new job immediately if it's ready.

Bug: 179818651
Test: atest CtsJobSchedulerTestCases
Change-Id: I86036e96964cc1786d25139ecd5e145165ce01c7
This commit is contained in:
Kweku Adams
2021-02-10 15:58:00 -08:00
parent 8fddb7a431
commit 9f9fe8efb5
2 changed files with 20 additions and 17 deletions

View File

@@ -212,7 +212,7 @@ public class JobSchedulerService extends com.android.server.SystemService
final JobPackageTracker mJobPackageTracker = new JobPackageTracker();
final JobConcurrencyManager mConcurrencyManager;
static final int MSG_JOB_EXPIRED = 0;
static final int MSG_CHECK_INDIVIDUAL_JOB = 0;
static final int MSG_CHECK_JOB = 1;
static final int MSG_STOP_JOB = 2;
static final int MSG_CHECK_JOB_GREEDY = 3;
@@ -1711,6 +1711,12 @@ public class JobSchedulerService extends com.android.server.SystemService
if (DEBUG) {
Slog.d(TAG, "Could not find job to remove. Was job removed while executing?");
}
JobStatus newJs = mJobs.getJobByUidAndJobId(jobStatus.getUid(), jobStatus.getJobId());
if (newJs != null) {
// This job was stopped because the app scheduled a new job with the same job ID.
// Check if the new job is ready to run.
mHandler.obtainMessage(MSG_CHECK_INDIVIDUAL_JOB, newJs).sendToTarget();
}
return;
}
@@ -1748,7 +1754,11 @@ public class JobSchedulerService extends com.android.server.SystemService
@Override
public void onRunJobNow(JobStatus jobStatus) {
mHandler.obtainMessage(MSG_JOB_EXPIRED, jobStatus).sendToTarget();
if (jobStatus == null) {
mHandler.obtainMessage(MSG_CHECK_JOB_GREEDY).sendToTarget();
} else {
mHandler.obtainMessage(MSG_CHECK_INDIVIDUAL_JOB, jobStatus).sendToTarget();
}
}
final private class JobHandler extends Handler {
@@ -1764,18 +1774,15 @@ public class JobSchedulerService extends com.android.server.SystemService
return;
}
switch (message.what) {
case MSG_JOB_EXPIRED: {
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) {
if (!isCurrentlyActiveLocked(runNow)
&& isReadyToBeExecutedLocked(runNow)) {
mJobPackageTracker.notePending(runNow);
addOrderedItem(mPendingJobs, runNow, sPendingJobComparator);
case MSG_CHECK_INDIVIDUAL_JOB: {
JobStatus js = (JobStatus) message.obj;
if (js != null) {
if (isReadyToBeExecutedLocked(js)) {
mJobPackageTracker.notePending(js);
addOrderedItem(mPendingJobs, js, sPendingJobComparator);
}
} else {
queueReadyJobsForExecutionLocked();
Slog.e(TAG, "Given null job to check individually");
}
} break;
case MSG_CHECK_JOB:
@@ -1909,12 +1916,10 @@ public class JobSchedulerService extends com.android.server.SystemService
// This method will check and capture all ready jobs, so we don't need to keep any messages
// in the queue.
mHandler.removeMessages(MSG_CHECK_JOB_GREEDY);
mHandler.removeMessages(MSG_CHECK_INDIVIDUAL_JOB);
// MSG_CHECK_JOB is a weaker form of _GREEDY. Since we're checking and queueing all ready
// jobs, we don't need to keep any MSG_CHECK_JOB messages in the queue.
mHandler.removeMessages(MSG_CHECK_JOB);
// This method will capture all expired jobs that are ready, so there's no need to keep
// the _EXPIRED messages in the queue.
mHandler.removeMessages(MSG_JOB_EXPIRED);
if (DEBUG) {
Slog.d(TAG, "queuing all ready jobs for execution:");
}

View File

@@ -107,8 +107,6 @@ public final class ContentObserverController extends StateController {
taskStatus.contentObserverJobInstance.mChangedUris.add(uri);
}
}
taskStatus.changedAuthorities = null;
taskStatus.changedUris = null;
}
taskStatus.changedAuthorities = null;
taskStatus.changedUris = null;