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 17 package androidx.work; 18 19 import androidx.annotation.RestrictTo; 20 import androidx.lifecycle.LifecycleOwner; 21 import androidx.lifecycle.LiveData; 22 import androidx.lifecycle.Observer; 23 24 import com.google.common.util.concurrent.ListenableFuture; 25 26 import org.jspecify.annotations.NonNull; 27 28 /** 29 * An object that provides information about the execution of an asynchronous command being 30 * performed by {@link WorkManager}. Operations are generally tied to enqueue or cancel commands; 31 * when you call one of those commands, they occur asynchronously. You can observe or await these 32 * commands by using the returned Operation. 33 */ 34 35 public interface Operation { 36 37 /** 38 */ 39 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 40 @SuppressWarnings("VariableNameSameAsType") 41 State.SUCCESS SUCCESS = new State.SUCCESS(); 42 43 /** 44 */ 45 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 46 @SuppressWarnings("VariableNameSameAsType") 47 State.IN_PROGRESS IN_PROGRESS = new State.IN_PROGRESS(); 48 49 /** 50 * Gets a {@link LiveData} of the Operation {@link State}. 51 * 52 * @return A {@link LiveData} of the Operation {@link State}; you must use 53 * {@link LiveData#observe(LifecycleOwner, Observer)} to receive updates 54 */ getState()55 @NonNull LiveData<State> getState(); 56 57 /** 58 * Gets a {@link ListenableFuture} for the terminal state of the {@link Operation}. This will 59 * only resolve with a {@link State.SUCCESS}. The {@link State.FAILURE} state will come through 60 * as a {@link Throwable} on the {@link ListenableFuture}. {@link State.IN_PROGRESS} will never 61 * be reported as it's not a terminal state. 62 * <p> 63 * Call {@link ListenableFuture#get()} to block until the {@link Operation} reaches a terminal 64 * state. 65 * 66 * @return A {@link ListenableFuture} with information about {@link Operation}'s 67 * {@link State.SUCCESS} state. 68 */ getResult()69 @NonNull ListenableFuture<State.SUCCESS> getResult(); 70 71 /** 72 * The lifecycle state of an {@link Operation}. 73 */ 74 abstract class State { 75 76 /** 77 */ 78 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) State()79 State() { 80 // Restricting access to the constructor, to give Operation.State a sealed class 81 // like behavior. 82 } 83 84 /** 85 * This represents an {@link Operation} which is successful. 86 */ 87 public static final class SUCCESS extends Operation.State { SUCCESS()88 private SUCCESS() { 89 super(); 90 } 91 92 @Override toString()93 public @NonNull String toString() { 94 return "SUCCESS"; 95 } 96 } 97 98 /** 99 * This represents an {@link Operation} which is in progress. 100 */ 101 public static final class IN_PROGRESS extends Operation.State { IN_PROGRESS()102 private IN_PROGRESS() { 103 super(); 104 } 105 106 @Override toString()107 public @NonNull String toString() { 108 return "IN_PROGRESS"; 109 } 110 } 111 112 /** 113 * This represents an {@link Operation} which has failed. 114 */ 115 public static final class FAILURE extends Operation.State { 116 117 private final Throwable mThrowable; 118 FAILURE(@onNull Throwable exception)119 public FAILURE(@NonNull Throwable exception) { 120 super(); 121 mThrowable = exception; 122 } 123 124 /** 125 * @return The {@link Throwable} which caused the {@link Operation} to fail. 126 */ getThrowable()127 public @NonNull Throwable getThrowable() { 128 return mThrowable; 129 } 130 131 @Override toString()132 public @NonNull String toString() { 133 return "FAILURE (" + mThrowable.getMessage() + ")"; 134 } 135 } 136 } 137 } 138