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