blob: 329e3c159bc8afed0ca1dc585853eca3bf81e11c [file] [log] [blame]
Sumir Kataria904ba122017-09-25 13:05:49 -07001/*
2 * Copyright (C) 2017 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
Sumir Kataria6d55d8c2017-12-07 13:37:42 -080017package android.arch.background.workmanager.impl.model;
Sumir Kataria904ba122017-09-25 13:05:49 -070018
Sumir Kataria96d3c9d2017-12-07 10:03:51 -080019import android.arch.background.workmanager.Arguments;
20import android.arch.background.workmanager.Constraints;
Sumir Kataria51dbe432017-12-06 10:52:48 -080021import android.arch.background.workmanager.impl.BaseWork;
Sumir Kataria904ba122017-09-25 13:05:49 -070022import android.arch.persistence.room.ColumnInfo;
23import android.arch.persistence.room.Embedded;
24import android.arch.persistence.room.Entity;
25import android.arch.persistence.room.PrimaryKey;
Sumir Kataria904ba122017-09-25 13:05:49 -070026import android.support.annotation.NonNull;
27
28/**
29 * Stores information about a logical unit of work.
30 */
31@Entity
Sumir Kataria904ba122017-09-25 13:05:49 -070032public class WorkSpec {
Xyan Bhatnagar367c6492017-10-06 11:20:02 -070033 private static final String TAG = "WorkSpec";
Sumir Kataria904ba122017-09-25 13:05:49 -070034
35 @ColumnInfo(name = "id")
36 @PrimaryKey
37 @NonNull
38 String mId;
39
Sumir Kataria904ba122017-09-25 13:05:49 -070040 @ColumnInfo(name = "status")
Sumir Kataria58e4d6f2017-11-14 14:31:15 -080041 @BaseWork.WorkStatus
42 int mStatus = BaseWork.STATUS_ENQUEUED;
Sumir Kataria904ba122017-09-25 13:05:49 -070043
Jan Clarinee302e12017-10-09 11:16:19 -070044 @ColumnInfo(name = "worker_class_name")
45 String mWorkerClassName;
46
Sumir Katariaa48d7ac2017-11-28 16:24:15 -080047 @ColumnInfo(name = "input_merger_class_name")
Sumir Kataria18aa0f02017-11-29 14:17:36 -080048 String mInputMergerClassName;
Sumir Katariaa48d7ac2017-11-28 16:24:15 -080049
Sumir Kataria9244d372017-11-30 13:39:07 -080050 @ColumnInfo(name = "arguments")
51 @NonNull
52 Arguments mArguments = Arguments.EMPTY;
53
54 @ColumnInfo(name = "output")
55 @NonNull
56 Arguments mOutput = Arguments.EMPTY;
57
Xyan Bhatnagara1af78b2017-10-04 17:36:36 -070058 @ColumnInfo(name = "initial_delay")
59 long mInitialDelay;
60
Jan Clarinee302e12017-10-09 11:16:19 -070061 @ColumnInfo(name = "interval_duration")
62 long mIntervalDuration;
63
64 @ColumnInfo(name = "flex_duration")
65 long mFlexDuration;
Sumir Kataria904ba122017-09-25 13:05:49 -070066
67 @Embedded
68 Constraints mConstraints = new Constraints.Builder().build();
69
Xyan Bhatnagar367c6492017-10-06 11:20:02 -070070 @ColumnInfo(name = "run_attempt_count")
71 int mRunAttemptCount;
72
Sumir Kataria904ba122017-09-25 13:05:49 -070073 // TODO(sumir): Should Backoff be disabled by default?
74 @ColumnInfo(name = "backoff_policy")
Sumir Kataria58e4d6f2017-11-14 14:31:15 -080075 @BaseWork.BackoffPolicy
76 int mBackoffPolicy = BaseWork.BACKOFF_POLICY_EXPONENTIAL;
Sumir Kataria904ba122017-09-25 13:05:49 -070077
78 @ColumnInfo(name = "backoff_delay_duration")
Xyan Bhatnagar3d9f4c62017-11-16 14:13:39 -080079 long mBackoffDelayDuration = BaseWork.DEFAULT_BACKOFF_DELAY_MILLIS;
Sumir Kataria904ba122017-09-25 13:05:49 -070080
Jan Clarin0deb5e22017-12-06 11:26:29 -080081 @ColumnInfo(name = "period_start_time")
82 long mPeriodStartTime;
83
Sumir Kataria904ba122017-09-25 13:05:49 -070084 public WorkSpec(@NonNull String id) {
85 mId = id;
86 }
87
88 @NonNull
89 public String getId() {
90 return mId;
91 }
92
93 public void setId(@NonNull String id) {
94 mId = id;
95 }
96
Sumir Kataria904ba122017-09-25 13:05:49 -070097 public int getStatus() {
98 return mStatus;
99 }
100
101 public void setStatus(int status) {
102 mStatus = status;
103 }
104
105 public String getWorkerClassName() {
106 return mWorkerClassName;
107 }
108
109 public void setWorkerClassName(String workerClassName) {
110 mWorkerClassName = workerClassName;
111 }
112
Sumir Katariaa48d7ac2017-11-28 16:24:15 -0800113 public String getInputMergerClassName() {
114 return mInputMergerClassName;
115 }
116
117 public void setInputMergerClassName(String inputMergerClassName) {
118 mInputMergerClassName = inputMergerClassName;
119 }
120
Sumir Kataria9244d372017-11-30 13:39:07 -0800121 public @NonNull Arguments getArguments() {
122 return mArguments;
123 }
124
125 public void setArguments(@NonNull Arguments arguments) {
126 mArguments = arguments;
127 }
128
129 public @NonNull Arguments getOutput() {
130 return mOutput;
131 }
132
133 public void setOutput(@NonNull Arguments output) {
134 mOutput = output;
135 }
136
Sumir Kataria904ba122017-09-25 13:05:49 -0700137 public Constraints getConstraints() {
138 return mConstraints;
139 }
140
141 public void setConstraints(Constraints constraints) {
142 mConstraints = constraints;
143 }
144
Sumir Kataria904ba122017-09-25 13:05:49 -0700145 public int getBackoffPolicy() {
146 return mBackoffPolicy;
147 }
148
149 public void setBackoffPolicy(int backoffPolicy) {
150 mBackoffPolicy = backoffPolicy;
151 }
152
153 public long getBackoffDelayDuration() {
154 return mBackoffDelayDuration;
155 }
156
157 public void setBackoffDelayDuration(long backoffDelayDuration) {
158 mBackoffDelayDuration = backoffDelayDuration;
159 }
Xyan Bhatnagara1af78b2017-10-04 17:36:36 -0700160
161 public long getInitialDelay() {
162 return mInitialDelay;
163 }
164
165 public void setInitialDelay(long initialDelay) {
166 mInitialDelay = initialDelay;
167 }
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700168
Jan Clarinee302e12017-10-09 11:16:19 -0700169 public boolean isPeriodic() {
170 return mIntervalDuration != 0L;
171 }
172
Sumir Kataria6d55d8c2017-12-07 13:37:42 -0800173 /**
174 * Sets the periodic interval for this unit of work.
175 *
176 * @param intervalDuration The interval in milliseconds
177 */
Jan Clarinee302e12017-10-09 11:16:19 -0700178 public void setPeriodic(long intervalDuration) {
179 setPeriodic(intervalDuration, intervalDuration);
180 }
181
Sumir Kataria6d55d8c2017-12-07 13:37:42 -0800182 /**
183 * Sets the periodic interval for this unit of work.
184 *
185 * @param intervalDuration The interval in milliseconds
186 * @param flexDuration The flex duration in milliseconds
187 */
Jan Clarinee302e12017-10-09 11:16:19 -0700188 public void setPeriodic(long intervalDuration, long flexDuration) {
189 mIntervalDuration = intervalDuration;
190 mFlexDuration = flexDuration;
191 }
192
193 public long getIntervalDuration() {
194 return mIntervalDuration;
195 }
196
197 public void setIntervalDuration(long intervalDuration) {
198 mIntervalDuration = intervalDuration;
199 }
200
201 public long getFlexDuration() {
202 return mFlexDuration;
203 }
204
205 public void setFlexDuration(long flexDuration) {
206 mFlexDuration = flexDuration;
207 }
208
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700209 public void setRunAttemptCount(int runAttemptCount) {
210 this.mRunAttemptCount = runAttemptCount;
211 }
212
213 public int getRunAttemptCount() {
214 return mRunAttemptCount;
215 }
216
217 /**
Jan Clarin0deb5e22017-12-06 11:26:29 -0800218 * For one-off work, this is the time that the work was unblocked by prerequisites.
219 * For periodic work, this is the time that the period started.
220 */
221 public long getPeriodStartTime() {
222 return mPeriodStartTime;
223 }
224
225 public void setPeriodStartTime(long periodStartTime) {
226 mPeriodStartTime = periodStartTime;
227 }
228
229 /**
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700230 * Calculates delay with which this Work item should be executed.
231 *
Sumir Kataria58e4d6f2017-11-14 14:31:15 -0800232 * If the run attempt count is 0, the initial delay is returned.
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700233 *
Sumir Kataria58e4d6f2017-11-14 14:31:15 -0800234 * If Backoff Policy is set to {@link BaseWork#BACKOFF_POLICY_EXPONENTIAL}, then delay
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700235 * increases at an exponential rate with respect to the run attempt count and is capped at
Xyan Bhatnagar3d9f4c62017-11-16 14:13:39 -0800236 * {@link BaseWork#MAX_BACKOFF_MILLIS}.
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700237 *
Sumir Kataria58e4d6f2017-11-14 14:31:15 -0800238 * if Backoff Policy is set to {@link BaseWork#BACKOFF_POLICY_LINEAR}, then delay
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700239 * increases at an linear rate with respect to the run attempt count and is capped at
Xyan Bhatnagar3d9f4c62017-11-16 14:13:39 -0800240 * {@link BaseWork#MAX_BACKOFF_MILLIS}.
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700241 *
242 * Based on {@see https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/job/JobSchedulerService.java#1125}
243 *
Sumir Kataria58e4d6f2017-11-14 14:31:15 -0800244 * Note that this delay is for WorkManager internal use and may not match what the OS considers
245 * to be the current delay.
246 *
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700247 * @return non-negative delay to execute this item with (in milliseconds)
248 */
249 public long calculateDelay() {
250 if (mRunAttemptCount <= 0) {
251 return mInitialDelay;
252 }
253 long delay;
Sumir Kataria58e4d6f2017-11-14 14:31:15 -0800254 if (mBackoffPolicy == BaseWork.BACKOFF_POLICY_LINEAR) {
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700255 delay = mBackoffDelayDuration * mRunAttemptCount;
256 } else {
257 // default to exponential backoff policy
258 delay = (long) Math.scalb(mBackoffDelayDuration, mRunAttemptCount - 1);
259 }
Xyan Bhatnagar3d9f4c62017-11-16 14:13:39 -0800260 return Math.min(BaseWork.MAX_BACKOFF_MILLIS, delay);
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700261 }
Jan Clarin91bccff2017-10-20 17:51:10 -0700262
263 @Override
264 public boolean equals(Object o) {
265 if (this == o) {
266 return true;
267 }
268 if (o == null || getClass() != o.getClass()) {
269 return false;
270 }
271 WorkSpec other = (WorkSpec) o;
272 return mId.equals(other.mId)
273 && mStatus == other.mStatus
274 && mInitialDelay == other.mInitialDelay
275 && mIntervalDuration == other.mIntervalDuration
276 && mFlexDuration == other.mFlexDuration
277 && mRunAttemptCount == other.mRunAttemptCount
278 && mBackoffPolicy == other.mBackoffPolicy
279 && mBackoffDelayDuration == other.mBackoffDelayDuration
Sumir Kataria9244d372017-11-30 13:39:07 -0800280 && mArguments.equals(other.mArguments)
281 && mOutput.equals(other.mOutput)
Jan Clarin91bccff2017-10-20 17:51:10 -0700282 && (mWorkerClassName != null
283 ? mWorkerClassName.equals(other.mWorkerClassName)
284 : other.mWorkerClassName == null)
Sumir Katariaa48d7ac2017-11-28 16:24:15 -0800285 && (mInputMergerClassName != null
286 ? mInputMergerClassName.equals(other.mInputMergerClassName)
287 : other.mInputMergerClassName == null)
Jan Clarin91bccff2017-10-20 17:51:10 -0700288 && (mConstraints != null
289 ? mConstraints.equals(other.mConstraints)
Sumir Kataria9e637902017-11-27 14:03:47 -0800290 : other.mConstraints == null);
Jan Clarin91bccff2017-10-20 17:51:10 -0700291 }
292
293 @Override
294 public int hashCode() {
295 int result = mId.hashCode();
296 result = 31 * result + mStatus;
297 result = 31 * result + (mWorkerClassName != null ? mWorkerClassName.hashCode() : 0);
Sumir Katariaa48d7ac2017-11-28 16:24:15 -0800298 result = 31 * result
299 + (mInputMergerClassName != null ? mInputMergerClassName.hashCode() : 0);
Sumir Kataria9244d372017-11-30 13:39:07 -0800300 result = 31 * result + mArguments.hashCode();
301 result = 31 * result + mOutput.hashCode();
Jan Clarin91bccff2017-10-20 17:51:10 -0700302 result = 31 * result + (int) (mInitialDelay ^ (mInitialDelay >>> 32));
303 result = 31 * result + (int) (mIntervalDuration ^ (mIntervalDuration >>> 32));
304 result = 31 * result + (int) (mFlexDuration ^ (mFlexDuration >>> 32));
305 result = 31 * result + (mConstraints != null ? mConstraints.hashCode() : 0);
Jan Clarin91bccff2017-10-20 17:51:10 -0700306 result = 31 * result + mRunAttemptCount;
307 result = 31 * result + mBackoffPolicy;
308 result = 31 * result + (int) (mBackoffDelayDuration ^ (mBackoffDelayDuration >>> 32));
309 return result;
310 }
Xyan Bhatnagarbbe9f312017-11-16 10:31:14 -0800311
312 @Override
313 public String toString() {
314 return "{WorkSpec: " + mId + "}";
315 }
Sumir Kataria904ba122017-09-25 13:05:49 -0700316}