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