Fix race condition while js evaluation

This commit is contained in:
Koitharu
2025-05-25 10:05:10 +03:00
parent d3d7912bb8
commit 41d7fd1b86

View File

@@ -9,7 +9,10 @@ import androidx.core.os.LocaleListCompat
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeout
import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Response import okhttp3.Response
@@ -36,6 +39,7 @@ import org.koitharu.kotatsu.parsers.network.UserAgents
import org.koitharu.kotatsu.parsers.util.map import org.koitharu.kotatsu.parsers.util.map
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import java.util.Locale import java.util.Locale
import java.util.concurrent.TimeUnit
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
import kotlin.coroutines.EmptyCoroutineContext import kotlin.coroutines.EmptyCoroutineContext
@@ -51,27 +55,28 @@ class MangaLoaderContextImpl @Inject constructor(
private var webViewCached: WeakReference<WebView>? = null private var webViewCached: WeakReference<WebView>? = null
private val webViewUserAgent by lazy { obtainWebViewUserAgent() } private val webViewUserAgent by lazy { obtainWebViewUserAgent() }
private val jsMutex = Mutex()
private val jsTimeout = TimeUnit.SECONDS.toMillis(4)
@Deprecated("Provide a base url") @Deprecated("Provide a base url")
@SuppressLint("SetJavaScriptEnabled") @SuppressLint("SetJavaScriptEnabled")
override suspend fun evaluateJs(script: String): String? = withContext(Dispatchers.Main.immediate) { override suspend fun evaluateJs(script: String): String? = evaluateJs("", script)
val webView = obtainWebView()
suspendCoroutine { cont ->
webView.evaluateJavascript(script) { result ->
cont.resume(result?.takeUnless { it == "null" })
}
}
}
override suspend fun evaluateJs(baseUrl: String, script: String): String? = withContext(Dispatchers.Main.immediate) { override suspend fun evaluateJs(baseUrl: String, script: String): String? = withTimeout(jsTimeout) {
val webView = obtainWebView() jsMutex.withLock {
suspendCoroutine { cont -> withContext(Dispatchers.Main.immediate) {
webView.webViewClient = ContinuationResumeWebViewClient(cont) val webView = obtainWebView()
webView.loadDataWithBaseURL(baseUrl, " ", "text/html", null, null) if (baseUrl.isNotEmpty()) {
} suspendCoroutine { cont ->
suspendCoroutine { cont -> webView.webViewClient = ContinuationResumeWebViewClient(cont)
webView.evaluateJavascript(script) { result -> webView.loadDataWithBaseURL(baseUrl, " ", "text/html", null, null)
cont.resume(result?.takeUnless { it == "null" }) }
}
suspendCoroutine { cont ->
webView.evaluateJavascript(script) { result ->
cont.resume(result?.takeUnless { it == "null" })
}
}
} }
} }
} }