From a6fb2c592bac997baf87016e9dd6b7a3c061ef3c Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 16 Jan 2020 22:43:07 +0100 Subject: Add getter/signal to get the render process PID This can useful for e.g. implementing something like the "Task manager" in Chromium or otherwise interacting with the render process (e.g. to kill it for some reason while debugging). [ChangeLog] Add a renderProcessPid() getter to (Q)WebEnginePage which allows getting the process ID of the underlying render process. Change-Id: Id5d59be9b6bd46ffc3a6aa480cb5ff7bd3b8aa31 Reviewed-by: Allan Sandfeld Jensen --- src/core/web_contents_adapter.cpp | 11 +++++++++++ src/core/web_contents_adapter.h | 1 + src/core/web_contents_adapter_client.h | 1 + src/core/web_contents_delegate_qt.cpp | 8 ++++++++ src/webengine/api/qquickwebengineview.cpp | 12 ++++++++++++ src/webengine/api/qquickwebengineview_p.h | 5 +++++ src/webengine/api/qquickwebengineview_p_p.h | 1 + src/webengine/doc/src/webengineview_lgpl.qdoc | 24 ++++++++++++++++++++++++ src/webengine/plugin/plugin.cpp | 1 + src/webengine/plugin/plugins.qmltypes | 6 ++++++ src/webenginewidgets/api/qwebenginepage.cpp | 27 +++++++++++++++++++++++++++ src/webenginewidgets/api/qwebenginepage.h | 3 +++ src/webenginewidgets/api/qwebenginepage_p.h | 1 + 13 files changed, 101 insertions(+) (limited to 'src') diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 8cc8179cf..6d763faa5 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -1139,6 +1139,17 @@ bool WebContentsAdapter::recentlyAudible() const return m_webContents->IsCurrentlyAudible(); } +qint64 WebContentsAdapter::renderProcessPid() const +{ + CHECK_INITIALIZED(0); + + content::RenderProcessHost *renderProcessHost = m_webContents->GetMainFrame()->GetProcess(); + const base::Process &process = renderProcessHost->GetProcess(); + if (!process.IsValid()) + return 0; + return process.Pid(); +} + void WebContentsAdapter::copyImageAt(const QPoint &location) { CHECK_INITIALIZED(); diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h index 11f8f9cb1..1afcdc01a 100644 --- a/src/core/web_contents_adapter.h +++ b/src/core/web_contents_adapter.h @@ -166,6 +166,7 @@ public: bool isAudioMuted() const; void setAudioMuted(bool mute); bool recentlyAudible() const; + qint64 renderProcessPid() const; // Must match blink::WebMediaPlayerAction::Type. enum MediaPlayerAction { diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index e2f667358..3a75185f8 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -458,6 +458,7 @@ public: virtual void didUpdateTargetURL(const QUrl&) = 0; virtual void selectionChanged() = 0; virtual void recentlyAudibleChanged(bool recentlyAudible) = 0; + virtual void renderProcessPidChanged(qint64 pid) = 0; virtual QRectF viewportRect() const = 0; virtual QColor backgroundColor() const = 0; virtual void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) = 0; diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index c1cf1f659..271b87736 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -313,6 +313,14 @@ void WebContentsDelegateQt::RenderFrameHostChanged(content::RenderFrameHost *old if (new_host) { content::FrameTreeNode *new_node = static_cast(new_host)->frame_tree_node(); m_frameFocusedObserver.addNode(new_node); + + // Is this a main frame? + if (new_host->GetFrameOwnerElementType() == blink::FrameOwnerElementType::kNone) { + content::RenderProcessHost *renderProcessHost = new_host->GetProcess(); + const base::Process &process = renderProcessHost->GetProcess(); + if (process.IsValid()) + m_viewClient->renderProcessPidChanged(process.Pid()); + } } } diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 83ada3c11..67d4142b9 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -428,6 +428,12 @@ void QQuickWebEngineViewPrivate::recentlyAudibleChanged(bool recentlyAudible) Q_EMIT q->recentlyAudibleChanged(recentlyAudible); } +void QQuickWebEngineViewPrivate::renderProcessPidChanged(qint64 pid) +{ + Q_Q(QQuickWebEngineView); + Q_EMIT q->renderProcessPidChanged(pid); +} + QRectF QQuickWebEngineViewPrivate::viewportRect() const { Q_Q(const QQuickWebEngineView); @@ -1403,6 +1409,12 @@ bool QQuickWebEngineView::recentlyAudible() const return d->adapter->recentlyAudible(); } +qint64 QQuickWebEngineView::renderProcessPid() const +{ + const Q_D(QQuickWebEngineView); + return d->adapter->renderProcessPid(); +} + void QQuickWebEngineView::printToPdf(const QString& filePath, PrintedPageSizeId pageSizeId, PrintedPageOrientation orientation) { #if QT_CONFIG(webengine_printing_and_pdf) diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h index 3a47b892b..ab84b2600 100644 --- a/src/webengine/api/qquickwebengineview_p.h +++ b/src/webengine/api/qquickwebengineview_p.h @@ -142,6 +142,8 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem { Q_PROPERTY(LifecycleState lifecycleState READ lifecycleState WRITE setLifecycleState NOTIFY lifecycleStateChanged REVISION 10 FINAL) Q_PROPERTY(LifecycleState recommendedState READ recommendedState NOTIFY recommendedStateChanged REVISION 10 FINAL) + Q_PROPERTY(qint64 renderProcessPid READ renderProcessPid NOTIFY renderProcessPidChanged FINAL REVISION 11) + public: QQuickWebEngineView(QQuickItem *parent = 0); ~QQuickWebEngineView(); @@ -493,6 +495,8 @@ public: void setAudioMuted(bool muted); bool recentlyAudible() const; + qint64 renderProcessPid() const; + #if QT_CONFIG(webengine_testsupport) QQuickWebEngineTestSupport *testSupport() const; void setTestSupport(QQuickWebEngineTestSupport *testSupport); @@ -576,6 +580,7 @@ Q_SIGNALS: Q_REVISION(10) void lifecycleStateChanged(LifecycleState state); Q_REVISION(10) void recommendedStateChanged(LifecycleState state); Q_REVISION(10) void findTextFinished(const QWebEngineFindTextResult &result); + Q_REVISION(11) void renderProcessPidChanged(qint64 pid); #if QT_CONFIG(webengine_testsupport) void testSupportChanged(); diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index a2ae86f91..8557a8db5 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -112,6 +112,7 @@ public: void didUpdateTargetURL(const QUrl&) override; void selectionChanged() override; void recentlyAudibleChanged(bool recentlyAudible) override; + void renderProcessPidChanged(qint64 pid) override; QRectF viewportRect() const override; QColor backgroundColor() const override; void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) override; diff --git a/src/webengine/doc/src/webengineview_lgpl.qdoc b/src/webengine/doc/src/webengineview_lgpl.qdoc index 6e349dfb3..0cd8441cf 100644 --- a/src/webengine/doc/src/webengineview_lgpl.qdoc +++ b/src/webengine/doc/src/webengineview_lgpl.qdoc @@ -1614,3 +1614,27 @@ \sa findText(), FindTextResult */ + +/*! + \qmlproperty qint64 WebEngineView::renderProcessPid + \brief Returns the process ID (PID) of the render process assigned to the + current page's main frame. + \since QtWebEngine 1.11 + \readonly + + If no render process is available yet, \c 0 is returned. + + \sa renderProcessPidChanged +*/ + +/*! + \qmlsignal WebEngineView::renderProcessPidChanged(qint64 pid) + \since QtWebEngine 1.11 + \readonly + + If no render process is available yet, \c 0 is returned. + This signal is emitted when the PID (process ID) of the page's underlying + render process changed. + + \sa renderProcessPid +*/ diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp index ecd381371..a74373b23 100644 --- a/src/webengine/plugin/plugin.cpp +++ b/src/webengine/plugin/plugin.cpp @@ -97,6 +97,7 @@ public: qmlRegisterType(uri, 1, 8, "WebEngineView"); qmlRegisterType(uri, 1, 9, "WebEngineView"); qmlRegisterType(uri, 1, 10, "WebEngineView"); + qmlRegisterType(uri, 1, 11, "WebEngineView"); qmlRegisterType(uri, 1, 1, "WebEngineProfile"); qmlRegisterType(uri, 1, 2, "WebEngineProfile"); qmlRegisterType(uri, 1, 3, "WebEngineProfile"); diff --git a/src/webengine/plugin/plugins.qmltypes b/src/webengine/plugin/plugins.qmltypes index a23d1c3c0..24b073290 100644 --- a/src/webengine/plugin/plugins.qmltypes +++ b/src/webengine/plugin/plugins.qmltypes @@ -1348,6 +1348,7 @@ Module { Property { name: "devToolsView"; revision: 7; type: "QQuickWebEngineView"; isPointer: true } Property { name: "lifecycleState"; revision: 10; type: "LifecycleState" } Property { name: "recommendedState"; revision: 10; type: "LifecycleState"; isReadonly: true } + Property { name: "renderProcessId"; revision: 11; type: "qint64"; isReadonly: true } Signal { name: "loadingChanged" Parameter { name: "loadRequest"; type: "QQuickWebEngineLoadRequest"; isPointer: true } @@ -1526,6 +1527,11 @@ Module { revision: 10 Parameter { name: "result"; type: "QWebEngineFindTextResult" } } + Signal { + name: "renderProcessPidChanged" + revision: 11 + Parameter { name: "pid"; type: "qint64" } + } Method { name: "runJavaScript" Parameter { type: "string" } diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index c176589b2..54e4dd9af 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -277,6 +277,12 @@ void QWebEnginePagePrivate::recentlyAudibleChanged(bool recentlyAudible) Q_EMIT q->recentlyAudibleChanged(recentlyAudible); } +void QWebEnginePagePrivate::renderProcessPidChanged(qint64 pid) +{ + Q_Q(QWebEnginePage); + Q_EMIT q->renderProcessPidChanged(pid); +} + QRectF QWebEnginePagePrivate::viewportRect() const { return view ? view->rect() : QRectF(); @@ -936,6 +942,13 @@ QWebEnginePage::QWebEnginePage(QObject* parent) delay}, from the moment the audio is paused. */ +/*! + \fn void QWebEnginePage::renderProcessPidChanged(qint64 pid); + \since 5.15 + + This signal is emitted when the underlying render process PID, \a renderProcessPid, changes. +*/ + /*! \fn void QWebEnginePage::iconUrlChanged(const QUrl &url) @@ -1149,6 +1162,20 @@ bool QWebEnginePage::recentlyAudible() const return d->adapter->isInitialized() && d->adapter->recentlyAudible(); } +/*! + \property QWebEnginePage::renderProcessPid + \brief The process ID (PID) of the render process assigned to the current + page's main frame. + \since 5.15 + + If no render process is available yet, \c 0 is returned. +*/ +qint64 QWebEnginePage::renderProcessPid() const +{ + Q_D(const QWebEnginePage); + return d->adapter->renderProcessPid(); +} + void QWebEnginePage::setView(QWidget *newViewBase) { QWebEnginePagePrivate::bindPageAndView(this, qobject_cast(newViewBase)); diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h index cd012ea70..3cf6a9f8b 100644 --- a/src/webenginewidgets/api/qwebenginepage.h +++ b/src/webenginewidgets/api/qwebenginepage.h @@ -92,6 +92,7 @@ class QWEBENGINEWIDGETS_EXPORT QWebEnginePage : public QObject { Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged) Q_PROPERTY(LifecycleState lifecycleState READ lifecycleState WRITE setLifecycleState NOTIFY lifecycleStateChanged) Q_PROPERTY(LifecycleState recommendedState READ recommendedState NOTIFY recommendedStateChanged) + Q_PROPERTY(qint64 renderProcessPid READ renderProcessPid NOTIFY renderProcessPidChanged) public: enum WebAction { @@ -305,6 +306,7 @@ public: bool isAudioMuted() const; void setAudioMuted(bool muted); bool recentlyAudible() const; + qint64 renderProcessPid() const; void printToPdf(const QString &filePath, const QPageLayout &layout = QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF())); void printToPdf(const QWebEngineCallback &resultCallback, const QPageLayout &layout = QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF())); @@ -361,6 +363,7 @@ Q_SIGNALS: void contentsSizeChanged(const QSizeF &size); void audioMutedChanged(bool muted); void recentlyAudibleChanged(bool recentlyAudible); + void renderProcessPidChanged(qint64 pid); void pdfPrintingFinished(const QString &filePath, bool success); void printRequested(); diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h index e78b0f926..7fdc811e2 100644 --- a/src/webenginewidgets/api/qwebenginepage_p.h +++ b/src/webenginewidgets/api/qwebenginepage_p.h @@ -103,6 +103,7 @@ public: void didUpdateTargetURL(const QUrl&) override; void selectionChanged() override; void recentlyAudibleChanged(bool recentlyAudible) override; + void renderProcessPidChanged(qint64 pid) override; QRectF viewportRect() const override; QColor backgroundColor() const override; void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) override; -- cgit v1.2.3