From cb481473982783927ca379d715a7b3b3c76f3336 Mon Sep 17 00:00:00 2001 From: Philip Peitsch Date: Mon, 24 Apr 2023 12:20:48 +1000 Subject: [PATCH] feat: add plugin hooks for WebViewClient.onRenderProcessGone (#1574) * feat: add plugin hooks for WebViewClient.onRenderProcessGone * Update framework/src/org/apache/cordova/CordovaPlugin.java Co-authored-by: Norman Breau --------- Co-authored-by: Norman Breau --- .../src/org/apache/cordova/CordovaPlugin.java | 17 ++++++++++++ .../src/org/apache/cordova/PluginManager.java | 27 +++++++++++++++++++ .../cordova/engine/SystemWebViewClient.java | 12 +++++++++ 3 files changed, 56 insertions(+) diff --git a/framework/src/org/apache/cordova/CordovaPlugin.java b/framework/src/org/apache/cordova/CordovaPlugin.java index 38e2e4af..1140c4af 100644 --- a/framework/src/org/apache/cordova/CordovaPlugin.java +++ b/framework/src/org/apache/cordova/CordovaPlugin.java @@ -31,6 +31,8 @@ import android.content.res.Configuration; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.webkit.RenderProcessGoneDetail; +import android.webkit.WebView; import java.io.FileNotFoundException; import java.io.IOException; @@ -442,4 +444,19 @@ public class CordovaPlugin { public CordovaPluginPathHandler getPathHandler() { return null; } + + /** + * Called when the WebView's render process has exited. Can be used to collect information regarding the crash for crashlytics or optionally attempt to gracefully handle/recover the crashed webview by recreating it. + * + * See WebViewClient#onRenderProcessGone + * + * Note: A plugin must not attempt to recover a webview that it does not own/manage. + * + * @return true if the host application handled the situation that process has exited, + * otherwise, application will crash if render process crashed, or be killed + * if render process was killed by the system. + */ + public boolean onRenderProcessGone(final WebView view, RenderProcessGoneDetail detail) { + return false; + } } diff --git a/framework/src/org/apache/cordova/PluginManager.java b/framework/src/org/apache/cordova/PluginManager.java index 7d9df723..255eacd0 100755 --- a/framework/src/org/apache/cordova/PluginManager.java +++ b/framework/src/org/apache/cordova/PluginManager.java @@ -32,6 +32,8 @@ import android.net.Uri; import android.os.Bundle; import android.os.Debug; import android.os.Build; +import android.webkit.RenderProcessGoneDetail; +import android.webkit.WebView; /** * PluginManager is exposed to JavaScript in the Cordova WebView. @@ -617,4 +619,29 @@ public class PluginManager { } return handlers; } + + /** + * Called when the WebView's render process has exited. + * + * See https://developer.android.com/reference/android/webkit/WebViewClient#onRenderProcessGone(android.webkit.WebView,%20android.webkit.RenderProcessGoneDetail) + * + * @return true if the host application handled the situation that process has exited, + * otherwise, application will crash if render process crashed, or be killed + * if render process was killed by the system. + */ + public boolean onRenderProcessGone(final WebView view, RenderProcessGoneDetail detail) { + boolean result = false; + synchronized (this.entryMap) { + for (PluginEntry entry : this.entryMap.values()) { + CordovaPlugin plugin = pluginMap.get(entry.service); + if (plugin != null) { + if (plugin.onRenderProcessGone(view, detail)) { + result = true; + } + } + } + } + + return result; + } } diff --git a/framework/src/org/apache/cordova/engine/SystemWebViewClient.java b/framework/src/org/apache/cordova/engine/SystemWebViewClient.java index 05400417..9f057182 100755 --- a/framework/src/org/apache/cordova/engine/SystemWebViewClient.java +++ b/framework/src/org/apache/cordova/engine/SystemWebViewClient.java @@ -28,6 +28,7 @@ import android.net.http.SslError; import android.webkit.ClientCertRequest; import android.webkit.HttpAuthHandler; import android.webkit.MimeTypeMap; +import android.webkit.RenderProcessGoneDetail; import android.webkit.SslErrorHandler; import android.webkit.WebResourceRequest; import android.webkit.WebResourceResponse; @@ -422,4 +423,15 @@ public class SystemWebViewClient extends WebViewClient { public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { return this.assetLoader.shouldInterceptRequest(request.getUrl()); } + + @Override + public boolean onRenderProcessGone(final WebView view, RenderProcessGoneDetail detail) { + // Check if there is some plugin which can handle this event + PluginManager pluginManager = this.parentEngine.pluginManager; + if (pluginManager != null && pluginManager.onRenderProcessGone(view, detail)) { + return true; + } + + return super.onRenderProcessGone(view, detail); + } }