diff --git a/CHANGELOG.md b/CHANGELOG.md index d5ef5f18f..272587c86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ The format is a modified version of [Keep a Changelog](https://keepachangelog.co - Fixed the start and resume button going under the taskbar on tablets ([@AntsyLich](https://github.com/AntsyLich)) - Fixed a crash when updating an extension while others were installing ([@AntsyLich](https://github.com/AntsyLich)) - Fixed library entries without a date added getting their last update time as date added when updating from v0.20.x ([@AntsyLich](https://github.com/AntsyLich)) +- Fixed the app closing when WebView's page process crashed ([@AntsyLich](https://github.com/AntsyLich)) ## [v0.21.0] - 2026-10-12 ### Added diff --git a/app/src/main/java/eu/kanade/presentation/webview/WebViewScreenContent.kt b/app/src/main/java/eu/kanade/presentation/webview/WebViewScreenContent.kt index fbc26ff3f..7ff8c7ee2 100644 --- a/app/src/main/java/eu/kanade/presentation/webview/WebViewScreenContent.kt +++ b/app/src/main/java/eu/kanade/presentation/webview/WebViewScreenContent.kt @@ -5,8 +5,10 @@ import android.graphics.Bitmap import android.os.Message import android.webkit.JsPromptResult import android.webkit.JsResult +import android.webkit.RenderProcessGoneDetail import android.webkit.WebResourceRequest import android.webkit.WebView +import android.widget.Toast import androidx.activity.compose.BackHandler import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box @@ -45,12 +47,15 @@ import eu.kanade.tachiyomi.BuildConfig import eu.kanade.tachiyomi.util.system.getHtml import eu.kanade.tachiyomi.util.system.setDefaultSettings import eu.kanade.tachiyomi.util.system.setUserAgent +import eu.kanade.tachiyomi.util.system.toast import kotlinx.coroutines.launch +import logcat.LogPriority import mihon.icons.materialsymbols.MaterialSymbols import mihon.icons.materialsymbols.automirroredrounded.ArrowBack import mihon.icons.materialsymbols.automirroredrounded.ArrowForward import mihon.icons.materialsymbols.rounded.Close import mihon.icons.materialsymbols.rounded.TabClose +import tachiyomi.core.common.util.system.logcat import tachiyomi.i18n.MR import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.i18n.stringResource @@ -152,6 +157,17 @@ fun WebViewScreenContent( return false } + + override fun onRenderProcessGone(view: WebView, detail: RenderProcessGoneDetail): Boolean { + // Not handling it kills the app along with the page + logcat(LogPriority.ERROR) { + "WebView renderer gone: crashed=${detail.didCrash()}, " + + "priority=${detail.rendererPriorityAtExit()}, url=$currentUrl" + } + view.context.toast(MR.strings.information_webview_crashed, Toast.LENGTH_LONG) + onNavigateUp() + return true + } } } diff --git a/core/common/src/main/kotlin/eu/kanade/tachiyomi/network/interceptor/CloudflareInterceptor.kt b/core/common/src/main/kotlin/eu/kanade/tachiyomi/network/interceptor/CloudflareInterceptor.kt index 7cc97fb01..3df2f876b 100644 --- a/core/common/src/main/kotlin/eu/kanade/tachiyomi/network/interceptor/CloudflareInterceptor.kt +++ b/core/common/src/main/kotlin/eu/kanade/tachiyomi/network/interceptor/CloudflareInterceptor.kt @@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.network.interceptor import android.annotation.SuppressLint import android.content.Context import android.webkit.JavascriptInterface +import android.webkit.RenderProcessGoneDetail import android.webkit.WebResourceRequest import android.webkit.WebResourceResponse import android.webkit.WebView @@ -13,12 +14,14 @@ import eu.kanade.tachiyomi.network.AndroidCookieJar import eu.kanade.tachiyomi.util.system.isOutdated import eu.kanade.tachiyomi.util.system.toast import kotlinx.coroutines.CoroutineScope +import logcat.LogPriority import okhttp3.Cookie import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.Interceptor import okhttp3.Request import okhttp3.Response import tachiyomi.core.common.i18n.stringResource +import tachiyomi.core.common.util.system.logcat import tachiyomi.i18n.MR import java.io.IOException import java.util.concurrent.CountDownLatch @@ -73,6 +76,7 @@ class CloudflareInterceptor( var challengeFound = false var cloudflareBypassed = false var isWebViewOutdated = false + var isRenderProcessGone = false val origRequestUrl = originalRequest.url.toString() val headers = parseHeaders(originalRequest.headers) @@ -140,6 +144,17 @@ class CloudflareInterceptor( } } } + + override fun onRenderProcessGone(view: WebView, detail: RenderProcessGoneDetail): Boolean { + // Not handling it kills the app, failing the bypass is enough + logcat(LogPriority.ERROR) { + "WebView renderer gone during Cloudflare bypass: crashed=${detail.didCrash()}, " + + "priority=${detail.rendererPriorityAtExit()}, url=$origRequestUrl" + } + isRenderProcessGone = true + latch.countDown() + return true + } } webview.loadUrl(origRequestUrl, headers) @@ -148,12 +163,13 @@ class CloudflareInterceptor( latch.awaitFor30Seconds() executor.execute { - if (!cloudflareBypassed) { + // Only destroy can be called on a WebView whose renderer is gone + if (!cloudflareBypassed && !isRenderProcessGone) { isWebViewOutdated = webview?.isOutdated() == true } webview?.run { - stopLoading() + if (!isRenderProcessGone) stopLoading() destroy() } } diff --git a/i18n/src/commonMain/moko-resources/base/strings.xml b/i18n/src/commonMain/moko-resources/base/strings.xml index 19925c456..d54c7a7f0 100644 --- a/i18n/src/commonMain/moko-resources/base/strings.xml +++ b/i18n/src/commonMain/moko-resources/base/strings.xml @@ -1020,6 +1020,8 @@ WebView is required for the app to function Please update the WebView app for better compatibility + + WebView stopped working and the page was closed Updated default chapter settings