OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package org.chromium.components.background_task_scheduler; |
| 6 |
| 7 import android.content.Context; |
| 8 import android.os.Bundle; |
| 9 import android.support.annotation.IntDef; |
| 10 import android.support.annotation.NonNull; |
| 11 |
| 12 import java.lang.annotation.Retention; |
| 13 import java.lang.annotation.RetentionPolicy; |
| 14 |
| 15 /** |
| 16 * TaskInfo represents a request to run a specific {@link BackgroundTask} given
the required |
| 17 * parameters, such as whether a special type of network is available. |
| 18 */ |
| 19 public class TaskInfo { |
| 20 /** |
| 21 * Specifies information regarding one-off tasks. |
| 22 * This is part of a {@link TaskInfo} iff the task is NOT a periodic task. |
| 23 */ |
| 24 public static class OneOffInfo { |
| 25 private final long mWindowStartTimeMs; |
| 26 private final long mWindowEndTimeMs; |
| 27 private final boolean mHasWindowStartTimeConstraint; |
| 28 |
| 29 private OneOffInfo(long windowStartTimeMs, long windowEndTimeMs, |
| 30 boolean hasWindowStartTimeConstraint) { |
| 31 mWindowStartTimeMs = windowStartTimeMs; |
| 32 mWindowEndTimeMs = windowEndTimeMs; |
| 33 mHasWindowStartTimeConstraint = hasWindowStartTimeConstraint; |
| 34 } |
| 35 |
| 36 /** |
| 37 * @return the start of the window that the task can begin executing as
a delta in |
| 38 * milliseconds from now. |
| 39 */ |
| 40 public long getWindowStartTimeMs() { |
| 41 return mWindowStartTimeMs; |
| 42 } |
| 43 |
| 44 /** |
| 45 * @return the end of the window that the task can begin executing as a
delta in |
| 46 * milliseconds from now. |
| 47 */ |
| 48 public long getWindowEndTimeMs() { |
| 49 return mWindowEndTimeMs; |
| 50 } |
| 51 |
| 52 /** |
| 53 * @return whether this one-off task has a window start time constraint. |
| 54 */ |
| 55 public boolean hasWindowStartTimeConstraint() { |
| 56 return mHasWindowStartTimeConstraint; |
| 57 } |
| 58 |
| 59 @Override |
| 60 public String toString() { |
| 61 return "{windowStartTimeMs: " + mWindowStartTimeMs + ", windowEndTim
eMs: " |
| 62 + mWindowEndTimeMs + "}"; |
| 63 } |
| 64 } |
| 65 |
| 66 /** |
| 67 * Specifies information regarding periodic tasks. |
| 68 * This is part of a {@link TaskInfo} iff the task is a periodic task. |
| 69 */ |
| 70 public static class PeriodicInfo { |
| 71 private final long mIntervalMs; |
| 72 private final long mFlexMs; |
| 73 private final boolean mHasFlex; |
| 74 |
| 75 private PeriodicInfo(long intervalMs, long flexMs, boolean hasFlex) { |
| 76 mIntervalMs = intervalMs; |
| 77 mFlexMs = flexMs; |
| 78 mHasFlex = hasFlex; |
| 79 } |
| 80 |
| 81 /** |
| 82 * @return the interval between occurrences of this task in milliseconds
. |
| 83 */ |
| 84 public long getIntervalMs() { |
| 85 return mIntervalMs; |
| 86 } |
| 87 |
| 88 /** |
| 89 * @return the flex time for this task. The task can execute at any time
in a window of flex |
| 90 * length at the end of the period. It is reported in milliseconds. |
| 91 */ |
| 92 public long getFlexMs() { |
| 93 return mFlexMs; |
| 94 } |
| 95 |
| 96 /** |
| 97 * @return true whether this task has defined a flex time. False otherwi
se. |
| 98 */ |
| 99 public boolean hasFlex() { |
| 100 return mHasFlex; |
| 101 } |
| 102 |
| 103 @Override |
| 104 public String toString() { |
| 105 StringBuilder sb = new StringBuilder("{"); |
| 106 sb.append("{"); |
| 107 sb.append("intervalMs: ").append(mIntervalMs); |
| 108 if (mHasFlex) { |
| 109 sb.append(", flexMs: ").append(mFlexMs); |
| 110 } |
| 111 sb.append("}"); |
| 112 return sb.toString(); |
| 113 } |
| 114 } |
| 115 |
| 116 @Retention(RetentionPolicy.SOURCE) |
| 117 @IntDef({NETWORK_TYPE_NONE, NETWORK_TYPE_ANY, NETWORK_TYPE_UNMETERED}) |
| 118 public @interface NetworkType {} |
| 119 |
| 120 /** |
| 121 * This task has no requirements for network connectivity. Default. |
| 122 * |
| 123 * @see NetworkType |
| 124 */ |
| 125 public static final int NETWORK_TYPE_NONE = 0; |
| 126 /** |
| 127 * This task requires network connectivity. |
| 128 * |
| 129 * @see NetworkType |
| 130 */ |
| 131 public static final int NETWORK_TYPE_ANY = 1; |
| 132 /** |
| 133 * This task requires network connectivity that is unmetered. |
| 134 * |
| 135 * @see NetworkType |
| 136 */ |
| 137 public static final int NETWORK_TYPE_UNMETERED = 2; |
| 138 |
| 139 /** |
| 140 * The task ID should be unique across all tasks. A list of such unique IDs
exists in |
| 141 * {@link TaskIds}. |
| 142 */ |
| 143 private final int mTaskId; |
| 144 |
| 145 /** |
| 146 * The {@link BackgroundTask} to invoke when this task is run. |
| 147 */ |
| 148 @NonNull |
| 149 private final Class<? extends BackgroundTask> mBackgroundTaskClass; |
| 150 |
| 151 /** |
| 152 * The extras to provide to the {@link BackgroundTask} when it is run. |
| 153 */ |
| 154 @NonNull |
| 155 private final Bundle mExtras; |
| 156 |
| 157 /** |
| 158 * The type of network the task requires to run. |
| 159 */ |
| 160 @NetworkType |
| 161 private final int mRequiredNetworkType; |
| 162 |
| 163 /** |
| 164 * Whether the task requires charging to run. |
| 165 */ |
| 166 private final boolean mRequiresCharging; |
| 167 |
| 168 /** |
| 169 * Whether or not to persist this task across device reboots. |
| 170 */ |
| 171 private final boolean mIsPersisted; |
| 172 |
| 173 /** |
| 174 * Whether this task should override any preexisting tasks with the same tas
k id. |
| 175 */ |
| 176 private final boolean mUpdateCurrent; |
| 177 |
| 178 /** |
| 179 * Whether this task is periodic. |
| 180 */ |
| 181 private final boolean mIsPeriodic; |
| 182 |
| 183 /** |
| 184 * Task information regarding one-off tasks. Non-null iff {@link #mIsPeriodi
c} is false. |
| 185 */ |
| 186 private final OneOffInfo mOneOffInfo; |
| 187 |
| 188 /** |
| 189 * Task information regarding periodic tasks. Non-null iff {@link #mIsPeriod
ic} is true. |
| 190 */ |
| 191 private final PeriodicInfo mPeriodicInfo; |
| 192 |
| 193 private TaskInfo(Builder builder) { |
| 194 mTaskId = builder.mTaskId; |
| 195 mBackgroundTaskClass = builder.mBackgroundTaskClass; |
| 196 mExtras = builder.mExtras == null ? new Bundle() : builder.mExtras; |
| 197 mRequiredNetworkType = builder.mRequiredNetworkType; |
| 198 mRequiresCharging = builder.mRequiresCharging; |
| 199 mIsPersisted = builder.mIsPersisted; |
| 200 mUpdateCurrent = builder.mUpdateCurrent; |
| 201 mIsPeriodic = builder.mIsPeriodic; |
| 202 if (mIsPeriodic) { |
| 203 mOneOffInfo = null; |
| 204 mPeriodicInfo = |
| 205 new PeriodicInfo(builder.mIntervalMs, builder.mFlexMs, build
er.mHasFlex); |
| 206 } else { |
| 207 mOneOffInfo = new OneOffInfo(builder.mWindowStartTimeMs, builder.mWi
ndowEndTimeMs, |
| 208 builder.mHasWindowStartTimeConstraint); |
| 209 mPeriodicInfo = null; |
| 210 } |
| 211 } |
| 212 |
| 213 /** |
| 214 * @return the unique ID of this task. |
| 215 */ |
| 216 public int getTaskId() { |
| 217 return mTaskId; |
| 218 } |
| 219 |
| 220 /** |
| 221 * @return the {@link BackgroundTask} class that will be instantiated for th
is task. |
| 222 */ |
| 223 @NonNull |
| 224 public Class<? extends BackgroundTask> getBackgroundTaskClass() { |
| 225 return mBackgroundTaskClass; |
| 226 } |
| 227 |
| 228 /** |
| 229 * @return the extras that will be provided to the {@link BackgroundTask}. |
| 230 */ |
| 231 @NonNull |
| 232 public Bundle getExtras() { |
| 233 return mExtras; |
| 234 } |
| 235 |
| 236 /** |
| 237 * @return the type of network the task requires to run. |
| 238 */ |
| 239 @NetworkType |
| 240 public int getRequiredNetworkType() { |
| 241 return mRequiredNetworkType; |
| 242 } |
| 243 |
| 244 /** |
| 245 * @return whether the task requires charging to run. |
| 246 */ |
| 247 public boolean requiresCharging() { |
| 248 return mRequiresCharging; |
| 249 } |
| 250 |
| 251 /** |
| 252 * @return whether or not to persist this task across device reboots. |
| 253 */ |
| 254 public boolean isPersisted() { |
| 255 return mIsPersisted; |
| 256 } |
| 257 |
| 258 /** |
| 259 * @return whether this task should override any preexisting tasks with the
same task id. |
| 260 */ |
| 261 public boolean shouldUpdateCurrent() { |
| 262 return mUpdateCurrent; |
| 263 } |
| 264 |
| 265 /** |
| 266 * @return Whether or not this task is a periodic task. |
| 267 */ |
| 268 public boolean isPeriodic() { |
| 269 return mIsPeriodic; |
| 270 } |
| 271 |
| 272 /** |
| 273 * This is part of a {@link TaskInfo} iff the task is NOT a periodic task, i.
e. |
| 274 * {@link TaskInfo#isPeriodic()} returns false. |
| 275 * |
| 276 * @return the specific data that is only available for one-off tasks. |
| 277 */ |
| 278 public OneOffInfo getOneOffInfo() { |
| 279 return mOneOffInfo; |
| 280 } |
| 281 |
| 282 /** |
| 283 * This is part of a {@link TaskInfo} iff the task is a periodic task, i.e. |
| 284 * {@link TaskInfo#isPeriodic()} returns true. |
| 285 * |
| 286 * @return the specific data that is only available for periodic tasks. |
| 287 */ |
| 288 public PeriodicInfo getPeriodicInfo() { |
| 289 return mPeriodicInfo; |
| 290 } |
| 291 |
| 292 @Override |
| 293 public String toString() { |
| 294 StringBuilder sb = new StringBuilder(); |
| 295 sb.append("{"); |
| 296 sb.append("taskId: ").append(mTaskId); |
| 297 sb.append(", backgroundTaskClass: ").append(mBackgroundTaskClass); |
| 298 sb.append(", extras: ").append(mExtras); |
| 299 sb.append(", requiredNetworkType: ").append(mRequiredNetworkType); |
| 300 sb.append(", requiresCharging: ").append(mRequiresCharging); |
| 301 sb.append(", isPersisted: ").append(mIsPersisted); |
| 302 sb.append(", updateCurrent: ").append(mUpdateCurrent); |
| 303 sb.append(", isPeriodic: ").append(mIsPeriodic); |
| 304 if (isPeriodic()) { |
| 305 sb.append(", periodicInfo: ").append(mPeriodicInfo); |
| 306 } else { |
| 307 sb.append(", oneOffInfo: ").append(mOneOffInfo); |
| 308 } |
| 309 sb.append("}"); |
| 310 return sb.toString(); |
| 311 } |
| 312 |
| 313 /** |
| 314 * Schedule a one-off task to execute within a deadline. If windowEndTimeMs
is 0, the task will |
| 315 * run as soon as possible. For executing a task within a time window, see |
| 316 * {@link #createOneOffTask(int, Class, long, long)}. |
| 317 * |
| 318 * @param taskId the unique task ID for this task. Should be listed in {@lin
k TaskIds}. |
| 319 * @param backgroundTaskClass the {@link BackgroundTask} class that will be
instantiated for |
| 320 * this task. |
| 321 * @param windowEndTimeMs the end of the window that the task can begin exec
uting as a delta in |
| 322 * milliseconds from now. |
| 323 * @return the builder which can be used to continue configuration and {@lin
k Builder#build()}. |
| 324 * @see TaskIds |
| 325 */ |
| 326 public static Builder createOneOffTask( |
| 327 int taskId, Class<? extends BackgroundTask> backgroundTaskClass, lon
g windowEndTimeMs) { |
| 328 return new Builder(taskId, backgroundTaskClass, false).setWindowEndTimeM
s(windowEndTimeMs); |
| 329 } |
| 330 |
| 331 /** |
| 332 * Schedule a one-off task to execute within a time window. For executing a
task within a |
| 333 * deadline, see {@link #createOneOffTask(int, Class, long)}, |
| 334 * |
| 335 * @param taskId the unique task ID for this task. Should be listed in {@lin
k TaskIds}. |
| 336 * @param backgroundTaskClass the {@link BackgroundTask} class that will be
instantiated for |
| 337 * this task. |
| 338 * @param windowStartTimeMs the start of the window that the task can begin
executing as a delta |
| 339 * in milliseconds from now. |
| 340 * @param windowEndTimeMs the end of the window that the task can begin exec
uting as a delta in |
| 341 * milliseconds from now. |
| 342 * @return the builder which can be used to continue configuration and {@lin
k Builder#build()}. |
| 343 * @see TaskIds |
| 344 */ |
| 345 public static Builder createOneOffTask(int taskId, |
| 346 Class<? extends BackgroundTask> backgroundTaskClass, long windowStar
tTimeMs, |
| 347 long windowEndTimeMs) { |
| 348 return new Builder(taskId, backgroundTaskClass, false) |
| 349 .setWindowStartTimeMs(windowStartTimeMs) |
| 350 .setWindowEndTimeMs(windowEndTimeMs); |
| 351 } |
| 352 |
| 353 /** |
| 354 * Schedule a periodic task that will recur at the specified interval, witho
ut the need to |
| 355 * be rescheduled. The task will continue to recur until |
| 356 * {@link BackgroundTaskScheduler#cancel(Context, int)} is invoked with the
task ID from this |
| 357 * {@link TaskInfo}. |
| 358 * |
| 359 * @param taskId the unique task ID for this task. Should be listed in {@lin
k TaskIds}. |
| 360 * @param backgroundTaskClass the {@link BackgroundTask} class that will be
instantiated for |
| 361 * this task. |
| 362 * @param intervalMs the interval between occurrences of this task in millis
econds. |
| 363 * @return the builder which can be used to continue configuration and {@lin
k Builder#build()}. |
| 364 * @see TaskIds |
| 365 */ |
| 366 public static Builder createPeriodicTask( |
| 367 int taskId, Class<? extends BackgroundTask> backgroundTaskClass, lon
g intervalMs) { |
| 368 return new Builder(taskId, backgroundTaskClass, true).setIntervalMs(inte
rvalMs); |
| 369 } |
| 370 |
| 371 /** |
| 372 * Schedule a periodic task that will recur at the specified interval, witho
ut the need to |
| 373 * be rescheduled. The task will continue to recur until |
| 374 * {@link BackgroundTaskScheduler#cancel(Context, int)} is invoked with the
task ID from this |
| 375 * {@link TaskInfo}. |
| 376 * The flex time specifies how close to the end of the interval you are will
ing to execute. |
| 377 * Instead of executing at the exact interval, the task will execute at the
interval or up to |
| 378 * flex milliseconds before. |
| 379 * |
| 380 * @param taskId the unique task ID for this task. Should be listed in {@lin
k TaskIds}. |
| 381 * @param backgroundTaskClass the {@link BackgroundTask} class that will be
instantiated for |
| 382 * this task. |
| 383 * @param intervalMs the interval between occurrences of this task in millis
econds. |
| 384 * @param flexMs the flex time for this task. The task can execute at any ti
me in a window of |
| 385 * flex |
| 386 * length at the end of the period. It is reported in milliseconds. |
| 387 * @return the builder which can be used to continue configuration and {@lin
k Builder#build()}. |
| 388 * @see TaskIds |
| 389 */ |
| 390 public static Builder createPeriodicTask(int taskId, |
| 391 Class<? extends BackgroundTask> backgroundTaskClass, long intervalMs
, long flexMs) { |
| 392 return new Builder(taskId, backgroundTaskClass, true) |
| 393 .setIntervalAndFlexMs(intervalMs, flexMs); |
| 394 } |
| 395 |
| 396 /** |
| 397 * A helper builder to provide a way to build {@link TaskInfo}. To create a
{@link Builder} |
| 398 * use one of the create* class method on {@link TaskInfo}. |
| 399 * |
| 400 * @see #createOneOffTask(int, Class, long) |
| 401 * @see #createOneOffTask(int, Class, long, long) |
| 402 * @see #createPeriodicTask(int, Class, long) |
| 403 * @see #createPeriodicTask(int, Class, long, long) |
| 404 */ |
| 405 public static final class Builder { |
| 406 private final int mTaskId; |
| 407 @NonNull |
| 408 private final Class<? extends BackgroundTask> mBackgroundTaskClass; |
| 409 private final boolean mIsPeriodic; |
| 410 private Bundle mExtras; |
| 411 @NetworkType |
| 412 private int mRequiredNetworkType; |
| 413 private boolean mRequiresCharging; |
| 414 private boolean mIsPersisted; |
| 415 private boolean mUpdateCurrent; |
| 416 |
| 417 // Data about one-off tasks. |
| 418 private long mWindowStartTimeMs; |
| 419 private long mWindowEndTimeMs; |
| 420 private boolean mHasWindowStartTimeConstraint; |
| 421 |
| 422 // Data about periodic tasks. |
| 423 private long mIntervalMs; |
| 424 private long mFlexMs; |
| 425 private boolean mHasFlex; |
| 426 |
| 427 Builder(int taskId, @NonNull Class<? extends BackgroundTask> backgroundT
askClass, |
| 428 boolean isPeriodic) { |
| 429 mTaskId = taskId; |
| 430 mBackgroundTaskClass = backgroundTaskClass; |
| 431 mIsPeriodic = isPeriodic; |
| 432 } |
| 433 |
| 434 Builder setWindowStartTimeMs(long windowStartTimeMs) { |
| 435 assert !mIsPeriodic; |
| 436 mWindowStartTimeMs = windowStartTimeMs; |
| 437 mHasWindowStartTimeConstraint = true; |
| 438 return this; |
| 439 } |
| 440 |
| 441 Builder setWindowEndTimeMs(long windowEndTimeMs) { |
| 442 assert !mIsPeriodic; |
| 443 mWindowEndTimeMs = windowEndTimeMs; |
| 444 return this; |
| 445 } |
| 446 |
| 447 Builder setIntervalMs(long intervalMs) { |
| 448 assert mIsPeriodic; |
| 449 mIntervalMs = intervalMs; |
| 450 return this; |
| 451 } |
| 452 |
| 453 Builder setIntervalAndFlexMs(long intervalMs, long flexMs) { |
| 454 assert mIsPeriodic; |
| 455 mIntervalMs = intervalMs; |
| 456 mFlexMs = flexMs; |
| 457 mHasFlex = true; |
| 458 return this; |
| 459 } |
| 460 |
| 461 /** |
| 462 * Set the optional extra values necessary for this task. Must only ever
contain simple |
| 463 * values supported by {@link android.os.BaseBundle}. All other values a
re thrown away. |
| 464 * If the extras for this builder are not set, or set to null, the resul
ting |
| 465 * {@link TaskInfo} will have an empty bundle (i.e. not null). |
| 466 * |
| 467 * @param bundle the bundle of extra values necessary for this task. |
| 468 * @return this {@link Builder}. |
| 469 */ |
| 470 public Builder setExtras(Bundle bundle) { |
| 471 mExtras = bundle; |
| 472 return this; |
| 473 } |
| 474 |
| 475 /** |
| 476 * Set the type of network the task requires to run. |
| 477 * |
| 478 * @param networkType the {@link NetworkType} required for this task. |
| 479 * @return this {@link Builder}. |
| 480 */ |
| 481 public Builder setRequiredNetworkType(@NetworkType int networkType) { |
| 482 mRequiredNetworkType = networkType; |
| 483 return this; |
| 484 } |
| 485 |
| 486 /** |
| 487 * Set whether the task requires charging to run. |
| 488 * |
| 489 * @param requiresCharging true if this task requires charging. |
| 490 * @return this {@link Builder}. |
| 491 */ |
| 492 public Builder setRequiresCharging(boolean requiresCharging) { |
| 493 mRequiresCharging = requiresCharging; |
| 494 return this; |
| 495 } |
| 496 |
| 497 /** |
| 498 * Set whether or not to persist this task across device reboots. |
| 499 * |
| 500 * @param isPersisted true if this task should be persisted across reboo
ts. |
| 501 * @return this {@link Builder}. |
| 502 */ |
| 503 public Builder setIsPersisted(boolean isPersisted) { |
| 504 mIsPersisted = isPersisted; |
| 505 return this; |
| 506 } |
| 507 |
| 508 /** |
| 509 * Set whether this task should override any preexisting tasks with the
same task id. |
| 510 * |
| 511 * @param updateCurrent true if this task should overwrite a currently e
xisting task with |
| 512 * the same ID, if it exists. |
| 513 * @return this {@link Builder}. |
| 514 */ |
| 515 public Builder setUpdateCurrent(boolean updateCurrent) { |
| 516 mUpdateCurrent = updateCurrent; |
| 517 return this; |
| 518 } |
| 519 |
| 520 /** |
| 521 * Build the {@link TaskInfo object} specified by this builder. |
| 522 * |
| 523 * @return the {@link TaskInfo} object. |
| 524 */ |
| 525 public TaskInfo build() { |
| 526 return new TaskInfo(this); |
| 527 } |
| 528 } |
| 529 } |
OLD | NEW |