summaryrefslogtreecommitdiffstats
path: root/src/core/web_contents_delegate_qt.cpp
diff options
context:
space:
mode:
authorJüri Valdmann <juri.valdmann@qt.io>2019-04-12 16:44:18 +0200
committerJüri Valdmann <juri.valdmann@qt.io>2019-05-24 16:14:51 +0200
commita69029cf9fcfd0c1fcdaafe5cbcbff2d5dd6b5c5 (patch)
treea38cae2c082ee3c9a0108942b8406947d826a782 /src/core/web_contents_delegate_qt.cpp
parent0f081baa31facec779057de29eec14c6f458f6a6 (diff)
Implement page lifecycle API
[ChangeLog][QtWebEngine][WebEngineView] WebEngineView now supports lifecycle states that can be used for reducing CPU and memory consumption of invisible views. [ChangeLog][QtWebEngineWidgets][QWebEnginePage] QWebEnginePage now supports lifecycle states that can be used for reducing CPU and memory consumption of invisible pages. Fixes: QTBUG-74166 Fixes: QTBUG-55079 Change-Id: I7d70c85dc995bd17c9fe91385a8e2750dbc0a627 Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
Diffstat (limited to 'src/core/web_contents_delegate_qt.cpp')
-rw-r--r--src/core/web_contents_delegate_qt.cpp133
1 files changed, 133 insertions, 0 deletions
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 021044a71..f4d794de5 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -104,6 +104,8 @@ WebContentsDelegateQt::WebContentsDelegateQt(content::WebContents *webContents,
, m_lastReceivedFindReply(0)
, m_faviconManager(new FaviconManager(webContents, adapterClient))
, m_lastLoadProgress(-1)
+ , m_loadingState(determineLoadingState(webContents))
+ , m_didStartLoadingSeen(m_loadingState == LoadingState::Loading)
{
webContents->SetDelegate(this);
Observe(webContents);
@@ -267,6 +269,18 @@ void WebContentsDelegateQt::RenderFrameDeleted(content::RenderFrameHost *render_
m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID());
}
+void WebContentsDelegateQt::RenderProcessGone(base::TerminationStatus status)
+{
+ // Based one TabLoadTracker::RenderProcessGone
+
+ if (status == base::TerminationStatus::TERMINATION_STATUS_NORMAL_TERMINATION
+ || status == base::TerminationStatus::TERMINATION_STATUS_STILL_RUNNING) {
+ return;
+ }
+
+ setLoadingState(LoadingState::Unloaded);
+}
+
void WebContentsDelegateQt::RenderViewHostChanged(content::RenderViewHost *, content::RenderViewHost *newHost)
{
if (newHost && newHost->GetWidget() && newHost->GetWidget()->GetView()) {
@@ -354,6 +368,46 @@ void WebContentsDelegateQt::DidFinishNavigation(content::NavigationHandle *navig
}
}
+void WebContentsDelegateQt::DidStartLoading()
+{
+ // Based on TabLoadTracker::DidStartLoading
+
+ if (!web_contents()->IsLoadingToDifferentDocument())
+ return;
+ if (m_loadingState == LoadingState::Loading) {
+ DCHECK(m_didStartLoadingSeen);
+ return;
+ }
+ m_didStartLoadingSeen = true;
+}
+
+void WebContentsDelegateQt::DidReceiveResponse()
+{
+ // Based on TabLoadTracker::DidReceiveResponse
+
+ if (m_loadingState == LoadingState::Loading) {
+ DCHECK(m_didStartLoadingSeen);
+ return;
+ }
+
+ // A transition to loading requires both DidStartLoading (navigation
+ // committed) and DidReceiveResponse (data has been transmitted over the
+ // network) events to occur. This is because NavigationThrottles can block
+ // actual network requests, but not the rest of the state machinery.
+ if (m_didStartLoadingSeen)
+ setLoadingState(LoadingState::Loading);
+}
+
+void WebContentsDelegateQt::DidStopLoading()
+{
+ // Based on TabLoadTracker::DidStopLoading
+
+ // NOTE: PageAlmostIdle feature not implemented
+
+ if (m_loadingState == LoadingState::Loading)
+ setLoadingState(LoadingState::Loaded);
+}
+
void WebContentsDelegateQt::didFailLoad(const QUrl &url, int errorCode, const QString &errorDescription)
{
m_viewClient->iconChanged(QUrl());
@@ -362,6 +416,9 @@ void WebContentsDelegateQt::didFailLoad(const QUrl &url, int errorCode, const QS
void WebContentsDelegateQt::DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code, const base::string16& error_description)
{
+ if (m_loadingState == LoadingState::Loading)
+ setLoadingState(LoadingState::Loaded);
+
if (render_frame_host != web_contents()->GetMainFrame())
return;
@@ -724,4 +781,80 @@ WebContentsAdapter *WebContentsDelegateQt::webContentsAdapter() const
return m_viewClient->webContentsAdapter();
}
+void WebContentsDelegateQt::copyStateFrom(WebContentsDelegateQt *source)
+{
+ m_url = source->m_url;
+ m_title = source->m_title;
+ NavigationStateChanged(web_contents(), content::INVALIDATE_TYPE_URL);
+ m_faviconManager->copyStateFrom(source->m_faviconManager.data());
+}
+
+WebContentsDelegateQt::LoadingState WebContentsDelegateQt::determineLoadingState(content::WebContents *contents)
+{
+ // Based on TabLoadTracker::DetermineLoadingState
+
+ if (contents->IsLoadingToDifferentDocument() && !contents->IsWaitingForResponse())
+ return LoadingState::Loading;
+
+ content::NavigationController &controller = contents->GetController();
+ if (controller.GetLastCommittedEntry() != nullptr && !controller.IsInitialNavigation() && !controller.NeedsReload())
+ return LoadingState::Loaded;
+
+ return LoadingState::Unloaded;
+}
+
+void WebContentsDelegateQt::setLoadingState(LoadingState state)
+{
+ if (m_loadingState == state)
+ return;
+
+ m_loadingState = state;
+
+ webContentsAdapter()->updateRecommendedState();
+}
+
+int &WebContentsDelegateQt::streamCount(blink::MediaStreamType type)
+{
+ // Based on MediaStreamCaptureIndicator::WebContentsDeviceUsage::GetStreamCount
+ switch (type) {
+ case blink::MEDIA_DEVICE_AUDIO_CAPTURE:
+ return m_audioStreamCount;
+
+ case blink::MEDIA_DEVICE_VIDEO_CAPTURE:
+ return m_videoStreamCount;
+
+ case blink::MEDIA_GUM_TAB_AUDIO_CAPTURE:
+ case blink::MEDIA_GUM_TAB_VIDEO_CAPTURE:
+ return m_mirroringStreamCount;
+
+ case blink::MEDIA_GUM_DESKTOP_VIDEO_CAPTURE:
+ case blink::MEDIA_GUM_DESKTOP_AUDIO_CAPTURE:
+ case blink::MEDIA_DISPLAY_VIDEO_CAPTURE:
+ return m_desktopStreamCount;
+
+ case blink::MEDIA_NO_SERVICE:
+ case blink::NUM_MEDIA_TYPES:
+ NOTREACHED();
+ return m_videoStreamCount;
+ }
+ NOTREACHED();
+ return m_videoStreamCount;
+}
+
+void WebContentsDelegateQt::addDevices(const blink::MediaStreamDevices &devices)
+{
+ for (const auto &device : devices)
+ ++streamCount(device.type);
+
+ webContentsAdapter()->updateRecommendedState();
+}
+
+void WebContentsDelegateQt::removeDevices(const blink::MediaStreamDevices &devices)
+{
+ for (const auto &device : devices)
+ ++streamCount(device.type);
+
+ webContentsAdapter()->updateRecommendedState();
+}
+
} // namespace QtWebEngineCore