1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package androidx.work;
17 
18 import android.os.Build;
19 import android.support.annotation.NonNull;
20 import android.support.annotation.RequiresApi;
21 
22 import java.time.Duration;
23 import java.util.concurrent.TimeUnit;
24 
25 /**
26  * A class that represents a request for repeating work.
27  */
28 
29 public final class PeriodicWorkRequest extends WorkRequest {
30 
31     /**
32      * The minimum interval duration for {@link PeriodicWorkRequest} (in milliseconds).
33      */
34     public static final long MIN_PERIODIC_INTERVAL_MILLIS = 15 * 60 * 1000L; // 15 minutes.
35     /**
36      * The minimum flex duration for {@link PeriodicWorkRequest} (in milliseconds).
37      */
38     public static final long MIN_PERIODIC_FLEX_MILLIS = 5 * 60 * 1000L; // 5 minutes.
39 
PeriodicWorkRequest(Builder builder)40     PeriodicWorkRequest(Builder builder) {
41         super(builder.mId, builder.mWorkSpec, builder.mTags);
42     }
43 
44     /**
45      * Builder for {@link PeriodicWorkRequest} class.
46      */
47     public static final class Builder extends WorkRequest.Builder<Builder, PeriodicWorkRequest> {
48 
49         /**
50          * Creates a {@link PeriodicWorkRequest} to run periodically once every interval period. The
51          * {@link PeriodicWorkRequest} is guaranteed to run exactly one time during this interval
52          * (subject to OS battery optimizations, such as doze mode). The {@code intervalMillis} must
53          * be greater than or equal to {@link PeriodicWorkRequest#MIN_PERIODIC_INTERVAL_MILLIS}. It
54          * may run immediately, at the end of the period, or any time in between so long as the
55          * other conditions are satisfied at the time. The run time of the
56          * {@link PeriodicWorkRequest} can be restricted to a flex period within an interval.
57          *
58          * @param workerClass The {@link Worker} class to run with this job
59          * @param repeatInterval The repeat interval in {@code repeatIntervalTimeUnit} units
60          * @param repeatIntervalTimeUnit The {@link TimeUnit} for {@code repeatInterval}
61          */
Builder( @onNull Class<? extends Worker> workerClass, long repeatInterval, @NonNull TimeUnit repeatIntervalTimeUnit)62         public Builder(
63                 @NonNull Class<? extends Worker> workerClass,
64                 long repeatInterval,
65                 @NonNull TimeUnit repeatIntervalTimeUnit) {
66             super(workerClass);
67             mWorkSpec.setPeriodic(repeatIntervalTimeUnit.toMillis(repeatInterval));
68         }
69 
70         /**
71          * Creates a {@link PeriodicWorkRequest} to run periodically once every interval period. The
72          * {@link PeriodicWorkRequest} is guaranteed to run exactly one time during this interval
73          * (subject to OS battery optimizations, such as doze mode). The {@code intervalMillis} must
74          * be greater than or equal to {@link PeriodicWorkRequest#MIN_PERIODIC_INTERVAL_MILLIS}. It
75          * may run immediately, at the end of the period, or any time in between so long as the
76          * other conditions are satisfied at the time. The run time of the
77          * {@link PeriodicWorkRequest} can be restricted to a flex period within an interval.
78          *
79          * @param workerClass The {@link Worker} class to run with this job
80          * @param repeatInterval The repeat interval
81          */
82         @RequiresApi(26)
Builder( @onNull Class<? extends Worker> workerClass, @NonNull Duration repeatInterval)83         public Builder(
84                 @NonNull Class<? extends Worker> workerClass,
85                 @NonNull Duration repeatInterval) {
86             super(workerClass);
87             mWorkSpec.setPeriodic(repeatInterval.toMillis());
88         }
89 
90         /**
91          * Creates a {@link PeriodicWorkRequest} to run periodically once within the
92          * <strong>flex period</strong> of every interval period. See diagram below. The flex period
93          * begins at {@code intervalMillis - flexMillis} to the end of the interval.
94          * {@code intervalMillis} must be greater than or equal to
95          * {@link PeriodicWorkRequest#MIN_PERIODIC_INTERVAL_MILLIS} and {@code flexMillis} must
96          * be greater than or equal to {@link PeriodicWorkRequest#MIN_PERIODIC_FLEX_MILLIS}.
97          *
98          * <p><pre>
99          * [     before flex     |     flex     ][     before flex     |     flex     ]...
100          * [   cannot run work   | can run work ][   cannot run work   | can run work ]...
101          * \____________________________________/\____________________________________/...
102          *                interval 1                            interval 2             ...(repeat)
103          * </pre></p>
104          *
105          * @param workerClass The {@link Worker} class to run with this job
106          * @param repeatInterval The repeat interval in {@code repeatIntervalTimeUnit} units
107          * @param repeatIntervalTimeUnit The {@link TimeUnit} for {@code repeatInterval}
108          * @param flexInterval The duration in {@code flexIntervalTimeUnit} units for which this
109          *                     work repeats from the end of the {@code repeatInterval}
110          * @param flexIntervalTimeUnit The {@link TimeUnit} for {@code flexInterval}
111          */
Builder( @onNull Class<? extends Worker> workerClass, long repeatInterval, @NonNull TimeUnit repeatIntervalTimeUnit, long flexInterval, @NonNull TimeUnit flexIntervalTimeUnit)112         public Builder(
113                 @NonNull Class<? extends Worker> workerClass,
114                 long repeatInterval,
115                 @NonNull TimeUnit repeatIntervalTimeUnit,
116                 long flexInterval,
117                 @NonNull TimeUnit flexIntervalTimeUnit) {
118             super(workerClass);
119             mWorkSpec.setPeriodic(
120                     repeatIntervalTimeUnit.toMillis(repeatInterval),
121                     flexIntervalTimeUnit.toMillis(flexInterval));
122         }
123 
124         /**
125          * Creates a {@link PeriodicWorkRequest} to run periodically once within the
126          * <strong>flex period</strong> of every interval period. See diagram below. The flex period
127          * begins at {@code intervalMillis - flexMillis} to the end of the interval.
128          * {@code intervalMillis} must be greater than or equal to
129          * {@link PeriodicWorkRequest#MIN_PERIODIC_INTERVAL_MILLIS} and {@code flexMillis} must
130          * be greater than or equal to {@link PeriodicWorkRequest#MIN_PERIODIC_FLEX_MILLIS}.
131          *
132          * <p><pre>
133          * [     before flex     |     flex     ][     before flex     |     flex     ]...
134          * [   cannot run work   | can run work ][   cannot run work   | can run work ]...
135          * \____________________________________/\____________________________________/...
136          *                interval 1                            interval 2             ...(repeat)
137          * </pre></p>
138          *
139          * @param workerClass The {@link Worker} class to run with this job
140          * @param repeatInterval The repeat interval
141          * @param flexInterval The duration in for which this work repeats from the end of the
142          *                     {@code repeatInterval}
143          */
144         @RequiresApi(26)
Builder( @onNull Class<? extends Worker> workerClass, @NonNull Duration repeatInterval, @NonNull Duration flexInterval)145         public Builder(
146                 @NonNull Class<? extends Worker> workerClass,
147                 @NonNull Duration repeatInterval,
148                 @NonNull Duration flexInterval) {
149             super(workerClass);
150             mWorkSpec.setPeriodic(repeatInterval.toMillis(), flexInterval.toMillis());
151         }
152 
153         @Override
build()154         public PeriodicWorkRequest build() {
155             if (mBackoffCriteriaSet
156                     && Build.VERSION.SDK_INT >= 23
157                     && mWorkSpec.constraints.requiresDeviceIdle()) {
158                 throw new IllegalArgumentException(
159                         "Cannot set backoff criteria on an idle mode job");
160             }
161             return new PeriodicWorkRequest(this);
162         }
163 
164         @Override
getThis()165         Builder getThis() {
166             return this;
167         }
168     }
169 }
170