blob: 216340ee1578382439d988186e85bc85e7178b02 [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 Kataria564e4302018-02-14 11:22:30 -080017package androidx.work.impl.model;
Sumir Kataria904ba122017-09-25 13:05:49 -070018
Sumir Kataria564e4302018-02-14 11:22:30 -080019import static androidx.work.BaseWork.MAX_BACKOFF_MILLIS;
20import static androidx.work.BaseWork.MIN_BACKOFF_MILLIS;
21import static androidx.work.PeriodicWork.MIN_PERIODIC_FLEX_MILLIS;
22import static androidx.work.PeriodicWork.MIN_PERIODIC_INTERVAL_MILLIS;
23import static androidx.work.State.ENQUEUED;
Sumir Kataria1cd0e4e2017-12-12 10:53:46 -080024
Sumir Kataria4401f792018-03-20 12:52:38 -070025import android.arch.core.util.Function;
Sumir Kataria904ba122017-09-25 13:05:49 -070026import android.arch.persistence.room.ColumnInfo;
27import android.arch.persistence.room.Embedded;
28import android.arch.persistence.room.Entity;
Rahul Ravikumar9f91ee82018-03-20 17:33:38 -070029import android.arch.persistence.room.Index;
Sumir Kataria904ba122017-09-25 13:05:49 -070030import android.arch.persistence.room.PrimaryKey;
Sumir Katariacc5ae8c2018-03-12 12:57:46 -070031import android.arch.persistence.room.Relation;
Sumir Kataria904ba122017-09-25 13:05:49 -070032import android.support.annotation.NonNull;
Sumir Katariab5728f42018-03-19 12:58:41 -070033import android.support.annotation.RestrictTo;
Sumir Katariacc5ae8c2018-03-12 12:57:46 -070034
Sumir Kataria564e4302018-02-14 11:22:30 -080035import androidx.work.Arguments;
36import androidx.work.BackoffPolicy;
37import androidx.work.BaseWork;
38import androidx.work.Constraints;
39import androidx.work.State;
Sumir Katariacc5ae8c2018-03-12 12:57:46 -070040import androidx.work.WorkStatus;
Sumir Kataria564e4302018-02-14 11:22:30 -080041import androidx.work.impl.logger.Logger;
42
Sumir Kataria4401f792018-03-20 12:52:38 -070043import java.util.ArrayList;
Sumir Katariab5728f42018-03-19 12:58:41 -070044import java.util.List;
45
Sumir Kataria904ba122017-09-25 13:05:49 -070046/**
47 * Stores information about a logical unit of work.
Sumir Katariab5728f42018-03-19 12:58:41 -070048 *
49 * @hide
Sumir Kataria904ba122017-09-25 13:05:49 -070050 */
Sumir Katariab5728f42018-03-19 12:58:41 -070051@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
Rahul Ravikumar9f91ee82018-03-20 17:33:38 -070052@Entity(
53 indices = {@Index(value = {"schedule_requested_at"})}
54)
Sumir Kataria904ba122017-09-25 13:05:49 -070055public class WorkSpec {
Xyan Bhatnagar367c6492017-10-06 11:20:02 -070056 private static final String TAG = "WorkSpec";
Rahul Ravikumar9f91ee82018-03-20 17:33:38 -070057 public static final long SCHEDULE_NOT_REQUESTED_YET = -1;
Sumir Kataria904ba122017-09-25 13:05:49 -070058
59 @ColumnInfo(name = "id")
60 @PrimaryKey
61 @NonNull
Sumir Katariab5728f42018-03-19 12:58:41 -070062 public String id;
Sumir Kataria904ba122017-09-25 13:05:49 -070063
Sumir Kataria9cf4f3d2018-02-06 09:57:51 -080064 @ColumnInfo(name = "state")
Sumir Kataria86894df2018-03-06 15:11:16 -080065 @NonNull
Sumir Katariab5728f42018-03-19 12:58:41 -070066 public State state = ENQUEUED;
Sumir Kataria904ba122017-09-25 13:05:49 -070067
Jan Clarinee302e12017-10-09 11:16:19 -070068 @ColumnInfo(name = "worker_class_name")
Sumir Kataria86894df2018-03-06 15:11:16 -080069 @NonNull
Sumir Katariab5728f42018-03-19 12:58:41 -070070 public String workerClassName;
Jan Clarinee302e12017-10-09 11:16:19 -070071
Sumir Katariaa48d7ac2017-11-28 16:24:15 -080072 @ColumnInfo(name = "input_merger_class_name")
Sumir Katariab5728f42018-03-19 12:58:41 -070073 public String inputMergerClassName;
Sumir Katariaa48d7ac2017-11-28 16:24:15 -080074
Sumir Kataria9244d372017-11-30 13:39:07 -080075 @ColumnInfo(name = "arguments")
76 @NonNull
Sumir Katariab5728f42018-03-19 12:58:41 -070077 public Arguments arguments = Arguments.EMPTY;
Sumir Kataria9244d372017-11-30 13:39:07 -080078
79 @ColumnInfo(name = "output")
80 @NonNull
Sumir Katariab5728f42018-03-19 12:58:41 -070081 public Arguments output = Arguments.EMPTY;
Sumir Kataria9244d372017-11-30 13:39:07 -080082
Xyan Bhatnagara1af78b2017-10-04 17:36:36 -070083 @ColumnInfo(name = "initial_delay")
Sumir Katariab5728f42018-03-19 12:58:41 -070084 public long initialDelay;
Xyan Bhatnagara1af78b2017-10-04 17:36:36 -070085
Jan Clarinee302e12017-10-09 11:16:19 -070086 @ColumnInfo(name = "interval_duration")
Sumir Katariab5728f42018-03-19 12:58:41 -070087 public long intervalDuration;
Jan Clarinee302e12017-10-09 11:16:19 -070088
89 @ColumnInfo(name = "flex_duration")
Sumir Katariab5728f42018-03-19 12:58:41 -070090 public long flexDuration;
Sumir Kataria904ba122017-09-25 13:05:49 -070091
92 @Embedded
Sumir Kataria86894df2018-03-06 15:11:16 -080093 @NonNull
Sumir Katariab5728f42018-03-19 12:58:41 -070094 public Constraints constraints = Constraints.NONE;
Sumir Kataria904ba122017-09-25 13:05:49 -070095
Xyan Bhatnagar367c6492017-10-06 11:20:02 -070096 @ColumnInfo(name = "run_attempt_count")
Sumir Katariab5728f42018-03-19 12:58:41 -070097 public int runAttemptCount;
Xyan Bhatnagar367c6492017-10-06 11:20:02 -070098
Sumir Kataria904ba122017-09-25 13:05:49 -070099 @ColumnInfo(name = "backoff_policy")
Sumir Kataria86894df2018-03-06 15:11:16 -0800100 @NonNull
Sumir Katariab5728f42018-03-19 12:58:41 -0700101 public BackoffPolicy backoffPolicy = BackoffPolicy.EXPONENTIAL;
Sumir Kataria904ba122017-09-25 13:05:49 -0700102
103 @ColumnInfo(name = "backoff_delay_duration")
Sumir Katariab5728f42018-03-19 12:58:41 -0700104 public long backoffDelayDuration = BaseWork.DEFAULT_BACKOFF_DELAY_MILLIS;
Sumir Kataria904ba122017-09-25 13:05:49 -0700105
Sumir Katariab5728f42018-03-19 12:58:41 -0700106 /**
107 * For one-off work, this is the time that the work was unblocked by prerequisites.
108 * For periodic work, this is the time that the period started.
109 */
Jan Clarin0deb5e22017-12-06 11:26:29 -0800110 @ColumnInfo(name = "period_start_time")
Sumir Katariab5728f42018-03-19 12:58:41 -0700111 public long periodStartTime;
Jan Clarin0deb5e22017-12-06 11:26:29 -0800112
Sumir Kataria3d5949e2018-03-06 13:32:20 -0800113 @ColumnInfo(name = "minimum_retention_duration")
Sumir Katariab5728f42018-03-19 12:58:41 -0700114 public long minimumRetentionDuration;
Sumir Kataria3d5949e2018-03-06 13:32:20 -0800115
Rahul Ravikumar9f91ee82018-03-20 17:33:38 -0700116 @ColumnInfo(name = "schedule_requested_at")
117 public long scheduleRequestedAt = SCHEDULE_NOT_REQUESTED_YET;
118
Sumir Katariab5728f42018-03-19 12:58:41 -0700119 public WorkSpec(@NonNull String id, @NonNull String workerClassName) {
120 this.id = id;
121 this.workerClassName = workerClassName;
Sumir Kataria904ba122017-09-25 13:05:49 -0700122 }
123
Sumir Kataria564e4302018-02-14 11:22:30 -0800124 /**
125 * @param backoffDelayDuration The backoff delay duration in milliseconds
126 */
Sumir Kataria904ba122017-09-25 13:05:49 -0700127 public void setBackoffDelayDuration(long backoffDelayDuration) {
Sumir Kataria1cd0e4e2017-12-12 10:53:46 -0800128 if (backoffDelayDuration > MAX_BACKOFF_MILLIS) {
Rahul Ravikumara9affbd2018-01-26 10:09:27 -0800129 Logger.warn(TAG, "Backoff delay duration exceeds maximum value");
Sumir Kataria1cd0e4e2017-12-12 10:53:46 -0800130 backoffDelayDuration = MAX_BACKOFF_MILLIS;
131 }
132 if (backoffDelayDuration < MIN_BACKOFF_MILLIS) {
Rahul Ravikumara9affbd2018-01-26 10:09:27 -0800133 Logger.warn(TAG, "Backoff delay duration less than minimum value");
Sumir Kataria1cd0e4e2017-12-12 10:53:46 -0800134 backoffDelayDuration = MIN_BACKOFF_MILLIS;
135 }
Sumir Katariab5728f42018-03-19 12:58:41 -0700136 this.backoffDelayDuration = backoffDelayDuration;
Sumir Kataria904ba122017-09-25 13:05:49 -0700137 }
Xyan Bhatnagara1af78b2017-10-04 17:36:36 -0700138
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700139
Jan Clarinee302e12017-10-09 11:16:19 -0700140 public boolean isPeriodic() {
Sumir Katariab5728f42018-03-19 12:58:41 -0700141 return intervalDuration != 0L;
Jan Clarinee302e12017-10-09 11:16:19 -0700142 }
143
Xyan Bhatnagar1c78bb22017-12-08 15:48:19 -0800144 public boolean isBackedOff() {
Sumir Katariab5728f42018-03-19 12:58:41 -0700145 return state == ENQUEUED && runAttemptCount > 0;
Xyan Bhatnagar1c78bb22017-12-08 15:48:19 -0800146 }
147
Sumir Kataria6d55d8c2017-12-07 13:37:42 -0800148 /**
149 * Sets the periodic interval for this unit of work.
150 *
151 * @param intervalDuration The interval in milliseconds
152 */
Jan Clarinee302e12017-10-09 11:16:19 -0700153 public void setPeriodic(long intervalDuration) {
Sumir Kataria1cd0e4e2017-12-12 10:53:46 -0800154 if (intervalDuration < MIN_PERIODIC_INTERVAL_MILLIS) {
Rahul Ravikumara9affbd2018-01-26 10:09:27 -0800155 Logger.warn(TAG, "Interval duration lesser than minimum allowed value; Changed to %s",
156 MIN_PERIODIC_INTERVAL_MILLIS);
Sumir Kataria1cd0e4e2017-12-12 10:53:46 -0800157 intervalDuration = MIN_PERIODIC_INTERVAL_MILLIS;
158 }
Jan Clarinee302e12017-10-09 11:16:19 -0700159 setPeriodic(intervalDuration, intervalDuration);
160 }
161
Sumir Kataria6d55d8c2017-12-07 13:37:42 -0800162 /**
163 * Sets the periodic interval for this unit of work.
164 *
165 * @param intervalDuration The interval in milliseconds
166 * @param flexDuration The flex duration in milliseconds
167 */
Jan Clarinee302e12017-10-09 11:16:19 -0700168 public void setPeriodic(long intervalDuration, long flexDuration) {
Sumir Kataria1cd0e4e2017-12-12 10:53:46 -0800169 if (intervalDuration < MIN_PERIODIC_INTERVAL_MILLIS) {
Rahul Ravikumara9affbd2018-01-26 10:09:27 -0800170 Logger.warn(TAG, "Interval duration lesser than minimum allowed value; Changed to %s",
171 MIN_PERIODIC_INTERVAL_MILLIS);
Sumir Kataria1cd0e4e2017-12-12 10:53:46 -0800172 intervalDuration = MIN_PERIODIC_INTERVAL_MILLIS;
173 }
174 if (flexDuration < MIN_PERIODIC_FLEX_MILLIS) {
Rahul Ravikumara9affbd2018-01-26 10:09:27 -0800175 Logger.warn(TAG, "Flex duration lesser than minimum allowed value; Changed to %s",
176 MIN_PERIODIC_FLEX_MILLIS);
Sumir Kataria1cd0e4e2017-12-12 10:53:46 -0800177 flexDuration = MIN_PERIODIC_FLEX_MILLIS;
178 }
179 if (flexDuration > intervalDuration) {
Rahul Ravikumara9affbd2018-01-26 10:09:27 -0800180 Logger.warn(TAG, "Flex duration greater than interval duration; Changed to %s",
181 intervalDuration);
Sumir Kataria1cd0e4e2017-12-12 10:53:46 -0800182 flexDuration = intervalDuration;
183 }
Sumir Katariab5728f42018-03-19 12:58:41 -0700184 this.intervalDuration = intervalDuration;
185 this.flexDuration = flexDuration;
Sumir Kataria3d5949e2018-03-06 13:32:20 -0800186 }
187
Jan Clarin0deb5e22017-12-06 11:26:29 -0800188 /**
Xyan Bhatnagar1c78bb22017-12-08 15:48:19 -0800189 * Calculates the UTC time at which this {@link WorkSpec} should be allowed to run.
190 * This method accounts for work that is backed off or periodic.
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700191 *
Sumir Katariab6430f22018-02-05 13:45:22 -0800192 * If Backoff Policy is set to {@link BackoffPolicy#EXPONENTIAL}, then delay
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700193 * increases at an exponential rate with respect to the run attempt count and is capped at
Sumir Kataria3032a522017-12-12 15:28:37 -0800194 * {@link BaseWork#MAX_BACKOFF_MILLIS}.
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700195 *
Sumir Katariab6430f22018-02-05 13:45:22 -0800196 * If Backoff Policy is set to {@link BackoffPolicy#LINEAR}, then delay
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700197 * increases at an linear rate with respect to the run attempt count and is capped at
Sumir Kataria3032a522017-12-12 15:28:37 -0800198 * {@link BaseWork#MAX_BACKOFF_MILLIS}.
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700199 *
200 * Based on {@see https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/job/JobSchedulerService.java#1125}
201 *
Xyan Bhatnagar1c78bb22017-12-08 15:48:19 -0800202 * Note that this runtime is for WorkManager internal use and may not match what the OS
203 * considers to be the next runtime.
Sumir Kataria58e4d6f2017-11-14 14:31:15 -0800204 *
Xyan Bhatnagar1c78bb22017-12-08 15:48:19 -0800205 * For jobs with constraints, this represents the earliest time at which constraints
206 * should be monitored for this work.
207 *
208 * For jobs without constraints, this represents the earliest time at which this work is
209 * allowed to run.
210 *
211 * @return UTC time at which this {@link WorkSpec} should be allowed to run.
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700212 */
Xyan Bhatnagar1c78bb22017-12-08 15:48:19 -0800213 public long calculateNextRunTime() {
214 if (isBackedOff()) {
Sumir Katariab5728f42018-03-19 12:58:41 -0700215 boolean isLinearBackoff = (backoffPolicy == BackoffPolicy.LINEAR);
216 long delay = isLinearBackoff ? (backoffDelayDuration * runAttemptCount)
217 : (long) Math.scalb(backoffDelayDuration, runAttemptCount - 1);
218 return periodStartTime + Math.min(BaseWork.MAX_BACKOFF_MILLIS, delay);
Xyan Bhatnagar1c78bb22017-12-08 15:48:19 -0800219 } else if (isPeriodic()) {
Sumir Katariab5728f42018-03-19 12:58:41 -0700220 return periodStartTime + intervalDuration - flexDuration;
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700221 } else {
Sumir Katariab5728f42018-03-19 12:58:41 -0700222 return periodStartTime + initialDelay;
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700223 }
Xyan Bhatnagar367c6492017-10-06 11:20:02 -0700224 }
Jan Clarin91bccff2017-10-20 17:51:10 -0700225
Rahul Ravikumare92262f2018-02-07 18:48:15 -0800226 /**
227 * @return <code>true</code> if the {@link WorkSpec} has constraints.
228 */
229 public boolean hasConstraints() {
Sumir Katariab5728f42018-03-19 12:58:41 -0700230 return !Constraints.NONE.equals(constraints);
Rahul Ravikumare92262f2018-02-07 18:48:15 -0800231 }
232
Jan Clarin91bccff2017-10-20 17:51:10 -0700233 @Override
234 public boolean equals(Object o) {
Sumir Kataria86894df2018-03-06 15:11:16 -0800235 if (this == o) return true;
236 if (o == null || getClass() != o.getClass()) return false;
237
238 WorkSpec workSpec = (WorkSpec) o;
239
Sumir Katariab5728f42018-03-19 12:58:41 -0700240 if (initialDelay != workSpec.initialDelay) return false;
241 if (intervalDuration != workSpec.intervalDuration) return false;
242 if (flexDuration != workSpec.flexDuration) return false;
243 if (runAttemptCount != workSpec.runAttemptCount) return false;
244 if (backoffDelayDuration != workSpec.backoffDelayDuration) return false;
245 if (periodStartTime != workSpec.periodStartTime) return false;
246 if (minimumRetentionDuration != workSpec.minimumRetentionDuration) return false;
Rahul Ravikumar9f91ee82018-03-20 17:33:38 -0700247 if (scheduleRequestedAt != workSpec.scheduleRequestedAt) return false;
Sumir Katariab5728f42018-03-19 12:58:41 -0700248 if (!id.equals(workSpec.id)) return false;
249 if (state != workSpec.state) return false;
250 if (!workerClassName.equals(workSpec.workerClassName)) return false;
251 if (inputMergerClassName != null ? !inputMergerClassName.equals(
Rahul Ravikumar9f91ee82018-03-20 17:33:38 -0700252 workSpec.inputMergerClassName)
253 : workSpec.inputMergerClassName != null) {
Jan Clarin91bccff2017-10-20 17:51:10 -0700254 return false;
255 }
Sumir Katariab5728f42018-03-19 12:58:41 -0700256 if (!arguments.equals(workSpec.arguments)) return false;
257 if (!output.equals(workSpec.output)) return false;
258 if (!constraints.equals(workSpec.constraints)) return false;
259 return backoffPolicy == workSpec.backoffPolicy;
Jan Clarin91bccff2017-10-20 17:51:10 -0700260 }
261
262 @Override
263 public int hashCode() {
Sumir Katariab5728f42018-03-19 12:58:41 -0700264 int result = id.hashCode();
265 result = 31 * result + state.hashCode();
266 result = 31 * result + workerClassName.hashCode();
Rahul Ravikumar9f91ee82018-03-20 17:33:38 -0700267 result = 31 * result + (inputMergerClassName != null ? inputMergerClassName.hashCode() : 0);
Sumir Katariab5728f42018-03-19 12:58:41 -0700268 result = 31 * result + arguments.hashCode();
269 result = 31 * result + output.hashCode();
270 result = 31 * result + (int) (initialDelay ^ (initialDelay >>> 32));
271 result = 31 * result + (int) (intervalDuration ^ (intervalDuration >>> 32));
272 result = 31 * result + (int) (flexDuration ^ (flexDuration >>> 32));
273 result = 31 * result + constraints.hashCode();
274 result = 31 * result + runAttemptCount;
275 result = 31 * result + backoffPolicy.hashCode();
276 result = 31 * result + (int) (backoffDelayDuration ^ (backoffDelayDuration >>> 32));
277 result = 31 * result + (int) (periodStartTime ^ (periodStartTime >>> 32));
Rahul Ravikumar9f91ee82018-03-20 17:33:38 -0700278 result = 31 * result + (int) (minimumRetentionDuration ^ (minimumRetentionDuration >>> 32));
279 result = 31 * result + (int) (scheduleRequestedAt ^ (scheduleRequestedAt >>> 32));
Jan Clarin91bccff2017-10-20 17:51:10 -0700280 return result;
281 }
Xyan Bhatnagarbbe9f312017-11-16 10:31:14 -0800282
283 @Override
284 public String toString() {
Sumir Katariab5728f42018-03-19 12:58:41 -0700285 return "{WorkSpec: " + id + "}";
Xyan Bhatnagarbbe9f312017-11-16 10:31:14 -0800286 }
Sumir Katariad2db35d2017-12-14 14:08:48 -0800287
288 /**
Sumir Kataria9cf4f3d2018-02-06 09:57:51 -0800289 * A POJO containing the ID and state of a WorkSpec.
Sumir Katariad2db35d2017-12-14 14:08:48 -0800290 */
Sumir Kataria9cf4f3d2018-02-06 09:57:51 -0800291 public static class IdAndState {
Sumir Katariad2db35d2017-12-14 14:08:48 -0800292
293 @ColumnInfo(name = "id")
294 public String id;
295
Sumir Kataria9cf4f3d2018-02-06 09:57:51 -0800296 @ColumnInfo(name = "state")
297 public State state;
Sumir Katariad2db35d2017-12-14 14:08:48 -0800298
299 @Override
300 public boolean equals(Object o) {
301 if (this == o) return true;
302 if (o == null || getClass() != o.getClass()) return false;
303
Sumir Kataria9cf4f3d2018-02-06 09:57:51 -0800304 IdAndState that = (IdAndState) o;
Sumir Katariad2db35d2017-12-14 14:08:48 -0800305
Sumir Kataria9cf4f3d2018-02-06 09:57:51 -0800306 if (state != that.state) return false;
Sumir Katariad2db35d2017-12-14 14:08:48 -0800307 return id.equals(that.id);
308 }
309
310 @Override
311 public int hashCode() {
312 int result = id.hashCode();
Sumir Kataria9cf4f3d2018-02-06 09:57:51 -0800313 result = 31 * result + state.hashCode();
314 return result;
315 }
316 }
317
318 /**
Sumir Katariacc5ae8c2018-03-12 12:57:46 -0700319 * A POJO containing the ID, state, output, and tags of a WorkSpec.
Sumir Kataria9cf4f3d2018-02-06 09:57:51 -0800320 */
Sumir Katariacc5ae8c2018-03-12 12:57:46 -0700321 public static class WorkStatusPojo {
Sumir Kataria9cf4f3d2018-02-06 09:57:51 -0800322
323 @ColumnInfo(name = "id")
324 public String id;
325
326 @ColumnInfo(name = "state")
327 public State state;
328
329 @ColumnInfo(name = "output")
330 public Arguments output;
331
Sumir Katariacc5ae8c2018-03-12 12:57:46 -0700332 @Relation(
333 parentColumn = "id",
334 entityColumn = "work_spec_id",
335 entity = WorkTag.class,
336 projection = {"tag"})
337 public List<String> tags;
338
339 /**
340 * Converts this POJO to a {@link WorkStatus}.
341 *
342 * @return The {@link WorkStatus} represented by this POJO
343 */
344 public WorkStatus toWorkStatus() {
345 return new WorkStatus(id, state, output, tags);
346 }
347
Sumir Kataria9cf4f3d2018-02-06 09:57:51 -0800348 @Override
349 public boolean equals(Object o) {
350 if (this == o) return true;
351 if (o == null || getClass() != o.getClass()) return false;
352
Sumir Katariacc5ae8c2018-03-12 12:57:46 -0700353 WorkStatusPojo that = (WorkStatusPojo) o;
Sumir Kataria9cf4f3d2018-02-06 09:57:51 -0800354
Sumir Katariacc5ae8c2018-03-12 12:57:46 -0700355 if (id != null ? !id.equals(that.id) : that.id != null) return false;
Sumir Kataria9cf4f3d2018-02-06 09:57:51 -0800356 if (state != that.state) return false;
Sumir Katariacc5ae8c2018-03-12 12:57:46 -0700357 if (output != null ? !output.equals(that.output) : that.output != null) return false;
358 return tags != null ? tags.equals(that.tags) : that.tags == null;
Sumir Kataria9cf4f3d2018-02-06 09:57:51 -0800359 }
360
361 @Override
362 public int hashCode() {
Sumir Katariacc5ae8c2018-03-12 12:57:46 -0700363 int result = id != null ? id.hashCode() : 0;
364 result = 31 * result + (state != null ? state.hashCode() : 0);
Sumir Kataria9cf4f3d2018-02-06 09:57:51 -0800365 result = 31 * result + (output != null ? output.hashCode() : 0);
Sumir Katariacc5ae8c2018-03-12 12:57:46 -0700366 result = 31 * result + (tags != null ? tags.hashCode() : 0);
Sumir Katariad2db35d2017-12-14 14:08:48 -0800367 return result;
368 }
369 }
Sumir Kataria4401f792018-03-20 12:52:38 -0700370
371 public static final Function<List<WorkStatusPojo>, List<WorkStatus>> WORK_STATUS_MAPPER =
372 new Function<List<WorkStatusPojo>, List<WorkStatus>>() {
373 @Override
374 public List<WorkStatus> apply(List<WorkStatusPojo> input) {
375 if (input == null) {
376 return null;
377 }
378 List<WorkStatus> output = new ArrayList<>(input.size());
379 for (WorkStatusPojo in : input) {
380 output.add(in.toWorkStatus());
381 }
382 return output;
383 }
384 };
Sumir Kataria904ba122017-09-25 13:05:49 -0700385}