Loading api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -5492,6 +5492,7 @@ package android.app.job { method public int getNetworkCapabilities(); method public android.content.ComponentName getService(); method public boolean isPeriodic(); method public boolean isPersisted(); method public boolean isRequireCharging(); method public boolean isRequireDeviceIdle(); method public void writeToParcel(android.os.Parcel, int); Loading @@ -5508,6 +5509,7 @@ package android.app.job { method public android.app.job.JobInfo build(); method public android.app.job.JobInfo.Builder setBackoffCriteria(long, int); method public android.app.job.JobInfo.Builder setExtras(android.os.PersistableBundle); method public android.app.job.JobInfo.Builder setIsPersisted(boolean); method public android.app.job.JobInfo.Builder setMinimumLatency(long); method public android.app.job.JobInfo.Builder setOverrideDeadline(long); method public android.app.job.JobInfo.Builder setPeriodic(long); core/java/android/app/job/JobInfo.java +25 −6 Original line number Diff line number Diff line Loading @@ -64,7 +64,6 @@ public class JobInfo implements Parcelable { } private final int jobId; // TODO: Change this to use PersistableBundle when that lands in master. private final PersistableBundle extras; private final ComponentName service; private final boolean requireCharging; Loading @@ -75,6 +74,7 @@ public class JobInfo implements Parcelable { private final long minLatencyMillis; private final long maxExecutionDelayMillis; private final boolean isPeriodic; private final boolean isPersisted; private final long intervalMillis; private final long initialBackoffMillis; private final int backoffPolicy; Loading Loading @@ -144,6 +144,13 @@ public class JobInfo implements Parcelable { return isPeriodic; } /** * @return Whether or not this job should be persisted across device reboots. */ public boolean isPersisted() { return isPersisted; } /** * Set to the interval between occurrences of this job. This value is <b>not</b> set if the * job does not recur periodically. Loading Loading @@ -197,6 +204,7 @@ public class JobInfo implements Parcelable { minLatencyMillis = in.readLong(); maxExecutionDelayMillis = in.readLong(); isPeriodic = in.readInt() == 1; isPersisted = in.readInt() == 1; intervalMillis = in.readLong(); initialBackoffMillis = in.readLong(); backoffPolicy = in.readInt(); Loading @@ -214,6 +222,7 @@ public class JobInfo implements Parcelable { minLatencyMillis = b.mMinLatencyMillis; maxExecutionDelayMillis = b.mMaxExecutionDelayMillis; isPeriodic = b.mIsPeriodic; isPersisted = b.mIsPersisted; intervalMillis = b.mIntervalMillis; initialBackoffMillis = b.mInitialBackoffMillis; backoffPolicy = b.mBackoffPolicy; Loading @@ -237,6 +246,7 @@ public class JobInfo implements Parcelable { out.writeLong(minLatencyMillis); out.writeLong(maxExecutionDelayMillis); out.writeInt(isPeriodic ? 1 : 0); out.writeInt(isPersisted ? 1 : 0); out.writeLong(intervalMillis); out.writeLong(initialBackoffMillis); out.writeInt(backoffPolicy); Loading Loading @@ -265,6 +275,7 @@ public class JobInfo implements Parcelable { private boolean mRequiresCharging; private boolean mRequiresDeviceIdle; private int mNetworkCapabilities; private boolean mIsPersisted; // One-off parameters. private long mMinLatencyMillis; private long mMaxExecutionDelayMillis; Loading Loading @@ -342,11 +353,6 @@ public class JobInfo implements Parcelable { * Specify that this job should recur with the provided interval, not more than once per * period. You have no control over when within this interval this job will be executed, * only the guarantee that it will be executed at most once within this interval. * A periodic job will be repeated until the phone is turned off, however it will only be * persisted beyond boot if the client app has declared the * {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED} permission. You can schedule * periodic jobs without this permission, they simply will cease to exist after the phone * restarts. * Setting this function on the builder with {@link #setMinimumLatency(long)} or * {@link #setOverrideDeadline(long)} will result in an error. * @param intervalMillis Millisecond interval for which this job will repeat. Loading Loading @@ -406,6 +412,19 @@ public class JobInfo implements Parcelable { return this; } /** * Set whether or not to persist this job across device reboots. This will only have an * effect if your application holds the permission * {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED}. Otherwise an exception will * be thrown. * @param isPersisted True to indicate that the job will be written to disk and loaded at * boot. */ public Builder setIsPersisted(boolean isPersisted) { mIsPersisted = isPersisted; return this; } /** * @return The job object to hand to the JobScheduler. This object is immutable. */ Loading services/core/java/com/android/server/job/JobSchedulerService.java +9 −6 Original line number Diff line number Diff line Loading @@ -140,12 +140,10 @@ public class JobSchedulerService extends com.android.server.SystemService * This cancels the job if it's already been scheduled, and replaces it with the one provided. * @param job JobInfo object containing execution parameters * @param uId The package identifier of the application this job is for. * @param canPersistJob Whether or not the client has the appropriate permissions for * persisting this job. * @return Result of this operation. See <code>JobScheduler#RESULT_*</code> return codes. */ public int schedule(JobInfo job, int uId, boolean canPersistJob) { JobStatus jobStatus = new JobStatus(job, uId, canPersistJob); public int schedule(JobInfo job, int uId) { JobStatus jobStatus = new JobStatus(job, uId); cancelJob(uId, job.getId()); startTrackingJob(jobStatus); return JobScheduler.RESULT_SUCCESS; Loading Loading @@ -668,11 +666,16 @@ public class JobSchedulerService extends com.android.server.SystemService final int uid = Binder.getCallingUid(); enforceValidJobRequest(uid, job); final boolean canPersist = canPersistJobs(pid, uid); if (job.isPersisted()) { if (!canPersistJobs(pid, uid)) { throw new IllegalArgumentException("Error: requested job be persisted without" + " holding RECEIVE_BOOT_COMPLETED permission."); } } long ident = Binder.clearCallingIdentity(); try { return JobSchedulerService.this.schedule(job, uid, canPersist); return JobSchedulerService.this.schedule(job, uid); } finally { Binder.restoreCallingIdentity(ident); } Loading services/core/java/com/android/server/job/JobStore.java +6 −2 Original line number Diff line number Diff line Loading @@ -160,7 +160,9 @@ public class JobStore { } return false; } if (jobStatus.isPersisted()) { maybeWriteStatusToDiskAsync(); } return removed; } Loading Loading @@ -429,7 +431,8 @@ public class JobStore { } } private List<JobStatus> readJobMapImpl(FileInputStream fis) throws XmlPullParserException, IOException { private List<JobStatus> readJobMapImpl(FileInputStream fis) throws XmlPullParserException, IOException { XmlPullParser parser = Xml.newPullParser(); parser.setInput(fis, null); Loading Loading @@ -498,6 +501,7 @@ public class JobStore { // Read out job identifier attributes. try { jobBuilder = buildBuilderFromXml(parser); jobBuilder.setIsPersisted(true); uid = Integer.valueOf(parser.getAttributeValue(null, "uid")); } catch (NumberFormatException e) { Slog.e(TAG, "Error parsing job's required fields, skipping"); Loading services/core/java/com/android/server/job/controllers/JobStatus.java +9 −12 Original line number Diff line number Diff line Loading @@ -43,9 +43,6 @@ public class JobStatus { final JobInfo job; final int uId; /** At reschedule time we need to know whether to update job on disk. */ final boolean persisted; // Constraints. final AtomicBoolean chargingConstraintSatisfied = new AtomicBoolean(); final AtomicBoolean timeDelayConstraintSatisfied = new AtomicBoolean(); Loading @@ -72,16 +69,15 @@ public class JobStatus { return uId; } private JobStatus(JobInfo job, int uId, boolean persisted, int numFailures) { private JobStatus(JobInfo job, int uId, int numFailures) { this.job = job; this.uId = uId; this.numFailures = numFailures; this.persisted = persisted; } /** Create a newly scheduled job. */ public JobStatus(JobInfo job, int uId, boolean persisted) { this(job, uId, persisted, 0); public JobStatus(JobInfo job, int uId) { this(job, uId, 0); final long elapsedNow = SystemClock.elapsedRealtime(); Loading @@ -105,7 +101,7 @@ public class JobStatus { */ public JobStatus(JobInfo job, int uId, long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis) { this(job, uId, true, 0); this(job, uId, 0); this.earliestRunTimeElapsedMillis = earliestRunTimeElapsedMillis; this.latestRunTimeElapsedMillis = latestRunTimeElapsedMillis; Loading @@ -114,7 +110,7 @@ public class JobStatus { /** Create a new job to be rescheduled with the provided parameters. */ public JobStatus(JobStatus rescheduling, long newEarliestRuntimeElapsedMillis, long newLatestRuntimeElapsedMillis, int backoffAttempt) { this(rescheduling.job, rescheduling.getUid(), rescheduling.isPersisted(), backoffAttempt); this(rescheduling.job, rescheduling.getUid(), backoffAttempt); earliestRunTimeElapsedMillis = newEarliestRuntimeElapsedMillis; latestRunTimeElapsedMillis = newLatestRuntimeElapsedMillis; Loading Loading @@ -172,6 +168,10 @@ public class JobStatus { return job.isRequireDeviceIdle(); } public boolean isPersisted() { return job.isPersisted(); } public long getEarliestRunTime() { return earliestRunTimeElapsedMillis; } Loading @@ -180,9 +180,6 @@ public class JobStatus { return latestRunTimeElapsedMillis; } public boolean isPersisted() { return persisted; } /** * @return Whether or not this job is ready to run, based on its requirements. */ Loading Loading
api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -5492,6 +5492,7 @@ package android.app.job { method public int getNetworkCapabilities(); method public android.content.ComponentName getService(); method public boolean isPeriodic(); method public boolean isPersisted(); method public boolean isRequireCharging(); method public boolean isRequireDeviceIdle(); method public void writeToParcel(android.os.Parcel, int); Loading @@ -5508,6 +5509,7 @@ package android.app.job { method public android.app.job.JobInfo build(); method public android.app.job.JobInfo.Builder setBackoffCriteria(long, int); method public android.app.job.JobInfo.Builder setExtras(android.os.PersistableBundle); method public android.app.job.JobInfo.Builder setIsPersisted(boolean); method public android.app.job.JobInfo.Builder setMinimumLatency(long); method public android.app.job.JobInfo.Builder setOverrideDeadline(long); method public android.app.job.JobInfo.Builder setPeriodic(long);
core/java/android/app/job/JobInfo.java +25 −6 Original line number Diff line number Diff line Loading @@ -64,7 +64,6 @@ public class JobInfo implements Parcelable { } private final int jobId; // TODO: Change this to use PersistableBundle when that lands in master. private final PersistableBundle extras; private final ComponentName service; private final boolean requireCharging; Loading @@ -75,6 +74,7 @@ public class JobInfo implements Parcelable { private final long minLatencyMillis; private final long maxExecutionDelayMillis; private final boolean isPeriodic; private final boolean isPersisted; private final long intervalMillis; private final long initialBackoffMillis; private final int backoffPolicy; Loading Loading @@ -144,6 +144,13 @@ public class JobInfo implements Parcelable { return isPeriodic; } /** * @return Whether or not this job should be persisted across device reboots. */ public boolean isPersisted() { return isPersisted; } /** * Set to the interval between occurrences of this job. This value is <b>not</b> set if the * job does not recur periodically. Loading Loading @@ -197,6 +204,7 @@ public class JobInfo implements Parcelable { minLatencyMillis = in.readLong(); maxExecutionDelayMillis = in.readLong(); isPeriodic = in.readInt() == 1; isPersisted = in.readInt() == 1; intervalMillis = in.readLong(); initialBackoffMillis = in.readLong(); backoffPolicy = in.readInt(); Loading @@ -214,6 +222,7 @@ public class JobInfo implements Parcelable { minLatencyMillis = b.mMinLatencyMillis; maxExecutionDelayMillis = b.mMaxExecutionDelayMillis; isPeriodic = b.mIsPeriodic; isPersisted = b.mIsPersisted; intervalMillis = b.mIntervalMillis; initialBackoffMillis = b.mInitialBackoffMillis; backoffPolicy = b.mBackoffPolicy; Loading @@ -237,6 +246,7 @@ public class JobInfo implements Parcelable { out.writeLong(minLatencyMillis); out.writeLong(maxExecutionDelayMillis); out.writeInt(isPeriodic ? 1 : 0); out.writeInt(isPersisted ? 1 : 0); out.writeLong(intervalMillis); out.writeLong(initialBackoffMillis); out.writeInt(backoffPolicy); Loading Loading @@ -265,6 +275,7 @@ public class JobInfo implements Parcelable { private boolean mRequiresCharging; private boolean mRequiresDeviceIdle; private int mNetworkCapabilities; private boolean mIsPersisted; // One-off parameters. private long mMinLatencyMillis; private long mMaxExecutionDelayMillis; Loading Loading @@ -342,11 +353,6 @@ public class JobInfo implements Parcelable { * Specify that this job should recur with the provided interval, not more than once per * period. You have no control over when within this interval this job will be executed, * only the guarantee that it will be executed at most once within this interval. * A periodic job will be repeated until the phone is turned off, however it will only be * persisted beyond boot if the client app has declared the * {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED} permission. You can schedule * periodic jobs without this permission, they simply will cease to exist after the phone * restarts. * Setting this function on the builder with {@link #setMinimumLatency(long)} or * {@link #setOverrideDeadline(long)} will result in an error. * @param intervalMillis Millisecond interval for which this job will repeat. Loading Loading @@ -406,6 +412,19 @@ public class JobInfo implements Parcelable { return this; } /** * Set whether or not to persist this job across device reboots. This will only have an * effect if your application holds the permission * {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED}. Otherwise an exception will * be thrown. * @param isPersisted True to indicate that the job will be written to disk and loaded at * boot. */ public Builder setIsPersisted(boolean isPersisted) { mIsPersisted = isPersisted; return this; } /** * @return The job object to hand to the JobScheduler. This object is immutable. */ Loading
services/core/java/com/android/server/job/JobSchedulerService.java +9 −6 Original line number Diff line number Diff line Loading @@ -140,12 +140,10 @@ public class JobSchedulerService extends com.android.server.SystemService * This cancels the job if it's already been scheduled, and replaces it with the one provided. * @param job JobInfo object containing execution parameters * @param uId The package identifier of the application this job is for. * @param canPersistJob Whether or not the client has the appropriate permissions for * persisting this job. * @return Result of this operation. See <code>JobScheduler#RESULT_*</code> return codes. */ public int schedule(JobInfo job, int uId, boolean canPersistJob) { JobStatus jobStatus = new JobStatus(job, uId, canPersistJob); public int schedule(JobInfo job, int uId) { JobStatus jobStatus = new JobStatus(job, uId); cancelJob(uId, job.getId()); startTrackingJob(jobStatus); return JobScheduler.RESULT_SUCCESS; Loading Loading @@ -668,11 +666,16 @@ public class JobSchedulerService extends com.android.server.SystemService final int uid = Binder.getCallingUid(); enforceValidJobRequest(uid, job); final boolean canPersist = canPersistJobs(pid, uid); if (job.isPersisted()) { if (!canPersistJobs(pid, uid)) { throw new IllegalArgumentException("Error: requested job be persisted without" + " holding RECEIVE_BOOT_COMPLETED permission."); } } long ident = Binder.clearCallingIdentity(); try { return JobSchedulerService.this.schedule(job, uid, canPersist); return JobSchedulerService.this.schedule(job, uid); } finally { Binder.restoreCallingIdentity(ident); } Loading
services/core/java/com/android/server/job/JobStore.java +6 −2 Original line number Diff line number Diff line Loading @@ -160,7 +160,9 @@ public class JobStore { } return false; } if (jobStatus.isPersisted()) { maybeWriteStatusToDiskAsync(); } return removed; } Loading Loading @@ -429,7 +431,8 @@ public class JobStore { } } private List<JobStatus> readJobMapImpl(FileInputStream fis) throws XmlPullParserException, IOException { private List<JobStatus> readJobMapImpl(FileInputStream fis) throws XmlPullParserException, IOException { XmlPullParser parser = Xml.newPullParser(); parser.setInput(fis, null); Loading Loading @@ -498,6 +501,7 @@ public class JobStore { // Read out job identifier attributes. try { jobBuilder = buildBuilderFromXml(parser); jobBuilder.setIsPersisted(true); uid = Integer.valueOf(parser.getAttributeValue(null, "uid")); } catch (NumberFormatException e) { Slog.e(TAG, "Error parsing job's required fields, skipping"); Loading
services/core/java/com/android/server/job/controllers/JobStatus.java +9 −12 Original line number Diff line number Diff line Loading @@ -43,9 +43,6 @@ public class JobStatus { final JobInfo job; final int uId; /** At reschedule time we need to know whether to update job on disk. */ final boolean persisted; // Constraints. final AtomicBoolean chargingConstraintSatisfied = new AtomicBoolean(); final AtomicBoolean timeDelayConstraintSatisfied = new AtomicBoolean(); Loading @@ -72,16 +69,15 @@ public class JobStatus { return uId; } private JobStatus(JobInfo job, int uId, boolean persisted, int numFailures) { private JobStatus(JobInfo job, int uId, int numFailures) { this.job = job; this.uId = uId; this.numFailures = numFailures; this.persisted = persisted; } /** Create a newly scheduled job. */ public JobStatus(JobInfo job, int uId, boolean persisted) { this(job, uId, persisted, 0); public JobStatus(JobInfo job, int uId) { this(job, uId, 0); final long elapsedNow = SystemClock.elapsedRealtime(); Loading @@ -105,7 +101,7 @@ public class JobStatus { */ public JobStatus(JobInfo job, int uId, long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis) { this(job, uId, true, 0); this(job, uId, 0); this.earliestRunTimeElapsedMillis = earliestRunTimeElapsedMillis; this.latestRunTimeElapsedMillis = latestRunTimeElapsedMillis; Loading @@ -114,7 +110,7 @@ public class JobStatus { /** Create a new job to be rescheduled with the provided parameters. */ public JobStatus(JobStatus rescheduling, long newEarliestRuntimeElapsedMillis, long newLatestRuntimeElapsedMillis, int backoffAttempt) { this(rescheduling.job, rescheduling.getUid(), rescheduling.isPersisted(), backoffAttempt); this(rescheduling.job, rescheduling.getUid(), backoffAttempt); earliestRunTimeElapsedMillis = newEarliestRuntimeElapsedMillis; latestRunTimeElapsedMillis = newLatestRuntimeElapsedMillis; Loading Loading @@ -172,6 +168,10 @@ public class JobStatus { return job.isRequireDeviceIdle(); } public boolean isPersisted() { return job.isPersisted(); } public long getEarliestRunTime() { return earliestRunTimeElapsedMillis; } Loading @@ -180,9 +180,6 @@ public class JobStatus { return latestRunTimeElapsedMillis; } public boolean isPersisted() { return persisted; } /** * @return Whether or not this job is ready to run, based on its requirements. */ Loading