diff --git a/app/src/main/java/org/jellyfin/mobile/fragment/WebViewFragment.kt b/app/src/main/java/org/jellyfin/mobile/fragment/WebViewFragment.kt index 7fb9aad8..6332bb1f 100644 --- a/app/src/main/java/org/jellyfin/mobile/fragment/WebViewFragment.kt +++ b/app/src/main/java/org/jellyfin/mobile/fragment/WebViewFragment.kt @@ -27,11 +27,14 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.add import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope +import androidx.webkit.ServiceWorkerClientCompat +import androidx.webkit.ServiceWorkerControllerCompat import androidx.webkit.WebResourceErrorCompat import androidx.webkit.WebViewAssetLoader.AssetsPathHandler import androidx.webkit.WebViewClientCompat import androidx.webkit.WebViewCompat import androidx.webkit.WebViewFeature +import io.ktor.http.HttpStatusCode import kotlinx.coroutines.launch import org.jellyfin.mobile.AppPreferences import org.jellyfin.mobile.R @@ -157,7 +160,6 @@ class WebViewFragment : Fragment(), NativePlayerHost { showOutdatedWebViewDialog() return } - webViewClient = object : WebViewClientCompat() { override fun shouldInterceptRequest(webView: WebView, request: WebResourceRequest): WebResourceResponse? { val url = request.url @@ -226,6 +228,25 @@ class WebViewFragment : Fragment(), NativePlayerHost { onErrorReceived() } } + // Workaround for service worker breaking script injections + if (WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_BASIC_USAGE)) { + val swController = ServiceWorkerControllerCompat.getInstance() + swController.setServiceWorkerClient(object : ServiceWorkerClientCompat() { + override fun shouldInterceptRequest(request: WebResourceRequest): WebResourceResponse? { + val path = request.url.path?.lowercase(Locale.ROOT) ?: return null + return when { + path.endsWith(Constants.SERVICE_WORKER_PATH) -> { + WebResourceResponse("application/javascript", "utf-8", null).apply { + with(HttpStatusCode.NotFound) { + setStatusCodeAndReasonPhrase(value, description) + } + } + } + else -> null + } + } + }) + } webChromeClient = object : WebChromeClient() { override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean { val logLevel = when (consoleMessage.messageLevel()) { diff --git a/app/src/main/java/org/jellyfin/mobile/utils/Constants.kt b/app/src/main/java/org/jellyfin/mobile/utils/Constants.kt index cadb1d7f..f4751c6d 100644 --- a/app/src/main/java/org/jellyfin/mobile/utils/Constants.kt +++ b/app/src/main/java/org/jellyfin/mobile/utils/Constants.kt @@ -15,6 +15,7 @@ object Constants { val MAIN_BUNDLE_PATH_REGEX = Regex(""".*/main\.[^/\s]+\.bundle\.js""") const val CAST_SDK_PATH = "cast_sender.js" const val SESSION_CAPABILITIES_PATH = "sessions/capabilities/full" + const val SERVICE_WORKER_PATH = "serviceworker.js" const val FRAGMENT_CONNECT_EXTRA_ERROR = "org.jellyfin.mobile.intent.extra.ERROR" const val FRAGMENT_WEB_VIEW_EXTRA_SERVER = "org.jellyfin.mobile.intent.extra.SERVER"