diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/network/webview/ContinuationResumeWebViewClient.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/network/webview/ContinuationResumeWebViewClient.kt index 4c991cac9..bbb3403e0 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/network/webview/ContinuationResumeWebViewClient.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/network/webview/ContinuationResumeWebViewClient.kt @@ -2,6 +2,7 @@ package org.koitharu.kotatsu.core.network.webview import android.webkit.WebView import android.webkit.WebViewClient +import kotlinx.coroutines.CancellableContinuation import kotlin.coroutines.Continuation import kotlin.coroutines.resume @@ -14,7 +15,9 @@ open class ContinuationResumeWebViewClient( } protected fun resumeContinuation(view: WebView?) { - view?.webViewClient = WebViewClient() // reset to default - continuation.resume(Unit) + if (continuation !is CancellableContinuation || continuation.isActive) { + view?.webViewClient = WebViewClient() // reset to default + continuation.resume(Unit) + } } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/network/webview/WebViewExecutor.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/network/webview/WebViewExecutor.kt index 02fe15b1a..8adf12432 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/network/webview/WebViewExecutor.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/network/webview/WebViewExecutor.kt @@ -3,9 +3,10 @@ package org.koitharu.kotatsu.core.network.webview import android.content.Context import android.webkit.WebSettings import android.webkit.WebView +import android.webkit.WebViewClient +import androidx.annotation.MainThread import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock @@ -25,7 +26,6 @@ import java.lang.ref.WeakReference import javax.inject.Inject import javax.inject.Provider import javax.inject.Singleton -import kotlin.coroutines.EmptyCoroutineContext import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine @@ -47,16 +47,20 @@ class WebViewExecutor @Inject constructor( suspend fun evaluateJs(baseUrl: String?, script: String): String? = mutex.withLock { withContext(Dispatchers.Main.immediate) { val webView = obtainWebView() - if (!baseUrl.isNullOrEmpty()) { - suspendCoroutine { cont -> - webView.webViewClient = ContinuationResumeWebViewClient(cont) - webView.loadDataWithBaseURL(baseUrl, " ", "text/html", null, null) + try { + if (!baseUrl.isNullOrEmpty()) { + suspendCoroutine { cont -> + webView.webViewClient = ContinuationResumeWebViewClient(cont) + webView.loadDataWithBaseURL(baseUrl, " ", "text/html", null, null) + } } - } - suspendCoroutine { cont -> - webView.evaluateJavascript(script) { result -> - cont.resume(result?.takeUnless { it == "null" }) + suspendCoroutine { cont -> + webView.evaluateJavascript(script) { result -> + cont.resume(result?.takeUnless { it == "null" }) + } } + } finally { + webView.reset() } } } @@ -69,23 +73,18 @@ class WebViewExecutor @Inject constructor( exception.source.getUserAgent()?.let { webView.settings.userAgentString = it } - coroutineScope { - withTimeout(timeout) { - suspendCancellableCoroutine { cont -> - webView.webViewClient = CaptchaContinuationClient( - cookieJar = cookieJar, - targetUrl = exception.url, - continuation = cont, - ) - cont.invokeOnCancellation { - webView.stopLoadingAsync() - } - webView.loadUrl(exception.url) - } + withTimeout(timeout) { + suspendCancellableCoroutine { cont -> + webView.webViewClient = CaptchaContinuationClient( + cookieJar = cookieJar, + targetUrl = exception.url, + continuation = cont, + ) + webView.loadUrl(exception.url) } } } finally { - webView.settings.userAgentString = defaultUserAgent + webView.reset() } } }.onFailure { e -> @@ -117,9 +116,12 @@ class WebViewExecutor @Inject constructor( return repository?.getRequestHeaders()?.get(CommonHeaders.USER_AGENT) } - private fun WebView.stopLoadingAsync() { - Dispatchers.Main.dispatch(EmptyCoroutineContext) { - stopLoading() - } + @MainThread + private fun WebView.reset() { + stopLoading() + webViewClient = WebViewClient() + settings.userAgentString = defaultUserAgent + loadDataWithBaseURL(null, " ", "text/html", null, null) + clearHistory() } }