1 /*
<lambda>null2  * 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 // Always inline ktx extension methods unless we have additional call site costs.
18 @file:Suppress("NOTHING_TO_INLINE")
19 
20 package androidx.work
21 
22 import androidx.concurrent.futures.CallbackToFutureAdapter
23 import androidx.concurrent.futures.await
24 import androidx.lifecycle.LiveData
25 import androidx.lifecycle.MutableLiveData
26 import com.google.common.util.concurrent.ListenableFuture
27 import java.util.concurrent.Executor
28 
29 /**
30  * Awaits an [Operation] without blocking a thread.
31  *
32  * <p>
33  * This method returns the terminal state of the [Operation] which is [Operation.State.SUCCESS] or
34  * throws a [Throwable] that represents why the [Operation] failed.
35  */
36 public suspend inline fun Operation.await(): Operation.State.SUCCESS = result.await()
37 
38 internal fun launchOperation(
39     tracer: Tracer,
40     label: String,
41     executor: Executor,
42     block: () -> Unit
43 ): Operation {
44     val liveData = MutableLiveData<Operation.State>(Operation.IN_PROGRESS)
45     val future =
46         CallbackToFutureAdapter.getFuture { completer ->
47             executor.execute {
48                 tracer.traced(label) {
49                     try {
50                         block()
51                         liveData.postValue(Operation.SUCCESS)
52                         completer.set(Operation.SUCCESS)
53                     } catch (t: Throwable) {
54                         liveData.postValue(Operation.State.FAILURE(t))
55                         completer.setException(t)
56                     }
57                 }
58             }
59         }
60     return OperationImpl(liveData, future)
61 }
62 
63 private class OperationImpl(
64     private val state: LiveData<Operation.State>,
65     private val future: ListenableFuture<Operation.State.SUCCESS>,
66 ) : Operation {
getStatenull67     override fun getState(): LiveData<Operation.State> = state
68 
69     override fun getResult(): ListenableFuture<Operation.State.SUCCESS> = future
70 }
71