[Android] Add a new waitForML method to block the current coroutine while ML init

Nicolas Pomepuy git at videolan.org
Fri Oct 15 08:58:50 UTC 2021


vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Wed Oct 13 14:40:29 2021 +0200| [875376d49b58235fc3029f8c07c05a9f305970f9] | committer: Nicolas Pomepuy

Add a new waitForML method to block the current coroutine while ML init

> https://code.videolan.org/videolan/vlc-android/commit/875376d49b58235fc3029f8c07c05a9f305970f9
---

 .../java/org/videolan/resources/util/Extensions.kt | 32 ++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/application/resources/src/main/java/org/videolan/resources/util/Extensions.kt b/application/resources/src/main/java/org/videolan/resources/util/Extensions.kt
index 5fc844590..da5a40b43 100644
--- a/application/resources/src/main/java/org/videolan/resources/util/Extensions.kt
+++ b/application/resources/src/main/java/org/videolan/resources/util/Extensions.kt
@@ -11,6 +11,11 @@ import java.io.File
 import kotlin.coroutines.resume
 
 
+/**
+ * Allows getting a ready medialibrary to query it.
+ * @param block: the unit to invoke when the medialibrary is ready
+ */
+ at ObsoleteCoroutinesApi
 @ExperimentalCoroutinesApi
 suspend inline fun <reified T> Context.getFromMl(crossinline block: Medialibrary.() -> T) = withContext(Dispatchers.IO) {
     val ml = Medialibrary.getInstance()
@@ -36,6 +41,33 @@ suspend inline fun <reified T> Context.getFromMl(crossinline block: Medialibrary
     }
 }
 
+/**
+ * Blocks the current coroutine while the medialibrary is not ready.
+ * Useful when we know the medialibrary init has been launched,
+ * we already have an instance of it and we want to wait that it's ready to query it
+ */
+ at ExperimentalCoroutinesApi
+suspend inline fun waitForML() = withContext(Dispatchers.IO) {
+    val ml = Medialibrary.getInstance()
+    if (!ml.isStarted){
+        suspendCancellableCoroutine<() -> Unit> { continuation ->
+            val listener = object : Medialibrary.OnMedialibraryReadyListener {
+                override fun onMedialibraryReady() {
+                    val cb = this
+                    if (!continuation.isCompleted) launch(start = CoroutineStart.UNDISPATCHED) {
+                        continuation.resume {}
+                        yield()
+                        ml.removeOnMedialibraryReadyListener(cb)
+                    }
+                }
+                override fun onMedialibraryIdle() {}
+            }
+            continuation.invokeOnCancellation { ml.removeOnMedialibraryReadyListener(listener) }
+            ml.addOnMedialibraryReadyListener(listener)
+        }
+    }
+}
+
 fun Context.startMedialibrary(firstRun: Boolean = false, upgrade: Boolean = false, parse: Boolean = true, removeDevices:Boolean = false, coroutineContextProvider: CoroutineContextProvider = CoroutineContextProvider()) = AppScope.launch {
     if (Medialibrary.getInstance().isStarted || !canReadStorage(this at startMedialibrary)) return at launch
     val prefs = withContext(coroutineContextProvider.IO) { Settings.getInstance(this at startMedialibrary) }



More information about the Android mailing list