Build PeriodicWork on top of OneTimeWork.

* This change applies mainly to SystemJobScheduler.
* This will allow us to set initial delays on PeriodicWork.
* Potentially make integration tests easier.
* Migrates all existing WorkRequests to the new paradigm.

Test: All unit tests pass.
Also ran a lot of integration tests on API 25 and API 22.

Change-Id: If4f1a3627af29d04fe2ed2df2333f627c4ca7095
diff --git a/work/workmanager/src/main/java/androidx/work/impl/model/WorkSpec.java b/work/workmanager/src/main/java/androidx/work/impl/model/WorkSpec.java
index cd1e224..bae09fe 100644
--- a/work/workmanager/src/main/java/androidx/work/impl/model/WorkSpec.java
+++ b/work/workmanager/src/main/java/androidx/work/impl/model/WorkSpec.java
@@ -22,8 +22,6 @@
 import static androidx.work.WorkRequest.MAX_BACKOFF_MILLIS;
 import static androidx.work.WorkRequest.MIN_BACKOFF_MILLIS;
 
-import android.os.Build;
-
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
 import androidx.arch.core.util.Function;
@@ -39,7 +37,6 @@
 import androidx.work.Logger;
 import androidx.work.WorkInfo;
 import androidx.work.WorkRequest;
-import androidx.work.impl.WorkManagerImpl;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -250,38 +247,33 @@
                     : (long) Math.scalb(backoffDelayDuration, runAttemptCount - 1);
             return periodStartTime + Math.min(WorkRequest.MAX_BACKOFF_MILLIS, delay);
         } else if (isPeriodic()) {
-            if (Build.VERSION.SDK_INT <= WorkManagerImpl.MAX_PRE_JOB_SCHEDULER_API_LEVEL) {
-                // Flex is only applicable when it's different from interval duration for
-                // the AlarmManager implementation.
-                boolean isFlexApplicable = flexDuration != intervalDuration;
-                if (isFlexApplicable) {
-                    // When a PeriodicWorkRequest is being scheduled for the first time,
-                    // the periodStartTime will be 0. To correctly emulate flex, we need to set it
-                    // to now, so the PeriodicWorkRequest has an initial delay of
-                    // (interval - flex).
+            boolean isFlexApplicable = flexDuration != intervalDuration;
+            if (isFlexApplicable) {
+                // When a PeriodicWorkRequest is being scheduled for the first time,
+                // the periodStartTime will be 0. To correctly emulate flex, we need to set it
+                // to now, so the PeriodicWorkRequest has an initial delay of
+                // initialDelay + (interval - flex).
 
-                    // The subsequent runs will only add the interval duration and no flex.
-                    // This gives us the following behavior:
-                    // 1 => now + (interval - flex) = firstRunTime
-                    // 2 => firstRunTime + 2 * interval - flex
-                    // 3 => firstRunTime + 3 * interval - flex
+                // The subsequent runs will only add the interval duration and no flex.
+                // This gives us the following behavior:
+                // 1 => now + (interval - flex) + initialDelay = firstRunTime
+                // 2 => firstRunTime + 2 * interval - flex
+                // 3 => firstRunTime + 3 * interval - flex
 
-                    long offset = periodStartTime == 0 ? (-1 * flexDuration) : 0;
-                    long start =
-                            periodStartTime == 0 ? System.currentTimeMillis() : periodStartTime;
-                    return start + intervalDuration + offset;
-                } else {
-                    // Don't use flexDuration for determining next run time for PeriodicWork
-                    // Schedulers <= API 22. This is because intervalDuration could equal
-                    // flexDuration.
-                    return periodStartTime + intervalDuration;
-                }
-
+                long offset = periodStartTime == 0 ? (-1 * flexDuration) : 0;
+                long start = periodStartTime == 0 ? (System.currentTimeMillis() + initialDelay)
+                        : periodStartTime;
+                return start + intervalDuration + offset;
             } else {
-                return periodStartTime + intervalDuration - flexDuration;
+                // Don't use flexDuration for determining next run time for PeriodicWork
+                // This is because intervalDuration could equal flexDuration.
+                return periodStartTime + intervalDuration;
             }
         } else {
-            return periodStartTime + initialDelay;
+            // We are checking for (periodStartTime == 0) to support our testing use case.
+            // For newly created WorkSpecs periodStartTime will always be 0.
+            long start = (periodStartTime == 0) ? System.currentTimeMillis() : periodStartTime;
+            return start + initialDelay;
         }
     }