summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichal Klocek <michal.klocek@qt.io>2019-02-28 10:49:22 +0100
committerMichal Klocek <michal.klocek@qt.io>2019-03-01 15:59:37 +0000
commit56fadb571f32b721d8b99554e6e38692009ec37f (patch)
tree0d57ee708bca414342c69dbf924a016f09361169 /src
parentddfa2997939fc4de2993b3e0de2201eca534af61 (diff)
Force destruction of webcontent client before profile adapter
Currently users might forget to delete webcontent client before profile adapter. This might be nasty if users are not aware of default profile. Instead of asserting badly in chromium, clean up and release chromium resources. This avoids the crash, but might leak memory if users never deletes page. Task-number: QTBUG-74021 Change-Id: I66f466f169d12f7ee08866d505260dca47800bb0 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/core/profile_adapter.cpp14
-rw-r--r--src/core/profile_adapter.h5
-rw-r--r--src/core/profile_adapter_client.h2
-rw-r--r--src/core/web_contents_adapter_client.h1
-rw-r--r--src/webengine/api/qquickwebengineprofile.cpp15
-rw-r--r--src/webengine/api/qquickwebengineprofile_p.h5
-rw-r--r--src/webengine/api/qquickwebengineview.cpp2
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h2
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp22
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h1
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp12
-rw-r--r--src/webenginewidgets/api/qwebengineprofile_p.h3
12 files changed, 65 insertions, 19 deletions
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index 50a97a6ac..1b946949a 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -53,6 +53,7 @@
#include "type_conversion.h"
#include "visited_links_manager_qt.h"
#include "web_engine_context.h"
+#include "web_contents_adapter_client.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
@@ -92,6 +93,9 @@ ProfileAdapter::ProfileAdapter(const QString &storageName):
ProfileAdapter::~ProfileAdapter()
{
+ while (!m_webContentsAdapterClients.isEmpty()) {
+ m_webContentsAdapterClients.first()->releaseProfile();
+ }
WebEngineContext::current()->removeProfileAdapter(this);
if (m_downloadManagerDelegate) {
m_profile->GetDownloadManager(m_profile.data())->Shutdown();
@@ -547,6 +551,16 @@ bool ProfileAdapter::isSpellCheckEnabled() const
#endif
}
+void ProfileAdapter::addWebContentsAdapterClient(WebContentsAdapterClient *client)
+{
+ m_webContentsAdapterClients.append(client);
+}
+
+void ProfileAdapter::removeWebContentsAdapterClient(WebContentsAdapterClient *client)
+{
+ m_webContentsAdapterClients.removeAll(client);
+}
+
void ProfileAdapter::resetVisitedLinksManager()
{
m_visitedLinksManager.reset(new VisitedLinksManagerQt(this));
diff --git a/src/core/profile_adapter.h b/src/core/profile_adapter.h
index 9bc92b54a..7ed5c13f5 100644
--- a/src/core/profile_adapter.h
+++ b/src/core/profile_adapter.h
@@ -73,6 +73,7 @@ class DownloadManagerDelegateQt;
class ProfileQt;
class UserResourceControllerHost;
class VisitedLinksManagerQt;
+class WebContentsAdapterClient;
class QWEBENGINECORE_PRIVATE_EXPORT ProfileAdapter : public QObject
{
@@ -127,6 +128,9 @@ public:
void setSpellCheckEnabled(bool enabled);
bool isSpellCheckEnabled() const;
+ void addWebContentsAdapterClient(WebContentsAdapterClient *client);
+ void removeWebContentsAdapterClient(WebContentsAdapterClient *client);
+
// KEEP IN SYNC with API or add mapping layer
enum HttpCacheType {
MemoryHttpCache = 0,
@@ -211,6 +215,7 @@ private:
VisitedLinksPolicy m_visitedLinksPolicy;
QHash<QByteArray, QWebEngineUrlSchemeHandler *> m_customUrlSchemeHandlers;
QList<ProfileAdapterClient*> m_clients;
+ QVector<WebContentsAdapterClient *> m_webContentsAdapterClients;
int m_httpCacheMaxSize;
Q_DISABLE_COPY(ProfileAdapter)
diff --git a/src/core/profile_adapter_client.h b/src/core/profile_adapter_client.h
index 06051fab6..19af12ca4 100644
--- a/src/core/profile_adapter_client.h
+++ b/src/core/profile_adapter_client.h
@@ -142,6 +142,8 @@ public:
virtual void downloadRequested(DownloadItemInfo &info) = 0;
virtual void downloadUpdated(const DownloadItemInfo &info) = 0;
+ virtual void addWebContentsAdapterClient(WebContentsAdapterClient *adapter) = 0;
+ virtual void removeWebContentsAdapterClient(WebContentsAdapterClient *adapter) = 0;
static QString downloadInterruptReasonToString(DownloadInterruptReason reason);
};
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 55cbe13dd..28be33c23 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -478,6 +478,7 @@ public:
virtual ProfileAdapter *profileAdapter() = 0;
virtual WebContentsAdapter* webContentsAdapter() = 0;
+ virtual void releaseProfile() = 0;
};
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
index b7abb13fc..73577a04c 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -163,11 +163,6 @@ QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(ProfileAdapter *pro
QQuickWebEngineProfilePrivate::~QQuickWebEngineProfilePrivate()
{
-
- while (!m_webContentsAdapterClients.isEmpty()) {
- m_webContentsAdapterClients.first()->destroy();
- }
-
if (m_profileAdapter) {
// In the case the user sets this profile as the parent of the interceptor
// it can be deleted before the browser-context still referencing it is.
@@ -179,14 +174,16 @@ QQuickWebEngineProfilePrivate::~QQuickWebEngineProfilePrivate()
delete m_profileAdapter;
}
-void QQuickWebEngineProfilePrivate::addWebContentsAdapterClient(QQuickWebEngineViewPrivate *adapter)
+void QQuickWebEngineProfilePrivate::addWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter)
{
- m_webContentsAdapterClients.append(adapter);
+ Q_ASSERT(m_profileAdapter);
+ m_profileAdapter->addWebContentsAdapterClient(adapter);
}
-void QQuickWebEngineProfilePrivate::removeWebContentsAdapterClient(QQuickWebEngineViewPrivate*adapter)
+void QQuickWebEngineProfilePrivate::removeWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient*adapter)
{
- m_webContentsAdapterClients.removeAll(adapter);
+ Q_ASSERT(m_profileAdapter);
+ m_profileAdapter->removeWebContentsAdapterClient(adapter);
}
QtWebEngineCore::ProfileAdapter *QQuickWebEngineProfilePrivate::profileAdapter() const
diff --git a/src/webengine/api/qquickwebengineprofile_p.h b/src/webengine/api/qquickwebengineprofile_p.h
index 2b1a5b134..41e513f4c 100644
--- a/src/webengine/api/qquickwebengineprofile_p.h
+++ b/src/webengine/api/qquickwebengineprofile_p.h
@@ -71,8 +71,8 @@ public:
Q_DECLARE_PUBLIC(QQuickWebEngineProfile)
QQuickWebEngineProfilePrivate(QtWebEngineCore::ProfileAdapter *profileAdapter);
~QQuickWebEngineProfilePrivate();
- void addWebContentsAdapterClient(QQuickWebEngineViewPrivate *adapter);
- void removeWebContentsAdapterClient(QQuickWebEngineViewPrivate *adapter);
+ void addWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) override;
+ void removeWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) override;
QtWebEngineCore::ProfileAdapter* profileAdapter() const;
QQuickWebEngineSettings *settings() const;
@@ -98,7 +98,6 @@ private:
QPointer<QtWebEngineCore::ProfileAdapter> m_profileAdapter;
QMap<quint32, QPointer<QQuickWebEngineDownloadItem> > m_ongoingDownloads;
QList<QQuickWebEngineScript *> m_userScripts;
- QVector<QQuickWebEngineViewPrivate *> m_webContentsAdapterClients;
};
QT_END_NAMESPACE
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 35f797cb1..53f12fa97 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -189,7 +189,7 @@ bool QQuickWebEngineViewPrivate::profileInitialized() const
return m_profileInitialized;
}
-void QQuickWebEngineViewPrivate::destroy()
+void QQuickWebEngineViewPrivate::releaseProfile()
{
// The profile for this web contents is about to be
// garbage collected, delete WebContents first and
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index cbba9b568..bc7a05b67 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -90,7 +90,7 @@ public:
QQuickWebEngineView *q_ptr;
QQuickWebEngineViewPrivate();
~QQuickWebEngineViewPrivate();
- void destroy();
+ void releaseProfile() override;
void initializeProfile();
QtWebEngineCore::UIDelegatesManager *ui();
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index aa1f7be7c..fae34ae8d 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -256,12 +256,15 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
ensureInitialized();
wasShown();
});
+
+ profile->d_ptr->addWebContentsAdapterClient(this);
}
QWebEnginePagePrivate::~QWebEnginePagePrivate()
{
delete history;
delete settings;
+ profile->d_ptr->removeWebContentsAdapterClient(this);
}
RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client)
@@ -545,6 +548,13 @@ void QWebEnginePagePrivate::authenticationRequired(QSharedPointer<Authentication
controller->accept(networkAuth.user(), networkAuth.password());
}
+void QWebEnginePagePrivate::releaseProfile()
+{
+ qDebug("Release of profile requested but WebEnginePage still not deleted. Expect troubles !");
+ // this is not the way to go, but might avoid the crash if user code does not make any calls to page.
+ delete q_ptr->d_ptr.take();
+}
+
void QWebEnginePagePrivate::showColorDialog(QSharedPointer<ColorChooserController> controller)
{
#if QT_CONFIG(colordialog)
@@ -967,11 +977,13 @@ QWebEnginePage::QWebEnginePage(QWebEngineProfile *profile, QObject* parent)
QWebEnginePage::~QWebEnginePage()
{
- Q_D(QWebEnginePage);
- setDevToolsPage(nullptr);
- d->adapter->stopFinding();
- QWebEnginePagePrivate::bindPageAndView(this, nullptr);
- QWebEnginePagePrivate::bindPageAndWidget(this, nullptr);
+ if (d_ptr) {
+ // d_ptr might be exceptionally null if profile adapter got deleted first
+ setDevToolsPage(nullptr);
+ d_ptr->adapter->stopFinding();
+ QWebEnginePagePrivate::bindPageAndView(this, nullptr);
+ QWebEnginePagePrivate::bindPageAndWidget(this, nullptr);
+ }
}
QWebEngineHistory *QWebEnginePage::history() const
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index eecbf0b65..a50a1972a 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -129,6 +129,7 @@ public:
void passOnFocus(bool reverse) override;
void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) override;
void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) override;
+ void releaseProfile() override;
void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) override;
void runGeolocationPermissionRequest(const QUrl &securityOrigin) override;
void runMouseLockPermissionRequest(const QUrl &securityOrigin) override;
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index 0d12fdae1..929c2aaa1 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -262,6 +262,18 @@ void QWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info)
download->d_func()->update(info);
}
+void QWebEngineProfilePrivate::addWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter)
+{
+ Q_ASSERT(m_profileAdapter);
+ m_profileAdapter->addWebContentsAdapterClient(adapter);
+}
+
+void QWebEngineProfilePrivate::removeWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter)
+{
+ Q_ASSERT(m_profileAdapter);
+ m_profileAdapter->removeWebContentsAdapterClient(adapter);
+}
+
/*!
Constructs a new off-the-record profile with the parent \a parent.
diff --git a/src/webenginewidgets/api/qwebengineprofile_p.h b/src/webenginewidgets/api/qwebengineprofile_p.h
index 4a76f457f..cb43dace5 100644
--- a/src/webenginewidgets/api/qwebengineprofile_p.h
+++ b/src/webenginewidgets/api/qwebengineprofile_p.h
@@ -86,6 +86,9 @@ public:
void downloadRequested(DownloadItemInfo &info) override;
void downloadUpdated(const DownloadItemInfo &info) override;
+ void addWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) override;
+ void removeWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) override;
+
private:
QWebEngineProfile *q_ptr;
QWebEngineSettings *m_settings;