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.support.annotation.NonNull; 19 import android.support.annotation.RequiresApi; 20 import android.support.annotation.RestrictTo; 21 import android.support.annotation.VisibleForTesting; 22 23 import androidx.work.impl.model.WorkSpec; 24 25 import java.time.Duration; 26 import java.util.HashSet; 27 import java.util.Set; 28 import java.util.UUID; 29 import java.util.concurrent.TimeUnit; 30 31 /** 32 * The base interface for work requests. 33 */ 34 35 public abstract class WorkRequest { 36 37 /** 38 * The default initial backoff time (in milliseconds) for work that has to be retried. 39 */ 40 public static final long DEFAULT_BACKOFF_DELAY_MILLIS = 30000L; 41 42 /** 43 * The maximum backoff time (in milliseconds) for work that has to be retried. 44 */ 45 public static final long MAX_BACKOFF_MILLIS = 5 * 60 * 60 * 1000; // 5 hours. 46 47 /** 48 * The minimum backoff time for work (in milliseconds) that has to be retried. 49 */ 50 public static final long MIN_BACKOFF_MILLIS = 10 * 1000; // 10 seconds. 51 52 private @NonNull UUID mId; 53 private @NonNull WorkSpec mWorkSpec; 54 private @NonNull Set<String> mTags; 55 56 /** 57 * @hide 58 */ 59 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) WorkRequest(@onNull UUID id, @NonNull WorkSpec workSpec, @NonNull Set<String> tags)60 protected WorkRequest(@NonNull UUID id, @NonNull WorkSpec workSpec, @NonNull Set<String> tags) { 61 mId = id; 62 mWorkSpec = workSpec; 63 mTags = tags; 64 } 65 66 /** 67 * Gets the unique identifier associated with this unit of work. 68 * 69 * @return The identifier for this unit of work 70 */ getId()71 public UUID getId() { 72 return mId; 73 } 74 75 /** 76 * Gets the string for the unique identifier associated with this unit of work. 77 * 78 * @return The string identifier for this unit of work 79 * @hide 80 */ 81 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) getStringId()82 public String getStringId() { 83 return mId.toString(); 84 } 85 86 /** 87 * Gets the {@link WorkSpec} associated with this unit of work. 88 * 89 * @return The {@link WorkSpec} for this unit of work 90 * @hide 91 */ 92 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) getWorkSpec()93 public WorkSpec getWorkSpec() { 94 return mWorkSpec; 95 } 96 97 /** 98 * Gets the tags associated with this unit of work. 99 * 100 * @return The tags for this unit of work 101 * @hide 102 */ 103 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) getTags()104 public Set<String> getTags() { 105 return mTags; 106 } 107 108 /** 109 * A builder for {@link WorkRequest}. 110 * 111 * @param <B> The concrete implementation of of this Builder 112 * @param <W> The type of work object built by this Builder 113 */ 114 public abstract static class Builder<B extends Builder, W extends WorkRequest> { 115 116 boolean mBackoffCriteriaSet = false; 117 UUID mId; 118 WorkSpec mWorkSpec; 119 Set<String> mTags = new HashSet<>(); 120 Builder(@onNull Class<? extends Worker> workerClass)121 public Builder(@NonNull Class<? extends Worker> workerClass) { 122 mId = UUID.randomUUID(); 123 mWorkSpec = new WorkSpec(mId.toString(), workerClass.getName()); 124 addTag(workerClass.getName()); 125 } 126 127 /** 128 * Change backoff policy and delay for the work. The default is 129 * {@link BackoffPolicy#EXPONENTIAL} and 130 * {@value WorkRequest#DEFAULT_BACKOFF_DELAY_MILLIS}. The maximum backoff delay 131 * duration is {@value WorkRequest#MAX_BACKOFF_MILLIS}. 132 * 133 * @param backoffPolicy The {@link BackoffPolicy} to use for work 134 * @param backoffDelay Time to wait before restarting {@link Worker} in {@code timeUnit} 135 * units 136 * @param timeUnit The {@link TimeUnit} for {@code backoffDelay} 137 * @return The current {@link Builder} 138 */ setBackoffCriteria( @onNull BackoffPolicy backoffPolicy, long backoffDelay, @NonNull TimeUnit timeUnit)139 public B setBackoffCriteria( 140 @NonNull BackoffPolicy backoffPolicy, 141 long backoffDelay, 142 @NonNull TimeUnit timeUnit) { 143 mBackoffCriteriaSet = true; 144 mWorkSpec.backoffPolicy = backoffPolicy; 145 mWorkSpec.setBackoffDelayDuration(timeUnit.toMillis(backoffDelay)); 146 return getThis(); 147 } 148 149 /** 150 * Add constraints to the {@link OneTimeWorkRequest}. 151 * 152 * @param constraints The constraints for the work 153 * @return The current {@link Builder} 154 */ setConstraints(@onNull Constraints constraints)155 public B setConstraints(@NonNull Constraints constraints) { 156 mWorkSpec.constraints = constraints; 157 return getThis(); 158 } 159 160 /** 161 * Add input {@link Data} to the work. 162 * 163 * @param inputData key/value pairs that will be provided to the {@link Worker} class 164 * @return The current {@link Builder} 165 */ setInputData(@onNull Data inputData)166 public B setInputData(@NonNull Data inputData) { 167 mWorkSpec.input = inputData; 168 return getThis(); 169 } 170 171 /** 172 * Add an optional tag for the work. This is particularly useful for modules or 173 * libraries who want to query for or cancel all of their own work. 174 * 175 * @param tag A tag for identifying the work in queries. 176 * @return The current {@link Builder} 177 */ addTag(@onNull String tag)178 public B addTag(@NonNull String tag) { 179 mTags.add(tag); 180 return getThis(); 181 } 182 183 /** 184 * Specifies that the results of this work should be kept for at least the specified amount 185 * of time. After this time has elapsed, the results may be pruned at the discretion of 186 * WorkManager when there are no pending dependent jobs. 187 * 188 * When the results of a work are pruned, it becomes impossible to query for its 189 * {@link WorkStatus}. 190 * 191 * Specifying a long duration here may adversely affect performance in terms of app storage 192 * and database query time. 193 * 194 * @param duration The minimum duration of time (in {@code timeUnit} units) to keep the 195 * results of this work 196 * @param timeUnit The unit of time for {@code duration} 197 * @return The current {@link Builder} 198 */ keepResultsForAtLeast(long duration, @NonNull TimeUnit timeUnit)199 public B keepResultsForAtLeast(long duration, @NonNull TimeUnit timeUnit) { 200 mWorkSpec.minimumRetentionDuration = timeUnit.toMillis(duration); 201 return getThis(); 202 } 203 204 /** 205 * Specifies that the results of this work should be kept for at least the specified amount 206 * of time. After this time has elapsed, the results may be pruned at the discretion of 207 * WorkManager when there are no pending dependent jobs. 208 * 209 * When the results of a work are pruned, it becomes impossible to query for its 210 * {@link WorkStatus}. 211 * 212 * Specifying a long duration here may adversely affect performance in terms of app storage 213 * and database query time. 214 * 215 * @param duration The minimum duration of time to keep the results of this work 216 * @return The current {@link Builder} 217 */ 218 @RequiresApi(26) keepResultsForAtLeast(@onNull Duration duration)219 public B keepResultsForAtLeast(@NonNull Duration duration) { 220 mWorkSpec.minimumRetentionDuration = duration.toMillis(); 221 return getThis(); 222 } 223 224 /** 225 * Builds this work object. 226 * 227 * @return The concrete implementation of the work associated with this builder 228 */ build()229 public abstract W build(); 230 getThis()231 abstract B getThis(); 232 233 /** 234 * Set the initial state for this work. Used in testing only. 235 * 236 * @param state The {@link State} to set 237 * @return The current {@link Builder} 238 * @hide 239 */ 240 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 241 @VisibleForTesting setInitialState(@onNull State state)242 public B setInitialState(@NonNull State state) { 243 mWorkSpec.state = state; 244 return getThis(); 245 } 246 247 /** 248 * Set the initial run attempt count for this work. Used in testing only. 249 * 250 * @param runAttemptCount The initial run attempt count 251 * @return The current {@link Builder} 252 * @hide 253 */ 254 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 255 @VisibleForTesting setInitialRunAttemptCount(int runAttemptCount)256 public B setInitialRunAttemptCount(int runAttemptCount) { 257 mWorkSpec.runAttemptCount = runAttemptCount; 258 return getThis(); 259 } 260 261 /** 262 * Set the period start time for this work. Used in testing only. 263 * 264 * @param periodStartTime the period start time in {@code timeUnit} units 265 * @param timeUnit The {@link TimeUnit} for {@code periodStartTime} 266 * @return The current {@link Builder} 267 * @hide 268 */ 269 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 270 @VisibleForTesting setPeriodStartTime(long periodStartTime, @NonNull TimeUnit timeUnit)271 public B setPeriodStartTime(long periodStartTime, @NonNull TimeUnit timeUnit) { 272 mWorkSpec.periodStartTime = timeUnit.toMillis(periodStartTime); 273 return getThis(); 274 } 275 276 /** 277 * Set when the scheduler actually schedules the worker. 278 * 279 * @param scheduleRequestedAt The time at which the scheduler scheduled a worker. 280 * @param timeUnit The {@link TimeUnit} for {@code scheduleRequestedAt} 281 * @return The current {@link Builder} 282 * @hide 283 */ 284 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 285 @VisibleForTesting setScheduleRequestedAt( long scheduleRequestedAt, @NonNull TimeUnit timeUnit)286 public B setScheduleRequestedAt( 287 long scheduleRequestedAt, 288 @NonNull TimeUnit timeUnit) { 289 mWorkSpec.scheduleRequestedAt = timeUnit.toMillis(scheduleRequestedAt); 290 return getThis(); 291 } 292 } 293 } 294