@javascriptcommon/react-native-webview 13.18.1 → 13.18.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -95,10 +95,53 @@ public class RNCWebView extends WebView implements LifecycleEventListener {
95
95
  // reactTag resolution.
96
96
  if (enabled) {
97
97
  EMBED_INSTANCE = this;
98
+ keepRendererImportant();
98
99
  startKeepAlive();
99
100
  }
100
101
  }
101
102
 
103
+ /**
104
+ * Tell Android this WebView's renderer must NOT be demoted when the WebView
105
+ * stops being visible.
106
+ *
107
+ * The renderer is a separate process (com.google.android.webview:
108
+ * sandboxed_process0) and its importance is inherited from us. The platform
109
+ * default is RENDERER_PRIORITY_IMPORTANT with waivedWhenNotVisible = TRUE:
110
+ * the moment the WebView is off screen the renderer drops to a cached
111
+ * process, Android's freezer suspends it — no JavaScript, no network, no
112
+ * decoding — and the system may then kill it outright.
113
+ *
114
+ * For a browser that default is right. For an embed player it is exactly
115
+ * backwards: this invisible WebView IS the audio source, and "screen off" or
116
+ * "app in the background" is precisely when it must keep working. Captured
117
+ * from the system log on a Pixel 6a (2026-08-05) while playback was stuck:
118
+ *
119
+ * ActivityManager: freezing 21392 com.google.android.webview:sandboxed_process0
120
+ * ActivityManager: sync unfroze 21392
121
+ * ActivityManager: freezing 21392
122
+ *
123
+ * The symptoms all follow from it: a media element left at readyState 0 /
124
+ * NETWORK_EMPTY (frozen mid-load), no events coming back (the injected
125
+ * script cannot run), a page that ends up about:blank (the renderer was
126
+ * killed), and playback that stops "after a while" in the background. It
127
+ * also explains why the keep-alive alone was not enough — that runs in the
128
+ * app process and calls evaluateJavascript, which merely queues against a
129
+ * renderer that is frozen.
130
+ *
131
+ * Scoped to the embed WebView for the same reason as the keep-alive: an
132
+ * in-app browser or a consent dialog has no claim on this.
133
+ */
134
+ private void keepRendererImportant() {
135
+ if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) return;
136
+ try {
137
+ setRendererPriorityPolicy(WebView.RENDERER_PRIORITY_IMPORTANT, false);
138
+ android.util.Log.i("RNCWebView", "embed renderer pinned IMPORTANT (not waived when hidden)");
139
+ } catch (Throwable ignored) {
140
+ // Some OEM WebView builds refuse the call; losing the guarantee must
141
+ // not cost us the WebView itself.
142
+ }
143
+ }
144
+
102
145
  public boolean getContentBlockerEnabled() {
103
146
  return this.contentBlockerEnabled;
104
147
  }
@@ -341,7 +341,10 @@ public class RNCWebViewClient extends WebViewClient {
341
341
 
342
342
  description = descriptionPrefix + description;
343
343
 
344
- if (!topWindowUrl.equalsIgnoreCase(failingUrl)) {
344
+ // getUrl() is null until the first navigation commits, so an SSL error on the very first load
345
+ // arrives with no top-level URL at all. That load IS the top-level navigation: report it as one
346
+ // instead of dereferencing null on the UI thread.
347
+ if (topWindowUrl != null && !topWindowUrl.equalsIgnoreCase(failingUrl)) {
345
348
  // If error is not due to top-level navigation, then do not call onReceivedError()
346
349
  Log.w(TAG, "Resource blocked from loading due to SSL error. Blocked URL: "+failingUrl);
347
350
  this.onReceivedSubResourceSslError(
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "Thibault Malbranche <malbranche.thibault@gmail.com>"
11
11
  ],
12
12
  "license": "MIT",
13
- "version": "13.18.1",
13
+ "version": "13.18.3",
14
14
  "homepage": "https://github.com/react-native-webview/react-native-webview#readme",
15
15
  "scripts": {
16
16
  "android": "react-native run-android",