summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJake Petroules <jake.petroules@theqtcompany.com>2015-09-05 19:14:17 -0700
committerJake Petroules <jake.petroules@theqtcompany.com>2015-09-10 21:09:14 +0000
commit5555afd6ce01bc9891ee33b075cc53f4fa48665e (patch)
treea0fc64b10090e9c7c4574c57c17c92cccc5e3adb
parentffddac06d3b98be9a477a5ecedc2acd255715453 (diff)
Emit a signal when the rendering process exits.
This allows users to implement a "sad tab" feature and/or track rendering process crashes using a crash reporting service. Task-number: QTBUG-48227 Change-Id: I97ef934fe5d0912cd0f41967a39052316b3c66b0 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@theqtcompany.com>
-rw-r--r--examples/webengine/quicknanobrowser/BrowserWindow.qml29
-rw-r--r--examples/webenginewidgets/demobrowser/demobrowser.pro1
-rw-r--r--examples/webenginewidgets/demobrowser/webview.cpp22
-rw-r--r--src/core/render_widget_host_view_qt.cpp5
-rw-r--r--src/core/web_contents_adapter.cpp32
-rw-r--r--src/core/web_contents_adapter_client.h9
-rw-r--r--src/webengine/api/qquickwebengineview.cpp8
-rw-r--r--src/webengine/api/qquickwebengineview_p.h10
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h2
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp8
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h10
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h2
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp1
-rw-r--r--src/webenginewidgets/api/qwebengineview.h2
14 files changed, 140 insertions, 1 deletions
diff --git a/examples/webengine/quicknanobrowser/BrowserWindow.qml b/examples/webengine/quicknanobrowser/BrowserWindow.qml
index bdee68d17..4d7513fae 100644
--- a/examples/webengine/quicknanobrowser/BrowserWindow.qml
+++ b/examples/webengine/quicknanobrowser/BrowserWindow.qml
@@ -393,6 +393,35 @@ ApplicationWindow {
}
request.accept()
}
+
+ onRenderProcessTerminated: {
+ var status = ""
+ switch (terminationStatus) {
+ case WebEngineView.NormalTerminationStatus:
+ status = "(normal exit)"
+ break;
+ case WebEngineView.AbnormalTerminationStatus:
+ status = "(abnormal exit)"
+ break;
+ case WebEngineView.CrashedTerminationStatus:
+ status = "(crashed)"
+ break;
+ case WebEngineView.KilledTerminationStatus:
+ status = "(killed)"
+ break;
+ }
+
+ print("Render process exited with code " + exitCode + " " + status)
+ reloadTimer.running = true
+ }
+
+ Timer {
+ id: reloadTimer
+ interval: 0
+ running: false
+ repeat: false
+ onTriggered: currentWebView.reload()
+ }
}
}
}
diff --git a/examples/webenginewidgets/demobrowser/demobrowser.pro b/examples/webenginewidgets/demobrowser/demobrowser.pro
index 310aea59c..0893fe649 100644
--- a/examples/webenginewidgets/demobrowser/demobrowser.pro
+++ b/examples/webenginewidgets/demobrowser/demobrowser.pro
@@ -1,6 +1,7 @@
TEMPLATE = app
TARGET = demobrowser
QT += webenginewidgets network widgets printsupport
+CONFIG += c++11
qtHaveModule(uitools):!embedded: QT += uitools
else: DEFINES += QT_NO_UITOOLS
diff --git a/examples/webenginewidgets/demobrowser/webview.cpp b/examples/webenginewidgets/demobrowser/webview.cpp
index e454f06c4..c12f3db36 100644
--- a/examples/webenginewidgets/demobrowser/webview.cpp
+++ b/examples/webenginewidgets/demobrowser/webview.cpp
@@ -66,6 +66,7 @@
#include <QtCore/QDebug>
#include <QtCore/QBuffer>
+#include <QtCore/QTimer>
WebPage::WebPage(QWebEngineProfile *profile, QObject *parent)
: QWebEnginePage(profile, parent)
@@ -341,6 +342,27 @@ WebView::WebView(QWidget* parent)
this, SLOT(setProgress(int)));
connect(this, SIGNAL(loadFinished(bool)),
this, SLOT(loadFinished(bool)));
+ connect(this, &QWebEngineView::renderProcessTerminated,
+ [=](QWebEnginePage::RenderProcessTerminationStatus termStatus, int statusCode) {
+ const char *status = "";
+ switch (termStatus) {
+ case QWebEnginePage::NormalTerminationStatus:
+ status = "(normal exit)";
+ break;
+ case QWebEnginePage::AbnormalTerminationStatus:
+ status = "(abnormal exit)";
+ break;
+ case QWebEnginePage::CrashedTerminationStatus:
+ status = "(crashed)";
+ break;
+ case QWebEnginePage::KilledTerminationStatus:
+ status = "(killed)";
+ break;
+ }
+
+ qInfo() << "Render process exited with code" << statusCode << status;
+ QTimer::singleShot(0, [this] { reload(); });
+ });
}
void WebView::setPage(WebPage *_page)
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 7ca528954..26ea4f4ae 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -567,8 +567,11 @@ void RenderWidgetHostViewQt::ImeCompositionRangeChanged(const gfx::Range&, const
QT_NOT_YET_IMPLEMENTED
}
-void RenderWidgetHostViewQt::RenderProcessGone(base::TerminationStatus, int)
+void RenderWidgetHostViewQt::RenderProcessGone(base::TerminationStatus terminationStatus,
+ int exitCode)
{
+ m_adapterClient->renderProcessTerminated(
+ m_adapterClient->renderProcessExitStatus(terminationStatus), exitCode);
Destroy();
}
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 6fb2f5c97..58fd23969 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -900,4 +900,36 @@ void WebContentsAdapter::setWebChannel(QWebChannel *channel)
channel->connectTo(d->webChannelTransport.get());
}
+WebContentsAdapterClient::RenderProcessTerminationStatus
+WebContentsAdapterClient::renderProcessExitStatus(int terminationStatus) {
+ auto status = WebContentsAdapterClient::RenderProcessTerminationStatus(-1);
+ switch (terminationStatus) {
+ case base::TERMINATION_STATUS_NORMAL_TERMINATION:
+ status = WebContentsAdapterClient::NormalTerminationStatus;
+ break;
+ case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
+ status = WebContentsAdapterClient::AbnormalTerminationStatus;
+ break;
+ case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
+#if defined(OS_CHROMEOS)
+ case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM:
+#endif
+ status = WebContentsAdapterClient::KilledTerminationStatus;
+ break;
+ case base::TERMINATION_STATUS_PROCESS_CRASHED:
+#if defined(OS_ANDROID)
+ case base::TERMINATION_STATUS_OOM_PROTECTED:
+#endif
+ status = WebContentsAdapterClient::CrashedTerminationStatus;
+ break;
+ case base::TERMINATION_STATUS_STILL_RUNNING:
+ case base::TERMINATION_STATUS_MAX_ENUM:
+ // should be unreachable since Chromium asserts status != TERMINATION_STATUS_STILL_RUNNING
+ // before calling this method
+ break;
+ }
+
+ return status;
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 8166224a4..3ae84f9c8 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -172,6 +172,13 @@ public:
Error
};
+ enum RenderProcessTerminationStatus {
+ NormalTerminationStatus = 0,
+ AbnormalTerminationStatus,
+ CrashedTerminationStatus,
+ KilledTerminationStatus
+ };
+
enum MediaRequestFlag {
MediaNone = 0,
MediaAudioCapture = 0x01,
@@ -225,6 +232,8 @@ public:
virtual void showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText) = 0;
virtual void hideValidationMessage() = 0;
virtual void moveValidationMessage(const QRect &anchor) = 0;
+ RenderProcessTerminationStatus renderProcessExitStatus(int);
+ virtual void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode) = 0;
virtual void allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController) = 0;
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 83a6f68bb..b22b2798e 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -893,6 +893,14 @@ void QQuickWebEngineViewPrivate::moveValidationMessage(const QRect &anchor)
ui()->moveMessageBubble(anchor);
}
+void QQuickWebEngineViewPrivate::renderProcessTerminated(
+ RenderProcessTerminationStatus terminationStatus, int exitCode)
+{
+ Q_Q(QQuickWebEngineView);
+ Q_EMIT q->renderProcessTerminated(static_cast<QQuickWebEngineView::RenderProcessTerminationStatus>(
+ renderProcessExitStatus(terminationStatus)), exitCode);
+}
+
bool QQuickWebEngineView::isLoading() const
{
Q_D(const QQuickWebEngineView);
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index ab2e6a566..22cca3277 100644
--- a/src/webengine/api/qquickwebengineview_p.h
+++ b/src/webengine/api/qquickwebengineview_p.h
@@ -116,6 +116,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem {
Q_ENUMS(NewViewDestination);
Q_ENUMS(Feature);
Q_ENUMS(JavaScriptConsoleMessageLevel);
+ Q_ENUMS(RenderProcessTerminationStatus);
Q_FLAGS(FindFlags);
Q_ENUMS(WebAction);
@@ -236,6 +237,14 @@ public:
ErrorMessageLevel
};
+ // must match WebContentsAdapterClient::RenderProcessTerminationStatus
+ enum RenderProcessTerminationStatus {
+ NormalTerminationStatus = 0,
+ AbnormalTerminationStatus,
+ CrashedTerminationStatus,
+ KilledTerminationStatus
+ };
+
enum FindFlag {
FindBackward = 1,
FindCaseSensitively = 2,
@@ -295,6 +304,7 @@ Q_SIGNALS:
Q_REVISION(1) void webChannelChanged();
Q_REVISION(2) void activeFocusOnPressChanged(bool);
Q_REVISION(2) void backgroundColorChanged();
+ Q_REVISION(2) void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode);
protected:
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index 4aebb6f7c..0140111b9 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -167,6 +167,8 @@ public:
virtual void showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText) Q_DECL_OVERRIDE;
virtual void hideValidationMessage() Q_DECL_OVERRIDE;
virtual void moveValidationMessage(const QRect &anchor) Q_DECL_OVERRIDE;
+ virtual void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus,
+ int exitCode) Q_DECL_OVERRIDE;
virtual QtWebEngineCore::BrowserContextAdapter *browserContextAdapter() Q_DECL_OVERRIDE;
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index b6880b086..80baf1c74 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -921,6 +921,14 @@ void QWebEnginePagePrivate::moveValidationMessage(const QRect &anchor)
#endif
}
+void QWebEnginePagePrivate::renderProcessTerminated(RenderProcessTerminationStatus terminationStatus,
+ int exitCode)
+{
+ Q_Q(QWebEnginePage);
+ Q_EMIT q->renderProcessTerminated(static_cast<QWebEnginePage::RenderProcessTerminationStatus>(
+ terminationStatus), exitCode);
+}
+
QMenu *QWebEnginePage::createStandardContextMenu()
{
Q_D(QWebEnginePage);
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index d027998ee..90fa62f97 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -165,6 +165,14 @@ public:
ErrorMessageLevel
};
+ // must match WebContentsAdapterClient::RenderProcessTerminationStatus
+ enum RenderProcessTerminationStatus {
+ NormalTerminationStatus = 0,
+ AbnormalTerminationStatus,
+ CrashedTerminationStatus,
+ KilledTerminationStatus
+ };
+
explicit QWebEnginePage(QObject *parent = 0);
QWebEnginePage(QWebEngineProfile *profile, QObject *parent = 0);
~QWebEnginePage();
@@ -247,6 +255,8 @@ Q_SIGNALS:
void authenticationRequired(const QUrl &requestUrl, QAuthenticator *authenticator);
void proxyAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *authenticator, const QString &proxyHost);
+ void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode);
+
// Ex-QWebFrame signals
void titleChanged(const QString &title);
void urlChanged(const QUrl &url);
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index a72debee2..8d9bc2517 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -119,6 +119,8 @@ public:
virtual void showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText) Q_DECL_OVERRIDE;
virtual void hideValidationMessage() Q_DECL_OVERRIDE;
virtual void moveValidationMessage(const QRect &anchor) Q_DECL_OVERRIDE;
+ virtual void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus,
+ int exitCode) Q_DECL_OVERRIDE;
virtual QtWebEngineCore::BrowserContextAdapter *browserContextAdapter() Q_DECL_OVERRIDE;
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index a4a8dd760..ddd1e4cbf 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -86,6 +86,7 @@ void QWebEngineViewPrivate::bind(QWebEngineView *view, QWebEnginePage *page)
QObject::connect(page, &QWebEnginePage::loadProgress, view, &QWebEngineView::loadProgress);
QObject::connect(page, &QWebEnginePage::loadFinished, view, &QWebEngineView::loadFinished);
QObject::connect(page, &QWebEnginePage::selectionChanged, view, &QWebEngineView::selectionChanged);
+ QObject::connect(page, &QWebEnginePage::renderProcessTerminated, view, &QWebEngineView::renderProcessTerminated);
}
}
diff --git a/src/webenginewidgets/api/qwebengineview.h b/src/webenginewidgets/api/qwebengineview.h
index 0d8f9fc17..ae38e6c5c 100644
--- a/src/webenginewidgets/api/qwebengineview.h
+++ b/src/webenginewidgets/api/qwebengineview.h
@@ -113,6 +113,8 @@ Q_SIGNALS:
void selectionChanged();
void urlChanged(const QUrl&);
void iconUrlChanged(const QUrl&);
+ void renderProcessTerminated(QWebEnginePage::RenderProcessTerminationStatus terminationStatus,
+ int exitCode);
protected:
virtual QWebEngineView *createWindow(QWebEnginePage::WebWindowType type);