diff options
| author | 2024-02-12 08:36:00 +0000 | |
|---|---|---|
| committer | 2024-02-12 08:36:00 +0000 | |
| commit | 774b44c9282b09a93c1bebb4baef6dcc2cf5d70c (patch) | |
| tree | e78eeea7de0d8547da2db51a74651e4052ca3f8a | |
| parent | da551436c68d7ef61ee4a54165cdb91c5fcf67c2 (diff) | |
| parent | 9c9e8d6b04ce409db7382f6a7cb7bbec2a4b97a2 (diff) | |
Merge "Handle negative delays and deadlines." into main
4 files changed, 51 insertions, 12 deletions
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java index 7de67993bc62..52c0ac1d981d 100644 --- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java +++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java @@ -124,6 +124,15 @@ public class JobInfo implements Parcelable { @Overridable // Aid in testing public static final long ENFORCE_MINIMUM_TIME_WINDOWS = 311402873L; + /** + * Require that minimum latencies and override deadlines are nonnegative. + * + * @hide + */ + @ChangeId + @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) + public static final long REJECT_NEGATIVE_DELAYS_AND_DEADLINES = 323349338L; + /** @hide */ @IntDef(prefix = { "NETWORK_TYPE_" }, value = { NETWORK_TYPE_NONE, @@ -692,14 +701,14 @@ public class JobInfo implements Parcelable { * @see JobInfo.Builder#setMinimumLatency(long) */ public long getMinLatencyMillis() { - return minLatencyMillis; + return Math.max(0, minLatencyMillis); } /** * @see JobInfo.Builder#setOverrideDeadline(long) */ public long getMaxExecutionDelayMillis() { - return maxExecutionDelayMillis; + return Math.max(0, maxExecutionDelayMillis); } /** @@ -818,7 +827,7 @@ public class JobInfo implements Parcelable { * @hide */ public boolean hasEarlyConstraint() { - return hasEarlyConstraint; + return hasEarlyConstraint && minLatencyMillis > 0; } /** @@ -827,7 +836,7 @@ public class JobInfo implements Parcelable { * @hide */ public boolean hasLateConstraint() { - return hasLateConstraint; + return hasLateConstraint && maxExecutionDelayMillis >= 0; } @Override @@ -1869,6 +1878,13 @@ public class JobInfo implements Parcelable { * Because it doesn't make sense setting this property on a periodic job, doing so will * throw an {@link java.lang.IllegalArgumentException} when * {@link android.app.job.JobInfo.Builder#build()} is called. + * + * Negative latencies also don't make sense for a job and are indicative of an error, + * so starting in Android version {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}, + * setting a negative deadline will result in + * {@link android.app.job.JobInfo.Builder#build()} throwing an + * {@link java.lang.IllegalArgumentException}. + * * @param minLatencyMillis Milliseconds before which this job will not be considered for * execution. * @see JobInfo#getMinLatencyMillis() @@ -1892,6 +1908,13 @@ public class JobInfo implements Parcelable { * throw an {@link java.lang.IllegalArgumentException} when * {@link android.app.job.JobInfo.Builder#build()} is called. * + * <p> + * Negative deadlines also don't make sense for a job and are indicative of an error, + * so starting in Android version {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}, + * setting a negative deadline will result in + * {@link android.app.job.JobInfo.Builder#build()} throwing an + * {@link java.lang.IllegalArgumentException}. + * * <p class="note"> * Since a job will run once the deadline has passed regardless of the status of other * constraints, setting a deadline of 0 (or a {@link #setMinimumLatency(long) delay} equal @@ -2189,13 +2212,15 @@ public class JobInfo implements Parcelable { public JobInfo build() { return build(Compatibility.isChangeEnabled(DISALLOW_DEADLINES_FOR_PREFETCH_JOBS), Compatibility.isChangeEnabled(REJECT_NEGATIVE_NETWORK_ESTIMATES), - Compatibility.isChangeEnabled(ENFORCE_MINIMUM_TIME_WINDOWS)); + Compatibility.isChangeEnabled(ENFORCE_MINIMUM_TIME_WINDOWS), + Compatibility.isChangeEnabled(REJECT_NEGATIVE_DELAYS_AND_DEADLINES)); } /** @hide */ public JobInfo build(boolean disallowPrefetchDeadlines, boolean rejectNegativeNetworkEstimates, - boolean enforceMinimumTimeWindows) { + boolean enforceMinimumTimeWindows, + boolean rejectNegativeDelaysAndDeadlines) { // This check doesn't need to be inside enforceValidity. It's an unnecessary legacy // check that would ideally be phased out instead. if (mBackoffPolicySet && (mConstraintFlags & CONSTRAINT_FLAG_DEVICE_IDLE) != 0) { @@ -2205,7 +2230,7 @@ public class JobInfo implements Parcelable { } JobInfo jobInfo = new JobInfo(this); jobInfo.enforceValidity(disallowPrefetchDeadlines, rejectNegativeNetworkEstimates, - enforceMinimumTimeWindows); + enforceMinimumTimeWindows, rejectNegativeDelaysAndDeadlines); return jobInfo; } @@ -2225,7 +2250,8 @@ public class JobInfo implements Parcelable { */ public final void enforceValidity(boolean disallowPrefetchDeadlines, boolean rejectNegativeNetworkEstimates, - boolean enforceMinimumTimeWindows) { + boolean enforceMinimumTimeWindows, + boolean rejectNegativeDelaysAndDeadlines) { // Check that network estimates require network type and are reasonable values. if ((networkDownloadBytes > 0 || networkUploadBytes > 0 || minimumNetworkChunkBytes > 0) && networkRequest == null) { @@ -2259,6 +2285,17 @@ public class JobInfo implements Parcelable { throw new IllegalArgumentException("Minimum chunk size must be positive"); } + if (rejectNegativeDelaysAndDeadlines) { + if (minLatencyMillis < 0) { + throw new IllegalArgumentException( + "Minimum latency is negative: " + minLatencyMillis); + } + if (maxExecutionDelayMillis < 0) { + throw new IllegalArgumentException( + "Override deadline is negative: " + maxExecutionDelayMillis); + } + } + final boolean hasDeadline = maxExecutionDelayMillis != 0L; // Check that a deadline was not set on a periodic job. if (isPeriodic) { 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 a83c099b764d..f819f15b430f 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java @@ -4850,7 +4850,7 @@ public class JobSchedulerService extends com.android.server.SystemService Slog.w(TAG, "Uid " + uid + " set bias on its job"); return new JobInfo.Builder(job) .setBias(JobInfo.BIAS_DEFAULT) - .build(false, false, false); + .build(false, false, false, false); } } @@ -4874,7 +4874,9 @@ public class JobSchedulerService extends com.android.server.SystemService JobInfo.DISALLOW_DEADLINES_FOR_PREFETCH_JOBS, callingUid), rejectNegativeNetworkEstimates, CompatChanges.isChangeEnabled( - JobInfo.ENFORCE_MINIMUM_TIME_WINDOWS, callingUid)); + JobInfo.ENFORCE_MINIMUM_TIME_WINDOWS, callingUid), + CompatChanges.isChangeEnabled( + JobInfo.REJECT_NEGATIVE_DELAYS_AND_DEADLINES, callingUid)); if ((job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0) { getContext().enforceCallingOrSelfPermission( android.Manifest.permission.CONNECTIVITY_INTERNAL, TAG); diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java index 53b14d616ecc..d8934d8f83b8 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java @@ -1495,7 +1495,7 @@ public final class JobStore { // return value), the deadline is dropped. Periodic jobs require all constraints // to be met, so there's no issue with their deadlines. // The same logic applies for other target SDK-based validation checks. - builtJob = jobBuilder.build(false, false, false); + builtJob = jobBuilder.build(false, false, false, false); } catch (Exception e) { Slog.w(TAG, "Unable to build job from XML, ignoring: " + jobBuilder.summarize(), e); return null; 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 a3a686fdc5c8..655afbc407f6 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 @@ -657,7 +657,7 @@ public final class JobStatus { .build()); // Don't perform validation checks at this point since we've already passed the // initial validation check. - job = builder.build(false, false, false); + job = builder.build(false, false, false, false); } this.job = job; |