blob: b3e1ba21bf21d5329fc4d0f9f56a4e41372a6339 [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
17package android.arch.background.workmanager.model;
18
Sumir Kataria58e4d6f2017-11-14 14:31:15 -080019import android.arch.background.workmanager.BaseWork;
Sumir Kataria904ba122017-09-25 13:05:49 -070020import android.arch.persistence.room.ColumnInfo;
21import android.arch.persistence.room.Embedded;
22import android.arch.persistence.room.Entity;
23import android.arch.persistence.room.PrimaryKey;
24import android.arch.persistence.room.TypeConverters;
25import android.support.annotation.NonNull;
26
27/**
28 * Stores information about a logical unit of work.
29 */
30@Entity
Xyan Bhatnagar1a294232017-10-25 13:08:48 -070031@TypeConverters(value = {Arguments.class, ContentUriTriggers.class})
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
Xyan Bhatnagara1af78b2017-10-04 17:36:36 -070047 @ColumnInfo(name = "initial_delay")
48 long mInitialDelay;
49
Jan Clarinee302e12017-10-09 11:16:19 -070050 @ColumnInfo(name = "interval_duration")
51 long mIntervalDuration;
52
53 @ColumnInfo(name = "flex_duration")
54 long mFlexDuration;
Sumir Kataria904ba122017-09-25 13:05:49 -070055
56 @Embedded
57 Constraints mConstraints = new Constraints.Builder().build();
58
59 Arguments mArguments = new Arguments();
60
Sumir Kataria1f78b6252017-11-01 10:15:05 -070061 @ColumnInfo(name = "tag")
Sumir Kataria904ba122017-09-25 13:05:49 -070062 String mTag;
63
Xyan Bhatnagar367c6492017-10-06 11:20:02 -070064 @ColumnInfo(name = "run_attempt_count")
65 int mRunAttemptCount;
66
Sumir Kataria904ba122017-09-25 13:05:49 -070067 // TODO(sumir): Should Backoff be disabled by default?
68 @ColumnInfo(name = "backoff_policy")
Sumir Kataria58e4d6f2017-11-14 14:31:15 -080069 @BaseWork.BackoffPolicy
70 int mBackoffPolicy = BaseWork.BACKOFF_POLICY_EXPONENTIAL;
Sumir Kataria904ba122017-09-25 13:05:49 -070071
72 @ColumnInfo(name = "backoff_delay_duration")
Sumir Kataria58e4d6f2017-11-14 14:31:15 -080073 long mBackoffDelayDuration = BaseWork.DEFAULT_BACKOFF_DELAY_DURATION;
Sumir Kataria904ba122017-09-25 13:05:49 -070074
75 public WorkSpec(@NonNull String id) {
76 mId = id;
77 }
78
79 @NonNull
80 public String getId() {
81 return mId;
82 }
83
84 public void setId(@NonNull String id) {
85 mId = id;
86 }
87
Sumir Kataria904ba122017-09-25 13:05:49 -070088 public int getStatus() {
89 return mStatus;
90 }
91
92 public void setStatus(int status) {
93 mStatus = status;
94 }
95
96 public String getWorkerClassName() {
97 return mWorkerClassName;
98 }
99
100 public void setWorkerClassName(String workerClassName) {
101 mWorkerClassName = workerClassName;
102 }
103
104 public Constraints getConstraints() {
105 return mConstraints;
106 }
107
108 public void setConstraints(Constraints constraints) {
109 mConstraints = constraints;
110 }
111
112 public Arguments getArguments() {
113 return mArguments;
114 }
115
116 public void setArguments(Arguments arguments) {
117 mArguments = arguments;
118 }
119
120 public String getTag() {
121 return mTag;
122 }
123
124 public void setTag(String tag) {
125 mTag = tag;
126 }
127
128 public int getBackoffPolicy() {
129 return mBackoffPolicy;
130 }
131
132 public void setBackoffPolicy(int backoffPolicy) {
133 mBackoffPolicy = backoffPolicy;
134 }
135
136 public long getBackoffDelayDuration() {
137 return mBackoffDelayDuration;
138 }
139
140 public void setBackoffDelayDuration(long backoffDelayDuration) {
141 mBackoffDelayDuration = backoffDelayDuration;
142 }
Xyan Bhatnagara1af78b2017-10-04 17:36:36 -0700143
144 public long getInitialDelay() {
145 return mInitialDelay;
146 }
147
148 public void setInitialDelay(long initialDelay) {
149 mInitialDelay = initialDelay;
150 }
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700151
Jan Clarinee302e12017-10-09 11:16:19 -0700152 public boolean isPeriodic() {
153 return mIntervalDuration != 0L;
154 }
155
156 public void setPeriodic(long intervalDuration) {
157 setPeriodic(intervalDuration, intervalDuration);
158 }
159
160 public void setPeriodic(long intervalDuration, long flexDuration) {
161 mIntervalDuration = intervalDuration;
162 mFlexDuration = flexDuration;
163 }
164
165 public long getIntervalDuration() {
166 return mIntervalDuration;
167 }
168
169 public void setIntervalDuration(long intervalDuration) {
170 mIntervalDuration = intervalDuration;
171 }
172
173 public long getFlexDuration() {
174 return mFlexDuration;
175 }
176
177 public void setFlexDuration(long flexDuration) {
178 mFlexDuration = flexDuration;
179 }
180
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700181 public void setRunAttemptCount(int runAttemptCount) {
182 this.mRunAttemptCount = runAttemptCount;
183 }
184
185 public int getRunAttemptCount() {
186 return mRunAttemptCount;
187 }
188
189 /**
190 * Calculates delay with which this Work item should be executed.
191 *
Sumir Kataria58e4d6f2017-11-14 14:31:15 -0800192 * If the run attempt count is 0, the initial delay is returned.
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700193 *
Sumir Kataria58e4d6f2017-11-14 14:31:15 -0800194 * If Backoff Policy is set to {@link BaseWork#BACKOFF_POLICY_EXPONENTIAL}, then delay
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700195 * increases at an exponential rate with respect to the run attempt count and is capped at
Sumir Kataria58e4d6f2017-11-14 14:31:15 -0800196 * {@link BaseWork#MAX_BACKOFF_DURATION}.
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700197 *
Sumir Kataria58e4d6f2017-11-14 14:31:15 -0800198 * if Backoff Policy is set to {@link BaseWork#BACKOFF_POLICY_LINEAR}, then delay
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700199 * increases at an linear rate with respect to the run attempt count and is capped at
Sumir Kataria58e4d6f2017-11-14 14:31:15 -0800200 * {@link BaseWork#MAX_BACKOFF_DURATION}.
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700201 *
202 * Based on {@see https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/job/JobSchedulerService.java#1125}
203 *
Sumir Kataria58e4d6f2017-11-14 14:31:15 -0800204 * Note that this delay is for WorkManager internal use and may not match what the OS considers
205 * to be the current delay.
206 *
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700207 * @return non-negative delay to execute this item with (in milliseconds)
208 */
209 public long calculateDelay() {
210 if (mRunAttemptCount <= 0) {
211 return mInitialDelay;
212 }
213 long delay;
Sumir Kataria58e4d6f2017-11-14 14:31:15 -0800214 if (mBackoffPolicy == BaseWork.BACKOFF_POLICY_LINEAR) {
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700215 delay = mBackoffDelayDuration * mRunAttemptCount;
216 } else {
217 // default to exponential backoff policy
218 delay = (long) Math.scalb(mBackoffDelayDuration, mRunAttemptCount - 1);
219 }
Sumir Kataria58e4d6f2017-11-14 14:31:15 -0800220 return Math.min(BaseWork.MAX_BACKOFF_DURATION, delay);
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700221 }
Jan Clarin91bccff2017-10-20 17:51:10 -0700222
223 @Override
224 public boolean equals(Object o) {
225 if (this == o) {
226 return true;
227 }
228 if (o == null || getClass() != o.getClass()) {
229 return false;
230 }
231 WorkSpec other = (WorkSpec) o;
232 return mId.equals(other.mId)
233 && mStatus == other.mStatus
234 && mInitialDelay == other.mInitialDelay
235 && mIntervalDuration == other.mIntervalDuration
236 && mFlexDuration == other.mFlexDuration
237 && mRunAttemptCount == other.mRunAttemptCount
238 && mBackoffPolicy == other.mBackoffPolicy
239 && mBackoffDelayDuration == other.mBackoffDelayDuration
240 && (mWorkerClassName != null
241 ? mWorkerClassName.equals(other.mWorkerClassName)
242 : other.mWorkerClassName == null)
243 && (mConstraints != null
244 ? mConstraints.equals(other.mConstraints)
245 : other.mConstraints == null)
246 && (mArguments != null
247 ? mArguments.equals(other.mArguments)
248 : other.mArguments == null)
249 && (mTag != null ? mTag.equals(other.mTag) : other.mTag == null);
250 }
251
252 @Override
253 public int hashCode() {
254 int result = mId.hashCode();
255 result = 31 * result + mStatus;
256 result = 31 * result + (mWorkerClassName != null ? mWorkerClassName.hashCode() : 0);
257 result = 31 * result + (int) (mInitialDelay ^ (mInitialDelay >>> 32));
258 result = 31 * result + (int) (mIntervalDuration ^ (mIntervalDuration >>> 32));
259 result = 31 * result + (int) (mFlexDuration ^ (mFlexDuration >>> 32));
260 result = 31 * result + (mConstraints != null ? mConstraints.hashCode() : 0);
261 result = 31 * result + (mArguments != null ? mArguments.hashCode() : 0);
262 result = 31 * result + (mTag != null ? mTag.hashCode() : 0);
263 result = 31 * result + mRunAttemptCount;
264 result = 31 * result + mBackoffPolicy;
265 result = 31 * result + (int) (mBackoffDelayDuration ^ (mBackoffDelayDuration >>> 32));
266 return result;
267 }
Xyan Bhatnagarbbe9f312017-11-16 10:31:14 -0800268
269 @Override
270 public String toString() {
271 return "{WorkSpec: " + mId + "}";
272 }
Sumir Kataria904ba122017-09-25 13:05:49 -0700273}