xref: /aosp_15_r20/external/lottie/snapshot-tests/src/androidTest/java/com/airbnb/lottie/snapshots/utils/Utils.kt (revision bb5273fecd5c61b9ace70f9ff4fcd88f0e12e3f7)

<lambda>null1 package com.airbnb.lottie.snapshots.utils
2 
3 import android.util.Log
4 import com.airbnb.lottie.L
5 import com.amazonaws.mobileconnectors.s3.transferutility.TransferListener
6 import com.amazonaws.mobileconnectors.s3.transferutility.TransferObserver
7 import com.amazonaws.mobileconnectors.s3.transferutility.TransferState
8 import kotlinx.coroutines.CancellationException
9 import kotlinx.coroutines.delay
10 import kotlinx.coroutines.suspendCancellableCoroutine
11 import kotlin.coroutines.resume
12 import kotlin.coroutines.resumeWithException
13 import kotlin.coroutines.suspendCoroutine
14 
15 suspend fun TransferObserver.await() = suspendCancellableCoroutine<TransferObserver> { continuation ->
16     val listener = object : TransferListener {
17         override fun onProgressChanged(id: Int, bytesCurrent: Long, bytesTotal: Long) {}
18 
19         override fun onError(id: Int, ex: Exception) {
20             Log.e(L.TAG, "$id failed uploading!", ex)
21             continuation.resumeWithException(ex)
22             cleanTransferListener()
23         }
24 
25         override fun onStateChanged(id: Int, state: TransferState) {
26             when (state) {
27                 TransferState.COMPLETED -> {
28                     continuation.resume(this@await)
29                     cleanTransferListener()
30                 }
31                 TransferState.CANCELED, TransferState.FAILED -> {
32                     Log.d(L.TAG, "$id failed uploading ($state).")
33                     continuation.resume(this@await)
34                     cleanTransferListener()
35                 }
36                 else -> Unit
37             }
38         }
39     }
40     setTransferListener(listener)
41 }
42 
retrynull43 suspend fun <T> retry(
44     delayMs: Long = 2_000,
45     maxRetryCount: Int = 10,
46     canRetry: (Throwable) -> Boolean = { true },
47     block: suspend (tryCount: Int, previousException: Throwable?) -> T,
48 ): T {
49     var previousException: Throwable? = null
50     for (i in 1..maxRetryCount) {
<lambda>null51         val result = runCatching { block(i, previousException) }
valuenull52         result.onSuccess { value ->
53             return value
54         }
enull55         result.onFailure { e ->
56             if (e is CancellationException || i == maxRetryCount || !canRetry(e)) throw e
57             previousException = e
58         }
59         delay(delayMs)
60     }
61     error("Max retries exceeded but the last invocation did not fail.")
62 }