From 3beacad57255fd27195e06f27f035ead5acb3db5 Mon Sep 17 00:00:00 2001 From: Howard Wang Date: Thu, 23 Jul 2026 23:09:40 +0800 Subject: [PATCH] fix: work around broken WebAssembly streaming compile in Android WebView Some Android System WebView builds throw on WebAssembly.compileStreaming / instantiateStreaming even when the .wasm is fetched correctly (200 application/wasm). This breaks sites that load a wasm video decoder for 4K playback, while the same URL plays fine in Chrome. Inject a small shim (assets/wasm-streaming-shim.js) in onPageStarted, before custom.js, that tries native streaming first and only falls back to fetch -> arrayBuffer -> compile on failure. Healthy engines keep the fast path; affected ones auto-recover. --- app/src/main/assets/wasm-streaming-shim.js | 33 +++++++++++++++++++ .../java/com/app/pakeplus/MainActivity.kt | 3 ++ 2 files changed, 36 insertions(+) create mode 100644 app/src/main/assets/wasm-streaming-shim.js diff --git a/app/src/main/assets/wasm-streaming-shim.js b/app/src/main/assets/wasm-streaming-shim.js new file mode 100644 index 0000000000..64e6906454 --- /dev/null +++ b/app/src/main/assets/wasm-streaming-shim.js @@ -0,0 +1,33 @@ +// Fix WebAssembly streaming compilation on Android System WebView. +// On some devices WebView's compileStreaming/instantiateStreaming throws +// even when the .wasm is fetched correctly (200 application/wasm), which +// breaks sites that load a wasm video decoder for 4K playback. +// Strategy: try native streaming first (fast path on healthy engines); +// only on failure, fall back to fetch -> arrayBuffer -> compile. +(function () { + if (window.__wasmStreamingPatched) return; + if (typeof WebAssembly === 'undefined') return; + var _cs = WebAssembly.compileStreaming; + var _is = WebAssembly.instantiateStreaming; + if (typeof _cs === 'function') { + WebAssembly.compileStreaming = async function (src) { + try { + return await _cs.call(WebAssembly, src); + } catch (e) { + var resp = await src; + return WebAssembly.compile(await resp.arrayBuffer()); + } + }; + } + if (typeof _is === 'function') { + WebAssembly.instantiateStreaming = async function (src, imports) { + try { + return await _is.call(WebAssembly, src, imports); + } catch (e) { + var resp = await src; + return WebAssembly.instantiate(await resp.arrayBuffer(), imports); + } + }; + } + window.__wasmStreamingPatched = true; +})(); diff --git a/app/src/main/java/com/app/pakeplus/MainActivity.kt b/app/src/main/java/com/app/pakeplus/MainActivity.kt index abbcaa1d6c..fddd6cc95c 100644 --- a/app/src/main/java/com/app/pakeplus/MainActivity.kt +++ b/app/src/main/java/com/app/pakeplus/MainActivity.kt @@ -1056,6 +1056,9 @@ class MainActivity : AppCompatActivity() { val openDebug = """var vConsole = new window.VConsole()""" view?.evaluateJavascript(vConsole + openDebug, null) } + // inject WebAssembly streaming shim before any page script and before custom.js + val wasmShim = assets.open("wasm-streaming-shim.js").bufferedReader().use { it.readText() } + view?.evaluateJavascript(wasmShim, null) // inject js val injectJs = assets.open("custom.js").bufferedReader().use { it.readText() } view?.evaluateJavascript(injectJs, null)