Merge "More small fixes/adjustments to job scheduler." into oc-dev

This commit is contained in:
TreeHugger Robot
2017-04-18 00:47:02 +00:00
committed by Android (Google) Code Review
7 changed files with 46 additions and 20 deletions

View File

@@ -6890,7 +6890,7 @@ package android.app.job {
}
public abstract class JobServiceEngine {
ctor public JobServiceEngine(android.content.Context);
ctor public JobServiceEngine(android.app.Service);
method public final android.os.IBinder getBinder();
method public final void jobFinished(android.app.job.JobParameters, boolean);
method public abstract boolean onStartJob(android.app.job.JobParameters);

View File

@@ -7326,7 +7326,7 @@ package android.app.job {
}
public abstract class JobServiceEngine {
ctor public JobServiceEngine(android.content.Context);
ctor public JobServiceEngine(android.app.Service);
method public final android.os.IBinder getBinder();
method public final void jobFinished(android.app.job.JobParameters, boolean);
method public abstract boolean onStartJob(android.app.job.JobParameters);

View File

@@ -6920,7 +6920,7 @@ package android.app.job {
}
public abstract class JobServiceEngine {
ctor public JobServiceEngine(android.content.Context);
ctor public JobServiceEngine(android.app.Service);
method public final android.os.IBinder getBinder();
method public final void jobFinished(android.app.job.JobParameters, boolean);
method public abstract boolean onStartJob(android.app.job.JobParameters);

View File

@@ -164,6 +164,20 @@ public class JobParameters implements Parcelable {
* you should not call {@link JobService#jobFinished(JobParameters, boolean)} yourself
* (otherwise you risk losing an upcoming JobWorkItem that is being enqueued at the same time).
*
* <p>Once you are done with the {@link JobWorkItem} returned by this method, you must call
* {@link #completeWork(JobWorkItem)} with it to inform the system that you are done
* executing the work. The job will not be finished until all dequeued work has been
* completed. You do not, however, have to complete each returned work item before deqeueing
* the next one -- you can use {@link #dequeueWork()} multiple times before completing
* previous work if you want to process work in parallel, and you can complete the work
* in whatever order you want.</p>
*
* <p>If the job runs to the end of its available time period before all work has been
* completed, it will stop as normal. You should return true from
* {@link JobService#onStopJob(JobParameters)} in order to have the job rescheduled, and by
* doing so any pending as well as remaining uncompleted work will be re-queued
* for the next time the job runs.</p>
*
* @return Returns a new {@link JobWorkItem} if there is one pending, otherwise null.
* If null is returned, the system will also stop the job if all work has also been completed.
* (This means that for correct operation, you must always call dequeueWork() after you have

View File

@@ -54,7 +54,7 @@ public abstract class JobServiceEngine {
/**
* Context we are running in.
*/
private final Context mContext;
private final Service mService;
private final IJobService mBinder;
@@ -182,12 +182,12 @@ public abstract class JobServiceEngine {
/**
* Create a new engine, ready for use.
*
* @param context The {@link Service} that is creating this engine.
* @param service The {@link Service} that is creating this engine and in which it will run.
*/
public JobServiceEngine(Context context) {
mContext = context;
public JobServiceEngine(Service service) {
mService = service;
mBinder = new JobInterface(this);
mHandler = new JobHandler(mContext.getMainLooper());
mHandler = new JobHandler(mService.getMainLooper());
}
/**

View File

@@ -1071,9 +1071,16 @@ public final class JobSchedulerService extends com.android.server.SystemService
if (DEBUG) {
Slog.d(TAG, "Completed " + jobStatus + ", reschedule=" + needsReschedule);
}
// If the job wants to be rescheduled, we first need to make the next upcoming
// job so we can transfer any appropriate state over from the previous job when
// we stop it.
final JobStatus rescheduledJob = needsReschedule
? getRescheduleJobForFailureLocked(jobStatus) : null;
// Do not write back immediately if this is a periodic job. The job may get lost if system
// shuts down before it is added back.
if (!stopTrackingJobLocked(jobStatus, null, !jobStatus.getJob().isPeriodic())) {
if (!stopTrackingJobLocked(jobStatus, rescheduledJob, !jobStatus.getJob().isPeriodic())) {
if (DEBUG) {
Slog.d(TAG, "Could not find job to remove. Was job removed while executing?");
}
@@ -1082,18 +1089,14 @@ public final class JobSchedulerService extends com.android.server.SystemService
mHandler.obtainMessage(MSG_CHECK_JOB_GREEDY).sendToTarget();
return;
}
// Note: there is a small window of time in here where, when rescheduling a job,
// we will stop monitoring its content providers. This should be fixed by stopping
// the old job after scheduling the new one, but since we have no lock held here
// that may cause ordering problems if the app removes jobStatus while in here.
if (needsReschedule) {
JobStatus rescheduled = getRescheduleJobForFailureLocked(jobStatus);
if (rescheduledJob != null) {
try {
rescheduled.prepareLocked(ActivityManager.getService());
rescheduledJob.prepareLocked(ActivityManager.getService());
} catch (SecurityException e) {
Slog.w(TAG, "Unable to regrant job permissions for " + rescheduled);
Slog.w(TAG, "Unable to regrant job permissions for " + rescheduledJob);
}
startTrackingJobLocked(rescheduled, jobStatus);
startTrackingJobLocked(rescheduledJob, jobStatus);
} else if (jobStatus.getJob().isPeriodic()) {
JobStatus rescheduledPeriodic = getRescheduleJobForPeriodic(jobStatus);
try {

View File

@@ -326,9 +326,18 @@ public final class JobStatus {
public void stopTrackingJobLocked(JobStatus incomingJob) {
if (incomingJob != null) {
// We are replacing with a new job -- transfer the work!
incomingJob.pendingWork = pendingWork;
// We are replacing with a new job -- transfer the work! We do any executing
// work first, since that was originally at the front of the pending work.
if (executingWork != null && executingWork.size() > 0) {
incomingJob.pendingWork = executingWork;
}
if (incomingJob.pendingWork == null) {
incomingJob.pendingWork = pendingWork;
} else if (pendingWork != null && pendingWork.size() > 0) {
incomingJob.pendingWork.addAll(pendingWork);
}
pendingWork = null;
executingWork = null;
incomingJob.nextPendingWorkId = nextPendingWorkId;
} else {
// We are completely stopping the job... need to clean up work.