Revert "[Compose] Parse LottieComposition synchronously instead of using LottieTask" (#1890)

Reverts #1888

This was not a good solution. It lost task joining so requesting the same animation multiples would parse the animation multiple times.
diff --git a/lottie-compose/src/main/java/com/airbnb/lottie/compose/LottieCompositionSpec.kt b/lottie-compose/src/main/java/com/airbnb/lottie/compose/LottieCompositionSpec.kt
index ba38a5b..9444a5b 100644
--- a/lottie-compose/src/main/java/com/airbnb/lottie/compose/LottieCompositionSpec.kt
+++ b/lottie-compose/src/main/java/com/airbnb/lottie/compose/LottieCompositionSpec.kt
@@ -1,7 +1,5 @@
 package com.airbnb.lottie.compose
 
-import com.airbnb.lottie.LottieComposition
-
 /**
  * Specification for a [com.airbnb.lottie.LottieComposition]. Each subclass represents a different source.
  * A [com.airbnb.lottie.LottieComposition] is the stateless parsed version of a Lottie json file and is
@@ -43,9 +41,4 @@
      * Load an animation from its json string.
      */
     inline class JsonString(val jsonString: String) : LottieCompositionSpec
-
-    /**
-     * Load an animation from a custom factory. This will be called on an IO thread pool.
-     */
-    inline class Custom(val factory: () -> LottieComposition) : LottieCompositionSpec
 }
diff --git a/lottie-compose/src/main/java/com/airbnb/lottie/compose/rememberLottieComposition.kt b/lottie-compose/src/main/java/com/airbnb/lottie/compose/rememberLottieComposition.kt
index f4f4187..42d3e3c 100644
--- a/lottie-compose/src/main/java/com/airbnb/lottie/compose/rememberLottieComposition.kt
+++ b/lottie-compose/src/main/java/com/airbnb/lottie/compose/rememberLottieComposition.kt
@@ -13,15 +13,18 @@
 import com.airbnb.lottie.LottieComposition
 import com.airbnb.lottie.LottieCompositionFactory
 import com.airbnb.lottie.LottieImageAsset
-import com.airbnb.lottie.LottieResult
+import com.airbnb.lottie.LottieTask
 import com.airbnb.lottie.model.Font
 import com.airbnb.lottie.utils.Logger
 import com.airbnb.lottie.utils.Utils
 import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.suspendCancellableCoroutine
 import kotlinx.coroutines.withContext
 import java.io.FileInputStream
 import java.io.IOException
 import java.util.zip.ZipInputStream
+import kotlin.coroutines.resume
+import kotlin.coroutines.resumeWithException
 
 /**
  * Use this with [rememberLottieComposition#cacheKey]'s cacheKey parameter to generate a default
@@ -78,7 +81,6 @@
 ): LottieCompositionResult {
     val context = LocalContext.current
     val result by remember(spec) { mutableStateOf(LottieCompositionResultImpl()) }
-
     LaunchedEffect(spec) {
         var exception: Throwable? = null
         var failedCount = 0
@@ -113,63 +115,58 @@
     fontFileExtension: String,
     cacheKey: String?,
 ): LottieComposition {
-    val result = parseCompositionSync(context, spec, cacheKey)
-    result.exception?.let { throw it }
+    val task = when (spec) {
+        is LottieCompositionSpec.RawRes -> {
+            if (cacheKey == DefaultCacheKey) {
+                LottieCompositionFactory.fromRawRes(context, spec.resId)
+            } else {
+                LottieCompositionFactory.fromRawRes(context, spec.resId, cacheKey)
+            }
+        }
+        is LottieCompositionSpec.Url -> {
+            if (cacheKey == DefaultCacheKey) {
+                LottieCompositionFactory.fromUrl(context, spec.url)
+            } else {
+                LottieCompositionFactory.fromUrl(context, spec.url, cacheKey)
+            }
+        }
+        is LottieCompositionSpec.File -> {
+            val fis = withContext(Dispatchers.IO) {
+                @Suppress("BlockingMethodInNonBlockingContext")
+                FileInputStream(spec.fileName)
+            }
+            when {
+                spec.fileName.endsWith("zip") -> LottieCompositionFactory.fromZipStream(
+                    ZipInputStream(fis),
+                    spec.fileName.takeIf { cacheKey != null },
+                )
+                else -> LottieCompositionFactory.fromJsonInputStream(fis, spec.fileName.takeIf { cacheKey != null })
+            }
+        }
+        is LottieCompositionSpec.Asset -> {
+            if (cacheKey == DefaultCacheKey) {
+                LottieCompositionFactory.fromAsset(context, spec.assetName)
+            } else {
+                LottieCompositionFactory.fromAsset(context, spec.assetName, null)
+            }
+        }
+        is LottieCompositionSpec.JsonString -> {
+            val jsonStringCacheKey = if (cacheKey == DefaultCacheKey) spec.jsonString.hashCode().toString() else cacheKey
+            LottieCompositionFactory.fromJsonString(spec.jsonString, jsonStringCacheKey)
+        }
+    }
 
-    val composition = result.value!!
+    val composition = task.await()
     loadImagesFromAssets(context, composition, imageAssetsFolder)
     loadFontsFromAssets(context, composition, fontAssetsFolder, fontFileExtension)
     return composition
 }
 
-private fun parseCompositionSync(
-    context: Context,
-    spec: LottieCompositionSpec,
-    cacheKey: String?,
-): LottieResult<LottieComposition> {
-    return when (spec) {
-        is LottieCompositionSpec.RawRes -> {
-            if (cacheKey == DefaultCacheKey) {
-                LottieCompositionFactory.fromRawResSync(context, spec.resId)
-            } else {
-                LottieCompositionFactory.fromRawResSync(context, spec.resId, cacheKey)
-            }
-        }
-        is LottieCompositionSpec.Url -> {
-            if (cacheKey == DefaultCacheKey) {
-                LottieCompositionFactory.fromUrlSync(context, spec.url)
-            } else {
-                LottieCompositionFactory.fromUrlSync(context, spec.url, cacheKey)
-            }
-        }
-        is LottieCompositionSpec.File -> {
-            val fis = FileInputStream(spec.fileName)
-            when {
-                spec.fileName.endsWith("zip") -> LottieCompositionFactory.fromZipStreamSync(
-                    ZipInputStream(fis),
-                    spec.fileName.takeIf { cacheKey != null },
-                )
-                else -> LottieCompositionFactory.fromJsonInputStreamSync(fis, spec.fileName.takeIf { cacheKey != null })
-            }
-        }
-        is LottieCompositionSpec.Asset -> {
-            if (cacheKey == DefaultCacheKey) {
-                LottieCompositionFactory.fromAssetSync(context, spec.assetName)
-            } else {
-                LottieCompositionFactory.fromAssetSync(context, spec.assetName, null)
-            }
-        }
-        is LottieCompositionSpec.JsonString -> {
-            val jsonStringCacheKey = if (cacheKey == DefaultCacheKey) spec.jsonString.hashCode().toString() else cacheKey
-            LottieCompositionFactory.fromJsonStringSync(spec.jsonString, jsonStringCacheKey)
-        }
-        is LottieCompositionSpec.Custom -> {
-            try {
-                LottieResult(spec.factory())
-            } catch (e: Throwable) {
-                LottieResult<LottieComposition>(e)
-            }
-        }
+private suspend fun <T> LottieTask<T>.await(): T = suspendCancellableCoroutine { cont ->
+    addListener { c ->
+        if (!cont.isCompleted) cont.resume(c)
+    }.addFailureListener { e ->
+        if (!cont.isCompleted) cont.resumeWithException(e)
     }
 }