[GH] Delayed work requests should not be expedited.
Fixes: b/203678406
Test: Added unit tests.
This is an imported pull request from https://github.com/androidx/androidx/pull/257.
Resolves #257
Github-Pr-Head-Sha: 1b78895cb761cc1bb44b26690d90f759d4cbc5f9
GitOrigin-RevId: b192f8999b1d1866f1c29f94f4d277fe86ab62ff
Change-Id: I06924b8f0359f57dd0b84baee6b2d531cfdc9d46
(cherry picked from commit 36d9fe97e1e619f99e59c10b266435d6c826db21)
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/WorkRequestTest.kt b/work/work-runtime/src/androidTest/java/androidx/work/WorkRequestTest.kt
new file mode 100644
index 0000000..4a49ecd
--- /dev/null
+++ b/work/work-runtime/src/androidTest/java/androidx/work/WorkRequestTest.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.work
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.work.worker.TestWorker
+import org.junit.Assert.assertNotNull
+import org.junit.Test
+import org.junit.runner.RunWith
+import java.util.concurrent.TimeUnit
+
+@RunWith(AndroidJUnit4::class)
+class WorkRequestTest {
+ @Test
+ @SmallTest
+ public fun expeditedRequest_withInitialDelay_throwsException() {
+ var error: Throwable? = null
+ try {
+ OneTimeWorkRequest.Builder(TestWorker::class.java)
+ .setInitialDelay(10, TimeUnit.SECONDS)
+ .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
+ .build()
+ } catch (exception: Throwable) {
+ error = exception
+ }
+ // Delayed work cannot be expedited
+ assertNotNull(error)
+ }
+
+ @Test
+ @SmallTest
+ public fun periodicWorkRequest_expedited_throwsException() {
+ var error: Throwable? = null
+ try {
+ PeriodicWorkRequest.Builder(TestWorker::class.java, 15, TimeUnit.MINUTES)
+ .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
+ .build()
+ } catch (exception: Throwable) {
+ error = exception
+ }
+ // Periodic work cannot be expedited
+ assertNotNull(error)
+ }
+}
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/impl/background/systemjob/SystemJobInfoConverterTest.java b/work/work-runtime/src/androidTest/java/androidx/work/impl/background/systemjob/SystemJobInfoConverterTest.java
index 64a2074..1c2bc79 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/impl/background/systemjob/SystemJobInfoConverterTest.java
+++ b/work/work-runtime/src/androidTest/java/androidx/work/impl/background/systemjob/SystemJobInfoConverterTest.java
@@ -269,6 +269,20 @@
assertThat(jobInfo.isExpedited(), is(false));
}
+ @Test
+ @SmallTest
+ public void testConvertExpeditedJobs_delaysAreNotExpedited() {
+ if (!BuildCompat.isAtLeastS()) {
+ return;
+ }
+
+ WorkSpec workSpec = new WorkSpec("id", TestWorker.class.getName());
+ workSpec.expedited = true;
+ workSpec.initialDelay = 1000L; // delay
+ JobInfo jobInfo = mConverter.convert(workSpec, JOB_ID);
+ assertThat(jobInfo.isExpedited(), is(false));
+ }
+
private void convertWithRequiredNetworkType(NetworkType networkType,
int jobInfoNetworkType,
int minSdkVersion) {
diff --git a/work/work-runtime/src/main/java/androidx/work/PeriodicWorkRequest.java b/work/work-runtime/src/main/java/androidx/work/PeriodicWorkRequest.java
index fb44604..af5767f 100644
--- a/work/work-runtime/src/main/java/androidx/work/PeriodicWorkRequest.java
+++ b/work/work-runtime/src/main/java/androidx/work/PeriodicWorkRequest.java
@@ -189,6 +189,10 @@
throw new IllegalArgumentException(
"Cannot set backoff criteria on an idle mode job");
}
+ if (mWorkSpec.expedited) {
+ throw new IllegalArgumentException(
+ "PeriodicWorkRequests cannot be expedited");
+ }
return new PeriodicWorkRequest(this);
}
diff --git a/work/work-runtime/src/main/java/androidx/work/WorkRequest.java b/work/work-runtime/src/main/java/androidx/work/WorkRequest.java
index f54f2f4..678c179 100644
--- a/work/work-runtime/src/main/java/androidx/work/WorkRequest.java
+++ b/work/work-runtime/src/main/java/androidx/work/WorkRequest.java
@@ -317,9 +317,14 @@
|| constraints.requiresCharging()
|| (Build.VERSION.SDK_INT >= 23 && constraints.requiresDeviceIdle());
- if (mWorkSpec.expedited && hasUnsupportedConstraints) {
- throw new IllegalArgumentException(
- "Expedited jobs only support network and storage constraints");
+ if (mWorkSpec.expedited) {
+ if (hasUnsupportedConstraints) {
+ throw new IllegalArgumentException(
+ "Expedited jobs only support network and storage constraints");
+ }
+ if (mWorkSpec.initialDelay > 0) {
+ throw new IllegalArgumentException("Expedited jobs cannot be delayed");
+ }
}
// Create a new id and WorkSpec so this WorkRequest.Builder can be used multiple times.
mId = UUID.randomUUID();
diff --git a/work/work-runtime/src/main/java/androidx/work/impl/background/systemjob/SystemJobInfoConverter.java b/work/work-runtime/src/main/java/androidx/work/impl/background/systemjob/SystemJobInfoConverter.java
index 02df55e..88fc6af 100644
--- a/work/work-runtime/src/main/java/androidx/work/impl/background/systemjob/SystemJobInfoConverter.java
+++ b/work/work-runtime/src/main/java/androidx/work/impl/background/systemjob/SystemJobInfoConverter.java
@@ -125,7 +125,8 @@
}
// Retries cannot be expedited jobs, given they will occur at some point in the future.
boolean isRetry = workSpec.runAttemptCount > 0;
- if (BuildCompat.isAtLeastS() && workSpec.expedited && !isRetry) {
+ boolean isDelayed = offset > 0;
+ if (BuildCompat.isAtLeastS() && workSpec.expedited && !isRetry && !isDelayed) {
//noinspection NewApi
builder.setExpedited(true);
}