summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSzabolcs David <davidsz@inf.u-szeged.hu>2023-06-23 11:59:21 +0200
committerSzabolcs David <davidsz@inf.u-szeged.hu>2023-12-14 11:09:10 +0100
commit075d57c6d1ef9377c1d5c78af86ef5bc889b320b (patch)
tree64a1828347dc6d9dcbfca8db52cfdaea14205b2c /src
parent842f122ce529c9c2935103bb235f0bf540a6a78e (diff)
Add API to override User Agent Client Hints
Implement QWebEngineClientHints class to provide API for each user agent client hints. Task-number: QTBUG-112826 Task-number: QTBUG-112825 Change-Id: I3091d60fb363bbafc16c8e48195c1fd82e8a81bb Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src')
-rw-r--r--src/core/api/CMakeLists.txt1
-rw-r--r--src/core/api/qwebengineclienthints.cpp133
-rw-r--r--src/core/api/qwebengineclienthints.h72
-rw-r--r--src/core/api/qwebengineprofile.cpp8
-rw-r--r--src/core/api/qwebengineprofile.h2
-rw-r--r--src/core/api/qwebengineprofile_p.h2
-rw-r--r--src/core/client_hints.cpp10
-rw-r--r--src/core/content_browser_client_qt.cpp3
-rw-r--r--src/core/content_browser_client_qt.h3
-rw-r--r--src/core/profile_adapter.cpp114
-rw-r--r--src/core/profile_adapter.h19
-rw-r--r--src/core/profile_qt.cpp6
-rw-r--r--src/core/profile_qt.h5
-rw-r--r--src/core/web_contents_adapter.cpp2
-rw-r--r--src/webenginequick/api/qquickwebengineprofile.cpp8
-rw-r--r--src/webenginequick/api/qquickwebengineprofile.h2
-rw-r--r--src/webenginequick/api/qquickwebengineprofile_p.h2
17 files changed, 382 insertions, 10 deletions
diff --git a/src/core/api/CMakeLists.txt b/src/core/api/CMakeLists.txt
index 8357ea4f4..296580a9d 100644
--- a/src/core/api/CMakeLists.txt
+++ b/src/core/api/CMakeLists.txt
@@ -12,6 +12,7 @@ qt_internal_add_module(WebEngineCore
qwebenginecertificateerror.cpp qwebenginecertificateerror.h
qwebengineclientcertificateselection.cpp qwebengineclientcertificateselection.h
qwebengineclientcertificatestore.cpp qwebengineclientcertificatestore.h
+ qwebengineclienthints.cpp qwebengineclienthints.h
qwebenginecontextmenurequest.cpp qwebenginecontextmenurequest.h qwebenginecontextmenurequest_p.h
qwebenginecookiestore.cpp qwebenginecookiestore.h qwebenginecookiestore_p.h
qwebenginedownloadrequest.cpp qwebenginedownloadrequest.h qwebenginedownloadrequest_p.h
diff --git a/src/core/api/qwebengineclienthints.cpp b/src/core/api/qwebengineclienthints.cpp
new file mode 100644
index 000000000..2388f9e3c
--- /dev/null
+++ b/src/core/api/qwebengineclienthints.cpp
@@ -0,0 +1,133 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qwebengineclienthints.h"
+
+#include "profile_adapter.h"
+
+#include <QJsonObject>
+
+QT_BEGIN_NAMESPACE
+
+QWebEngineClientHints::QWebEngineClientHints(QtWebEngineCore::ProfileAdapter *profileAdapter)
+ : m_profileAdapter(profileAdapter)
+{
+}
+
+QWebEngineClientHints::~QWebEngineClientHints()
+{
+}
+
+QString QWebEngineClientHints::arch() const
+{
+ return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAArchitecture).toString();
+}
+
+QString QWebEngineClientHints::platform() const
+{
+ return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAPlatform).toString();
+}
+
+QString QWebEngineClientHints::model() const
+{
+ return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAModel).toString();
+}
+
+bool QWebEngineClientHints::isMobile() const
+{
+ return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAMobile).toBool();
+}
+
+QString QWebEngineClientHints::fullVersion() const
+{
+ return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAFullVersion).toString();
+}
+
+QString QWebEngineClientHints::platformVersion() const
+{
+ return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAPlatformVersion).toString();
+}
+
+QString QWebEngineClientHints::bitness() const
+{
+ return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UABitness).toString();
+}
+
+QHash<QString,QString> QWebEngineClientHints::fullVersionList() const
+{
+ QHash<QString, QString> ret;
+ QJsonObject fullVersionList = m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAFullVersionList).toJsonObject();
+ for (const QString &key : fullVersionList.keys())
+ ret.insert(key, fullVersionList.value(key).toString());
+ return ret;
+}
+
+bool QWebEngineClientHints::isWow64() const
+{
+ return m_profileAdapter->clientHint(QtWebEngineCore::ProfileAdapter::UAWOW64).toBool();
+}
+
+void QWebEngineClientHints::setArch(const QString &arch)
+{
+ m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAArchitecture, QVariant(arch));
+}
+
+void QWebEngineClientHints::setPlatform(const QString &platform)
+{
+ m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAPlatform, QVariant(platform));
+}
+
+void QWebEngineClientHints::setModel(const QString &model)
+{
+ m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAModel, QVariant(model));
+}
+
+void QWebEngineClientHints::setIsMobile(const bool mobile)
+{
+ m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAMobile, QVariant(mobile));
+}
+
+void QWebEngineClientHints::setFullVersion(const QString &fullVerson)
+{
+ m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAFullVersion, QVariant(fullVerson));
+}
+
+void QWebEngineClientHints::setPlatformVersion(const QString &platformVersion)
+{
+ m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAPlatformVersion, QVariant(platformVersion));
+}
+
+void QWebEngineClientHints::setBitness(const QString &bitness)
+{
+ m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UABitness, QVariant(bitness));
+}
+
+void QWebEngineClientHints::setFullVersionList(const QHash<QString,QString> &fullVersionList)
+{
+ QJsonObject jsonObject;
+ for (auto i = fullVersionList.cbegin(), end = fullVersionList.cend(); i != end; ++i)
+ jsonObject.insert(i.key(), QJsonValue(i.value()));
+ m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAFullVersionList, QVariant(jsonObject));
+}
+
+void QWebEngineClientHints::setIsWow64(const bool wow64)
+{
+ m_profileAdapter->setClientHint(QtWebEngineCore::ProfileAdapter::UAWOW64, QVariant(wow64));
+}
+
+bool QWebEngineClientHints::isAllClientHintsEnabled()
+{
+ return m_profileAdapter->clientHintsEnabled();
+}
+
+void QWebEngineClientHints::setAllClientHintsEnabled(bool enabled)
+{
+ m_profileAdapter->setClientHintsEnabled(enabled);
+}
+
+void QWebEngineClientHints::resetAll()
+{
+ m_profileAdapter->resetClientHints();
+}
+
+QT_END_NAMESPACE
diff --git a/src/core/api/qwebengineclienthints.h b/src/core/api/qwebengineclienthints.h
new file mode 100644
index 000000000..8956b5cb6
--- /dev/null
+++ b/src/core/api/qwebengineclienthints.h
@@ -0,0 +1,72 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QWEBENGINECLIENTHINTS_H
+#define QWEBENGINECLIENTHINTS_H
+
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+
+#include <QtCore/qobject.h>
+#include <QtCore/qhash.h>
+
+namespace QtWebEngineCore {
+class ProfileAdapter;
+}
+
+QT_BEGIN_NAMESPACE
+
+class Q_WEBENGINECORE_EXPORT QWebEngineClientHints
+{
+ Q_GADGET
+ Q_PROPERTY(QString arch READ arch WRITE setArch)
+ Q_PROPERTY(QString platform READ platform WRITE setPlatform)
+ Q_PROPERTY(QString model READ model WRITE setModel)
+ Q_PROPERTY(bool mobile READ isMobile WRITE setIsMobile)
+ Q_PROPERTY(QString fullVersion READ fullVersion WRITE setFullVersion)
+ Q_PROPERTY(QString platformVersion READ platformVersion WRITE setPlatformVersion)
+ Q_PROPERTY(QString bitness READ bitness WRITE setBitness)
+ Q_PROPERTY(QHash<QString,QString> fullVersionList READ fullVersionList WRITE setFullVersionList)
+ Q_PROPERTY(bool wow64 READ isWow64 WRITE setIsWow64)
+
+ Q_PROPERTY(bool isAllClientHintsEnabled READ isAllClientHintsEnabled WRITE setAllClientHintsEnabled)
+
+public:
+ ~QWebEngineClientHints();
+
+ QString arch() const;
+ QString platform() const;
+ QString model() const;
+ bool isMobile() const;
+ QString fullVersion() const;
+ QString platformVersion() const;
+ QString bitness() const;
+ QHash<QString,QString> fullVersionList() const;
+ bool isWow64() const;
+
+ void setArch(const QString &);
+ void setPlatform(const QString &);
+ void setModel(const QString &);
+ void setIsMobile(const bool);
+ void setFullVersion(const QString &);
+ void setPlatformVersion(const QString &);
+ void setBitness(const QString &);
+ void setFullVersionList(const QHash<QString,QString> &);
+ void setIsWow64(const bool);
+
+ bool isAllClientHintsEnabled();
+ void setAllClientHintsEnabled(bool enabled);
+
+ void resetAll();
+
+private:
+ explicit QWebEngineClientHints(QtWebEngineCore::ProfileAdapter *profileAdapter);
+ Q_DISABLE_COPY(QWebEngineClientHints)
+ friend class QWebEngineProfilePrivate;
+ friend class QQuickWebEngineProfilePrivate;
+
+ QtWebEngineCore::ProfileAdapter *m_profileAdapter;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINECLIENTHINTS_H
diff --git a/src/core/api/qwebengineprofile.cpp b/src/core/api/qwebengineprofile.cpp
index 6fd304fc2..e619696df 100644
--- a/src/core/api/qwebengineprofile.cpp
+++ b/src/core/api/qwebengineprofile.cpp
@@ -3,6 +3,7 @@
#include "qwebengineprofile.h"
#include "qwebengineprofile_p.h"
+#include "qwebengineclienthints.h"
#include "qwebenginecookiestore.h"
#include "qwebenginedownloadrequest.h"
#include "qwebenginedownloadrequest_p.h"
@@ -143,6 +144,7 @@ QWebEngineProfilePrivate::QWebEngineProfilePrivate(ProfileAdapter* profileAdapte
, m_profileAdapter(profileAdapter)
, m_scriptCollection(new QWebEngineScriptCollection(
new QWebEngineScriptCollectionPrivate(profileAdapter->userResourceController())))
+ , m_clientHints(new QWebEngineClientHints(profileAdapter))
{
m_profileAdapter->addClient(this);
}
@@ -927,6 +929,12 @@ void QWebEngineProfile::requestIconForIconURL(const QUrl &url, int desiredSizeIn
iconAvailableCallback);
}
+QWebEngineClientHints *QWebEngineProfile::clientHints() const
+{
+ Q_D(const QWebEngineProfile);
+ return d->m_clientHints.data();
+}
+
QT_END_NAMESPACE
#include "moc_qwebengineprofile.cpp"
diff --git a/src/core/api/qwebengineprofile.h b/src/core/api/qwebengineprofile.h
index 756f77d36..a0027cb81 100644
--- a/src/core/api/qwebengineprofile.h
+++ b/src/core/api/qwebengineprofile.h
@@ -17,6 +17,7 @@ QT_BEGIN_NAMESPACE
class QUrl;
class QWebEngineClientCertificateStore;
+class QWebEngineClientHints;
class QWebEngineCookieStore;
class QWebEngineDownloadRequest;
class QWebEngineNotification;
@@ -81,6 +82,7 @@ public:
QWebEngineSettings *settings() const;
QWebEngineScriptCollection *scripts() const;
+ QWebEngineClientHints *clientHints() const;
const QWebEngineUrlSchemeHandler *urlSchemeHandler(const QByteArray &) const;
void installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *);
diff --git a/src/core/api/qwebengineprofile_p.h b/src/core/api/qwebengineprofile_p.h
index 0bf54c17b..377692f16 100644
--- a/src/core/api/qwebengineprofile_p.h
+++ b/src/core/api/qwebengineprofile_p.h
@@ -31,6 +31,7 @@ class WebEngineSettings;
QT_BEGIN_NAMESPACE
+class QWebEngineClientHints;
class QWebEngineNotification;
class QWebEngineProfile;
class QWebEngineScriptCollection;
@@ -64,6 +65,7 @@ private:
QWebEngineSettings *m_settings;
QPointer<QtWebEngineCore::ProfileAdapter> m_profileAdapter;
QScopedPointer<QWebEngineScriptCollection> m_scriptCollection;
+ QScopedPointer<QWebEngineClientHints> m_clientHints;
QMap<quint32, QPointer<QWebEngineDownloadRequest>> m_ongoingDownloads;
std::function<void(std::unique_ptr<QWebEngineNotification>)> m_notificationPresenter;
};
diff --git a/src/core/client_hints.cpp b/src/core/client_hints.cpp
index 2fcecde58..9fa7531da 100644
--- a/src/core/client_hints.cpp
+++ b/src/core/client_hints.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "client_hints.h"
+#include "profile_qt.h"
#include "web_contents_delegate_qt.h"
#include "web_engine_settings.h"
@@ -59,6 +60,7 @@ content::BrowserContext *ClientHintsFactory::GetBrowserContextToUse(content::Bro
// found in the LICENSE file.
ClientHints::ClientHints(content::BrowserContext *context)
+ : context_(context)
{
}
@@ -81,8 +83,9 @@ void ClientHints::PersistClientHints(const url::Origin &primary_origin,
return;
blink::EnabledClientHints enabled_hints;
+ ProfileAdapter *profileAdapter = static_cast<ProfileQt *>(context_)->profileAdapter();
for (auto hint : client_hints) {
- enabled_hints.SetIsEnabled(hint, true);
+ enabled_hints.SetIsEnabled(hint, profileAdapter->clientHintsEnabled());
}
accept_ch_cache_[primary_origin] = enabled_hints;
}
@@ -103,8 +106,9 @@ void ClientHints::GetAllowedClientHintsFromSource(const url::Origin &origin,
*client_hints = it->second;
}
+ ProfileAdapter *profileAdapter = static_cast<ProfileQt *>(context_)->profileAdapter();
for (auto hint : additional_hints_)
- client_hints->SetIsEnabled(hint, true);
+ client_hints->SetIsEnabled(hint, profileAdapter->clientHintsEnabled());
}
void ClientHints::SetAdditionalClientHints(const std::vector<network::mojom::WebClientHintsType> &hints)
@@ -158,7 +162,7 @@ bool ClientHints::AreThirdPartyCookiesBlocked(const GURL &url, content::RenderFr
blink::UserAgentMetadata ClientHints::GetUserAgentMetadata()
{
- return embedder_support::GetUserAgentMetadata();
+ return static_cast<ProfileQt *>(context_)->userAgentMetadata();
}
void ClientHints::SetMostRecentMainFrameViewportSize(
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index 5b8f9697d..53c2caa2d 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -970,8 +970,9 @@ std::string ContentBrowserClientQt::getUserAgent()
+ std::string(qWebEngineChromiumVersion()));
}
-blink::UserAgentMetadata ContentBrowserClientQt::getUserAgentMetadata()
+blink::UserAgentMetadata ContentBrowserClientQt::GetUserAgentMetadata()
{
+ // Implemented only for safe-keeping. It will be overridden on WebContents level.
static blink::UserAgentMetadata userAgentMetadata(embedder_support::GetUserAgentMetadata());
return userAgentMetadata;
}
diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h
index d824793ba..7d8e98028 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -230,10 +230,9 @@ public:
std::unique_ptr<content::WebContentsViewDelegate> GetWebContentsViewDelegate(content::WebContents *web_contents) override;
static std::string getUserAgent();
- static blink::UserAgentMetadata getUserAgentMetadata();
std::string GetUserAgent() override { return getUserAgent(); }
- blink::UserAgentMetadata GetUserAgentMetadata() override { return getUserAgentMetadata(); }
+ blink::UserAgentMetadata GetUserAgentMetadata() override;
std::string GetProduct() override;
content::WebAuthenticationDelegate *GetWebAuthenticationDelegate() override;
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index fdb01d4ed..b26f9b1de 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -7,6 +7,7 @@
#include "base/task/cancelable_task_tracker.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time_to_iso8601.h"
+#include "components/embedder_support/user_agent_utils.h"
#include "components/favicon/core/favicon_service.h"
#include "components/history/content/browser/history_database_helper.h"
#include "components/history/core/browser/history_database_params.h"
@@ -39,6 +40,7 @@
#include <QCoreApplication>
#include <QDir>
+#include <QJsonObject>
#include <QSet>
#include <QString>
#include <QStandardPaths>
@@ -63,6 +65,7 @@ ProfileAdapter::ProfileAdapter(const QString &storageName):
, m_httpCacheType(DiskHttpCache)
, m_persistentCookiesPolicy(AllowPersistentCookies)
, m_visitedLinksPolicy(TrackVisitedLinksOnDisk)
+ , m_clientHintsEnabled(true)
, m_pushServiceEnabled(false)
, m_httpCacheMaxSize(0)
{
@@ -319,8 +322,11 @@ void ProfileAdapter::setHttpUserAgent(const QString &userAgent)
std::vector<content::WebContentsImpl *> list = content::WebContentsImpl::GetAllWebContents();
for (content::WebContentsImpl *web_contents : list)
- if (web_contents->GetBrowserContext() == m_profile.data())
- web_contents->SetUserAgentOverride(blink::UserAgentOverride::UserAgentOnly(stdUserAgent), true);
+ if (web_contents->GetBrowserContext() == m_profile.data()) {
+ auto userAgentOverride = blink::UserAgentOverride::UserAgentOnly(stdUserAgent);
+ userAgentOverride.ua_metadata_override = m_profile->m_userAgentMetadata;
+ web_contents->SetUserAgentOverride(userAgentOverride, true);
+ }
m_profile->ForEachLoadedStoragePartition(
base::BindRepeating([](const std::string &user_agent, content::StoragePartition *storage_partition) {
@@ -590,6 +596,110 @@ void ProfileAdapter::setHttpAcceptLanguage(const QString &httpAcceptLanguage)
}, http_accept_language));
}
+QVariant ProfileAdapter::clientHint(ClientHint clientHint) const
+{
+ blink::UserAgentMetadata &userAgentMetadata = m_profile->m_userAgentMetadata;
+ switch (clientHint) {
+ case ProfileAdapter::UAArchitecture:
+ return QVariant(toQString(userAgentMetadata.architecture));
+ case ProfileAdapter::UAPlatform:
+ return QVariant(toQString(userAgentMetadata.platform));
+ case ProfileAdapter::UAModel:
+ return QVariant(toQString(userAgentMetadata.model));
+ case ProfileAdapter::UAMobile:
+ return QVariant(userAgentMetadata.mobile);
+ case ProfileAdapter::UAFullVersion:
+ return QVariant(toQString(userAgentMetadata.full_version));
+ case ProfileAdapter::UAPlatformVersion:
+ return QVariant(toQString(userAgentMetadata.platform_version));
+ case ProfileAdapter::UABitness:
+ return QVariant(toQString(userAgentMetadata.bitness));
+ case ProfileAdapter::UAFullVersionList: {
+ QJsonObject ret;
+ for (const auto &value : userAgentMetadata.brand_full_version_list)
+ ret.insert(toQString(value.brand), QJsonValue(toQString(value.version)));
+ return QVariant(ret);
+ }
+ case ProfileAdapter::UAWOW64:
+ return QVariant(userAgentMetadata.wow64);
+ default:
+ return QVariant();
+ }
+}
+
+void ProfileAdapter::setClientHint(ClientHint clientHint, const QVariant &value)
+{
+ blink::UserAgentMetadata &userAgentMetadata = m_profile->m_userAgentMetadata;
+ switch (clientHint) {
+ case ProfileAdapter::UAArchitecture:
+ userAgentMetadata.architecture = value.toString().toStdString();
+ break;
+ case ProfileAdapter::UAPlatform:
+ userAgentMetadata.platform = value.toString().toStdString();
+ break;
+ case ProfileAdapter::UAModel:
+ userAgentMetadata.model = value.toString().toStdString();
+ break;
+ case ProfileAdapter::UAMobile:
+ userAgentMetadata.mobile = value.toBool();
+ break;
+ case ProfileAdapter::UAFullVersion:
+ userAgentMetadata.full_version = value.toString().toStdString();
+ break;
+ case ProfileAdapter::UAPlatformVersion:
+ userAgentMetadata.platform_version = value.toString().toStdString();
+ break;
+ case ProfileAdapter::UABitness:
+ userAgentMetadata.bitness = value.toString().toStdString();
+ break;
+ case ProfileAdapter::UAFullVersionList: {
+ userAgentMetadata.brand_full_version_list.clear();
+ QJsonObject fullVersionList = value.toJsonObject();
+ for (const QString &key : fullVersionList.keys())
+ userAgentMetadata.brand_full_version_list.push_back({
+ key.toStdString(),
+ fullVersionList.value(key).toString().toStdString()
+ });
+ break;
+ }
+ case ProfileAdapter::UAWOW64:
+ userAgentMetadata.wow64 = value.toBool();
+ break;
+ default:
+ break;
+ }
+
+ std::vector<content::WebContentsImpl *> list = content::WebContentsImpl::GetAllWebContents();
+ for (content::WebContentsImpl *web_contents : list) {
+ if (web_contents->GetBrowserContext() == m_profile.data()) {
+ web_contents->GetMutableRendererPrefs()->user_agent_override.ua_metadata_override = userAgentMetadata;
+ web_contents->SyncRendererPrefs();
+ }
+ }
+}
+
+bool ProfileAdapter::clientHintsEnabled()
+{
+ return m_clientHintsEnabled;
+}
+
+void ProfileAdapter::setClientHintsEnabled(bool enabled)
+{
+ m_clientHintsEnabled = enabled;
+}
+
+void ProfileAdapter::resetClientHints()
+{
+ m_profile->m_userAgentMetadata = embedder_support::GetUserAgentMetadata();
+ std::vector<content::WebContentsImpl *> list = content::WebContentsImpl::GetAllWebContents();
+ for (content::WebContentsImpl *web_contents : list) {
+ if (web_contents->GetBrowserContext() == m_profile.data()) {
+ web_contents->GetMutableRendererPrefs()->user_agent_override.ua_metadata_override = m_profile->m_userAgentMetadata;
+ web_contents->SyncRendererPrefs();
+ }
+ }
+}
+
void ProfileAdapter::clearHttpCache()
{
m_profile->m_profileIOData->clearHttpCache();
diff --git a/src/core/profile_adapter.h b/src/core/profile_adapter.h
index 317364ac0..c778a140d 100644
--- a/src/core/profile_adapter.h
+++ b/src/core/profile_adapter.h
@@ -143,6 +143,18 @@ public:
DeniedPermission = 2
};
+ enum ClientHint : uchar {
+ UAArchitecture,
+ UAPlatform,
+ UAModel,
+ UAMobile,
+ UAFullVersion,
+ UAPlatformVersion,
+ UABitness,
+ UAFullVersionList,
+ UAWOW64,
+ };
+
HttpCacheType httpCacheType() const;
void setHttpCacheType(ProfileAdapter::HttpCacheType);
@@ -173,6 +185,12 @@ public:
QString httpAcceptLanguage() const;
void setHttpAcceptLanguage(const QString &httpAcceptLanguage);
+ QVariant clientHint(ClientHint clientHint) const;
+ void setClientHint(ClientHint clientHint, const QVariant &value);
+ bool clientHintsEnabled();
+ void setClientHintsEnabled(bool enabled);
+ void resetClientHints();
+
void clearHttpCache();
#if QT_CONFIG(ssl)
@@ -221,6 +239,7 @@ private:
QHash<QByteArray, QPointer<QWebEngineUrlSchemeHandler>> m_customUrlSchemeHandlers;
QHash<QByteArray, QWeakPointer<UserNotificationController>> m_ephemeralNotifications;
QHash<QByteArray, QSharedPointer<UserNotificationController>> m_persistentNotifications;
+ bool m_clientHintsEnabled;
QList<ProfileAdapterClient*> m_clients;
QList<WebContentsAdapterClient *> m_webContentsAdapterClients;
diff --git a/src/core/profile_qt.cpp b/src/core/profile_qt.cpp
index 86324fa17..293e8d557 100644
--- a/src/core/profile_qt.cpp
+++ b/src/core/profile_qt.cpp
@@ -44,6 +44,7 @@ namespace QtWebEngineCore {
ProfileQt::ProfileQt(ProfileAdapter *profileAdapter)
: m_profileIOData(new ProfileIODataQt(this))
, m_profileAdapter(profileAdapter)
+ , m_userAgentMetadata(embedder_support::GetUserAgentMetadata())
#if BUILDFLAG(ENABLE_EXTENSIONS)
, m_extensionSystem(nullptr)
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
@@ -269,6 +270,11 @@ const PrefServiceAdapter &ProfileQt::prefServiceAdapter() const
return m_prefServiceAdapter;
}
+const blink::UserAgentMetadata &ProfileQt::userAgentMetadata()
+{
+ return m_userAgentMetadata;
+}
+
content::PlatformNotificationService *ProfileQt::GetPlatformNotificationService()
{
if (!m_platformNotificationService)
diff --git a/src/core/profile_qt.h b/src/core/profile_qt.h
index 2f2b12b18..b5cd08db1 100644
--- a/src/core/profile_qt.h
+++ b/src/core/profile_qt.h
@@ -5,6 +5,7 @@
#define PROFILE_QT_H
#include "chrome/browser/profiles/profile.h"
+#include "components/embedder_support/user_agent_utils.h"
#include "extensions/buildflags/buildflags.h"
#include "pref_service_adapter.h"
@@ -78,9 +79,10 @@ public:
void setupPrefService();
PrefServiceAdapter &prefServiceAdapter();
-
const PrefServiceAdapter &prefServiceAdapter() const;
+ const blink::UserAgentMetadata &userAgentMetadata();
+
private:
std::unique_ptr<BrowsingDataRemoverDelegateQt> m_removerDelegate;
std::unique_ptr<PermissionManagerQt> m_permissionManager;
@@ -89,6 +91,7 @@ private:
std::unique_ptr<content::PlatformNotificationService> m_platformNotificationService;
ProfileAdapter *m_profileAdapter;
PrefServiceAdapter m_prefServiceAdapter;
+ blink::UserAgentMetadata m_userAgentMetadata;
#if BUILDFLAG(ENABLE_EXTENSIONS)
extensions::ExtensionSystemQt *m_extensionSystem;
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 989927199..494e5a8cb 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -518,7 +518,7 @@ void WebContentsAdapter::initializeRenderPrefs()
rendererPrefs->caret_blink_interval =
base::Milliseconds(0.5 * static_cast<double>(qtCursorFlashTime));
rendererPrefs->user_agent_override = blink::UserAgentOverride::UserAgentOnly(m_profileAdapter->httpUserAgent().toStdString());
- rendererPrefs->user_agent_override.ua_metadata_override = ContentBrowserClientQt::getUserAgentMetadata();
+ rendererPrefs->user_agent_override.ua_metadata_override = profile()->userAgentMetadata();
rendererPrefs->accept_languages = m_profileAdapter->httpAcceptLanguageWithoutQualities().toStdString();
#if QT_CONFIG(webengine_webrtc)
base::CommandLine* commandLine = base::CommandLine::ForCurrentProcess();
diff --git a/src/webenginequick/api/qquickwebengineprofile.cpp b/src/webenginequick/api/qquickwebengineprofile.cpp
index 386e82cf4..847570b03 100644
--- a/src/webenginequick/api/qquickwebengineprofile.cpp
+++ b/src/webenginequick/api/qquickwebengineprofile.cpp
@@ -14,6 +14,7 @@
#include <QtWebEngineCore/qwebenginescriptcollection.h>
#include <QtWebEngineCore/private/qwebenginescriptcollection_p.h>
+#include <QtWebEngineCore/qwebengineclienthints.h>
#include <QtWebEngineCore/qwebenginecookiestore.h>
#include <QtWebEngineCore/qwebenginenotification.h>
#include <QtWebEngineCore/private/qwebenginedownloadrequest_p.h>
@@ -135,6 +136,7 @@ QT_BEGIN_NAMESPACE
QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(ProfileAdapter *profileAdapter)
: m_settings(new QQuickWebEngineSettings())
+ , m_clientHints(new QWebEngineClientHints(profileAdapter))
, m_profileAdapter(profileAdapter)
{
profileAdapter->addClient(this);
@@ -1022,6 +1024,12 @@ QWebEngineClientCertificateStore *QQuickWebEngineProfile::clientCertificateStore
#endif
}
+QWebEngineClientHints *QQuickWebEngineProfile::clientHints() const
+{
+ Q_D(const QQuickWebEngineProfile);
+ return d->m_clientHints.data();
+}
+
void QQuickWebEngineProfile::ensureQmlContext(const QObject *object)
{
if (!qmlContext(this)) {
diff --git a/src/webenginequick/api/qquickwebengineprofile.h b/src/webenginequick/api/qquickwebengineprofile.h
index 29f5ca82f..088a971e0 100644
--- a/src/webenginequick/api/qquickwebengineprofile.h
+++ b/src/webenginequick/api/qquickwebengineprofile.h
@@ -15,6 +15,7 @@ QT_BEGIN_NAMESPACE
class QQuickWebEngineDownloadRequest;
class QQuickWebEngineSettings;
class QWebEngineClientCertificateStore;
+class QWebEngineClientHints;
class QWebEngineCookieStore;
class QWebEngineNotification;
class QWebEngineUrlRequestInterceptor;
@@ -113,6 +114,7 @@ public:
void setPushServiceEnabled(bool enable);
QWebEngineClientCertificateStore *clientCertificateStore();
+ QWebEngineClientHints *clientHints() const;
static QQuickWebEngineProfile *defaultProfile();
diff --git a/src/webenginequick/api/qquickwebengineprofile_p.h b/src/webenginequick/api/qquickwebengineprofile_p.h
index f463bab5a..477936f98 100644
--- a/src/webenginequick/api/qquickwebengineprofile_p.h
+++ b/src/webenginequick/api/qquickwebengineprofile_p.h
@@ -28,6 +28,7 @@ class ProfileAdapter;
QT_BEGIN_NAMESPACE
+class QWebEngineClientHints;
class QQuickWebEngineDownloadRequest;
class QQuickWebEngineSettings;
class QQuickWebEngineScriptCollection;
@@ -58,6 +59,7 @@ public:
private:
QQuickWebEngineProfile *q_ptr;
QScopedPointer<QQuickWebEngineSettings> m_settings;
+ QScopedPointer<QWebEngineClientHints> m_clientHints;
QPointer<QtWebEngineCore::ProfileAdapter> m_profileAdapter;
QMap<quint32, QPointer<QQuickWebEngineDownloadRequest> > m_ongoingDownloads;