Home | History | Annotate | Download | only in work
      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)
     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      */
     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)
     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)
     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)
    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 
    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          */
    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          */
    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          */
    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          */
    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          */
    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)
    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          */
    229         public abstract W build();
    230 
    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
    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
    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
    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
    286         public B setScheduleRequestedAt(
    287                 long scheduleRequestedAt,
    288                 @NonNull TimeUnit timeUnit) {
    289             mWorkSpec.scheduleRequestedAt = timeUnit.toMillis(scheduleRequestedAt);
    290             return getThis();
    291         }
    292     }
    293 }
    294