summaryrefslogtreecommitdiffstats
path: root/src/core/profile_adapter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/profile_adapter.cpp')
-rw-r--r--src/core/profile_adapter.cpp637
1 files changed, 475 insertions, 162 deletions
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index b04fa0d46..b26f9b1de 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -1,65 +1,47 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 "profile_adapter.h"
+#include "base/files/file_util.h"
+#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"
+#include "components/history/core/browser/history_service.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/browser/download_manager.h"
+#include "content/public/browser/storage_partition.h"
+#include "services/network/public/mojom/network_context.mojom.h"
+#include "url/url_util.h"
#include "api/qwebengineurlscheme.h"
-#include "content_client_qt.h"
+#include "content_browser_client_qt.h"
#include "download_manager_delegate_qt.h"
-#include "net/url_request_context_getter_qt.h"
+#include "favicon_service_factory_qt.h"
#include "permission_manager_qt.h"
+#include "profile_adapter_client.h"
+#include "profile_io_data_qt.h"
#include "profile_qt.h"
#include "renderer_host/user_resource_controller_host.h"
#include "type_conversion.h"
#include "visited_links_manager_qt.h"
-#include "web_engine_context.h"
#include "web_contents_adapter_client.h"
+#include "web_engine_context.h"
-#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "extensions/browser/extension_system.h"
+#endif
#include <QCoreApplication>
#include <QDir>
+#include <QJsonObject>
+#include <QSet>
#include <QString>
#include <QStandardPaths>
@@ -79,29 +61,45 @@ namespace QtWebEngineCore {
ProfileAdapter::ProfileAdapter(const QString &storageName):
m_name(storageName)
, m_offTheRecord(storageName.isEmpty())
+ , m_downloadPath(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation))
, m_httpCacheType(DiskHttpCache)
, m_persistentCookiesPolicy(AllowPersistentCookies)
, m_visitedLinksPolicy(TrackVisitedLinksOnDisk)
+ , m_clientHintsEnabled(true)
+ , m_pushServiceEnabled(false)
, m_httpCacheMaxSize(0)
{
WebEngineContext::current()->addProfileAdapter(this);
// creation of profile requires webengine context
m_profile.reset(new ProfileQt(this));
- content::BrowserContext::Initialize(m_profile.data(), toFilePath(dataPath()));
// fixme: this should not be here
m_profile->m_profileIOData->initializeOnUIThread();
+ m_customUrlSchemeHandlers.insert(QByteArrayLiteral("qrc"), &m_qrcHandler);
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ if (!storageName.isEmpty())
+ extensions::ExtensionSystem::Get(m_profile.data())->InitForRegularProfile(true);
+#endif
+ m_cancelableTaskTracker.reset(new base::CancelableTaskTracker());
+
+ m_profile->DoFinalInit();
}
ProfileAdapter::~ProfileAdapter()
{
- while (!m_webContentsAdapterClients.isEmpty()) {
- m_webContentsAdapterClients.first()->releaseProfile();
- }
+ m_cancelableTaskTracker->TryCancelAll();
+ m_profile->NotifyWillBeDestroyed();
+ releaseAllWebContentsAdapterClients();
+
WebEngineContext::current()->removeProfileAdapter(this);
if (m_downloadManagerDelegate) {
- m_profile->GetDownloadManager(m_profile.data())->Shutdown();
+ m_profile->GetDownloadManager()->Shutdown();
m_downloadManagerDelegate.reset();
}
+#if QT_CONFIG(ssl)
+ delete m_clientCertificateStore;
+ m_clientCertificateStore = nullptr;
+#endif
+ WebEngineContext::flushMessages();
}
void ProfileAdapter::setStorageName(const QString &storageName)
@@ -110,10 +108,13 @@ void ProfileAdapter::setStorageName(const QString &storageName)
return;
m_name = storageName;
if (!m_offTheRecord) {
- if (m_profile->m_urlRequestContextGetter.get())
- m_profile->m_profileIOData->updateStorageSettings();
+ m_profile->setupPrefService();
+ if (!m_profile->m_profileIOData->isClearHttpCacheInProgress())
+ m_profile->m_profileIOData->resetNetworkContext();
if (m_visitedLinksManager)
resetVisitedLinksManager();
+
+ reinitializeHistoryService();
}
}
@@ -122,10 +123,19 @@ void ProfileAdapter::setOffTheRecord(bool offTheRecord)
if (offTheRecord == m_offTheRecord)
return;
m_offTheRecord = offTheRecord;
- if (m_profile->m_urlRequestContextGetter.get())
- m_profile->m_profileIOData->updateStorageSettings();
+ m_profile->setupPrefService();
+ if (!m_profile->m_profileIOData->isClearHttpCacheInProgress())
+ m_profile->m_profileIOData->resetNetworkContext();
if (m_visitedLinksManager)
resetVisitedLinksManager();
+
+ if (offTheRecord) {
+ favicon::FaviconService *faviconService =
+ FaviconServiceFactoryQt::GetForBrowserContext(m_profile.data());
+ faviconService->SetHistoryService(nullptr);
+ } else if (!m_name.isEmpty()) {
+ reinitializeHistoryService();
+ }
}
ProfileQt *ProfileAdapter::profile()
@@ -133,6 +143,26 @@ ProfileQt *ProfileAdapter::profile()
return m_profile.data();
}
+bool ProfileAdapter::ensureDataPathExists()
+{
+ Q_ASSERT(!m_offTheRecord);
+ base::ScopedAllowBlocking allowBlock;
+ const base::FilePath &path = toFilePath(dataPath());
+ if (path.empty())
+ return false;
+ if (base::DirectoryExists(path))
+ return true;
+
+ base::File::Error error;
+ if (base::CreateDirectoryAndGetError(path, &error))
+ return true;
+
+ std::string errorstr = base::File::ErrorToString(error);
+ qWarning("Cannot create directory %s. Error: %s.", path.AsUTF8Unsafe().c_str(),
+ errorstr.c_str());
+ return false;
+}
+
VisitedLinksManagerQt *ProfileAdapter::visitedLinksManager()
{
if (!m_visitedLinksManager)
@@ -161,11 +191,7 @@ QWebEngineUrlRequestInterceptor *ProfileAdapter::requestInterceptor()
void ProfileAdapter::setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
{
- if (m_requestInterceptor == interceptor)
- return;
m_requestInterceptor = interceptor;
- if (m_profile->m_urlRequestContextGetter.get())
- m_profile->m_profileIOData->updateRequestInterceptor();
}
void ProfileAdapter::addClient(ProfileAdapterClient *adapterClient)
@@ -178,9 +204,9 @@ void ProfileAdapter::removeClient(ProfileAdapterClient *adapterClient)
m_clients.removeOne(adapterClient);
}
-void ProfileAdapter::cancelDownload(quint32 downloadId)
+bool ProfileAdapter::cancelDownload(quint32 downloadId)
{
- downloadManagerDelegate()->cancelDownload(downloadId);
+ return downloadManagerDelegate()->cancelDownload(downloadId);
}
void ProfileAdapter::pauseDownload(quint32 downloadId)
@@ -216,13 +242,17 @@ QObject* ProfileAdapter::globalQObjectRoot()
QString ProfileAdapter::dataPath() const
{
- if (m_offTheRecord)
- return QString();
if (!m_dataPath.isEmpty())
return m_dataPath;
- if (!m_name.isNull())
- return buildLocationFromStandardPath(QStandardPaths::writableLocation(QStandardPaths::DataLocation), m_name);
- return QString();
+ // And off-the-record or memory-only profile should not write to disk
+ // but Chromium often creates temporary directories anyway, so given them
+ // a location to do so.
+ QString name = m_name;
+ if (m_offTheRecord)
+ name = QStringLiteral("OffTheRecord");
+ else if (m_name.isEmpty())
+ name = QStringLiteral("UnknownProfile");
+ return buildLocationFromStandardPath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), name);
}
void ProfileAdapter::setDataPath(const QString &path)
@@ -230,12 +260,19 @@ void ProfileAdapter::setDataPath(const QString &path)
if (m_dataPath == path)
return;
m_dataPath = path;
- if (!m_offTheRecord) {
- if (m_profile->m_urlRequestContextGetter.get())
- m_profile->m_profileIOData->updateStorageSettings();
- if (m_visitedLinksManager)
- resetVisitedLinksManager();
- }
+ m_profile->setupPrefService();
+ if (!m_profile->m_profileIOData->isClearHttpCacheInProgress())
+ m_profile->m_profileIOData->resetNetworkContext();
+ if (!m_offTheRecord && m_visitedLinksManager)
+ resetVisitedLinksManager();
+
+ if (!m_offTheRecord)
+ reinitializeHistoryService();
+}
+
+void ProfileAdapter::setDownloadPath(const QString &path)
+{
+ m_downloadPath = path.isEmpty() ? QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) : path;
}
QString ProfileAdapter::cachePath() const
@@ -254,33 +291,8 @@ void ProfileAdapter::setCachePath(const QString &path)
if (m_cachePath == path)
return;
m_cachePath = path;
- if (!m_offTheRecord && m_profile->m_urlRequestContextGetter.get())
- m_profile->m_profileIOData->updateHttpCache();
-}
-
-QString ProfileAdapter::cookiesPath() const
-{
- if (m_offTheRecord)
- return QString();
- QString basePath = dataPath();
- if (!basePath.isEmpty()) {
- // This is a typo fix. We still need the old path in order to avoid breaking migration.
- QDir coookiesFolder(basePath % QLatin1String("/Coookies"));
- if (coookiesFolder.exists())
- return coookiesFolder.path();
- return basePath % QLatin1String("/Cookies");
- }
- return QString();
-}
-
-QString ProfileAdapter::channelIdPath() const
-{
- if (m_offTheRecord)
- return QString();
- QString basePath = dataPath();
- if (!basePath.isEmpty())
- return basePath % QLatin1String("/Origin Bound Certs");
- return QString();
+ if (!m_offTheRecord && !m_profile->m_profileIOData->isClearHttpCacheInProgress())
+ m_profile->m_profileIOData->resetNetworkContext();
}
QString ProfileAdapter::httpCachePath() const
@@ -296,23 +308,30 @@ QString ProfileAdapter::httpCachePath() const
QString ProfileAdapter::httpUserAgent() const
{
if (m_httpUserAgent.isNull())
- return QString::fromStdString(ContentClientQt::getUserAgent());
+ return QString::fromStdString(ContentBrowserClientQt::getUserAgent());
return m_httpUserAgent;
}
void ProfileAdapter::setHttpUserAgent(const QString &userAgent)
{
- if (m_httpUserAgent == userAgent)
+ const QString httpUserAgent = userAgent.simplified();
+ if (m_httpUserAgent == httpUserAgent)
return;
- m_httpUserAgent = userAgent.simplified();
+ m_httpUserAgent = httpUserAgent;
+ const std::string stdUserAgent = httpUserAgent.toStdString();
std::vector<content::WebContentsImpl *> list = content::WebContentsImpl::GetAllWebContents();
for (content::WebContentsImpl *web_contents : list)
- if (web_contents->GetBrowserContext() == m_profile.data())
- web_contents->SetUserAgentOverride(m_httpUserAgent.toStdString(), 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);
+ }
- if (m_profile->m_urlRequestContextGetter.get())
- m_profile->m_profileIOData->updateUserAgent();
+ m_profile->ForEachLoadedStoragePartition(
+ base::BindRepeating([](const std::string &user_agent, content::StoragePartition *storage_partition) {
+ storage_partition->GetNetworkContext()->SetUserAgent(user_agent);
+ }, stdUserAgent));
}
ProfileAdapter::HttpCacheType ProfileAdapter::httpCacheType() const
@@ -330,13 +349,14 @@ void ProfileAdapter::setHttpCacheType(ProfileAdapter::HttpCacheType newhttpCache
m_httpCacheType = newhttpCacheType;
if (oldCacheType == httpCacheType())
return;
- if (!m_offTheRecord && m_profile->m_urlRequestContextGetter.get())
- m_profile->m_profileIOData->updateHttpCache();
+ if (!m_offTheRecord && !m_profile->m_profileIOData->isClearHttpCacheInProgress()) {
+ m_profile->m_profileIOData->resetNetworkContext();
+ }
}
ProfileAdapter::PersistentCookiesPolicy ProfileAdapter::persistentCookiesPolicy() const
{
- if (isOffTheRecord() || cookiesPath().isEmpty())
+ if (isOffTheRecord() || m_name.isEmpty())
return NoPersistentCookies;
return m_persistentCookiesPolicy;
}
@@ -347,15 +367,15 @@ void ProfileAdapter::setPersistentCookiesPolicy(ProfileAdapter::PersistentCookie
m_persistentCookiesPolicy = newPersistentCookiesPolicy;
if (oldPolicy == persistentCookiesPolicy())
return;
- if (!m_offTheRecord && m_profile->m_urlRequestContextGetter.get())
- m_profile->m_profileIOData->updateCookieStore();
+ if (!m_offTheRecord && !m_profile->m_profileIOData->isClearHttpCacheInProgress())
+ m_profile->m_profileIOData->resetNetworkContext();
}
ProfileAdapter::VisitedLinksPolicy ProfileAdapter::visitedLinksPolicy() const
{
if (isOffTheRecord() || m_visitedLinksPolicy == DoNotTrackVisitedLinks)
return DoNotTrackVisitedLinks;
- if (dataPath().isEmpty())
+ if (m_name.isEmpty())
return TrackVisitedLinksInMemory;
return m_visitedLinksPolicy;
}
@@ -402,13 +422,43 @@ void ProfileAdapter::setHttpCacheMaxSize(int maxSize)
if (m_httpCacheMaxSize == maxSize)
return;
m_httpCacheMaxSize = maxSize;
- if (!m_offTheRecord && m_profile->m_urlRequestContextGetter.get())
- m_profile->m_profileIOData->updateHttpCache();
+ if (!m_offTheRecord && !m_profile->m_profileIOData->isClearHttpCacheInProgress())
+ m_profile->m_profileIOData->resetNetworkContext();
+}
+
+enum class SchemeType { Protected, Overridable, Custom, Unknown };
+static SchemeType schemeType(const QByteArray &canonicalScheme)
+{
+ static const QSet<QByteArray> blacklist{
+ QByteArrayLiteral("about"),
+ QByteArrayLiteral("blob"),
+ QByteArrayLiteral("data"),
+ QByteArrayLiteral("javascript"),
+ QByteArrayLiteral("qrc"),
+ // See also kStandardURLSchemes in url/url_util.cc (through url::IsStandard below)
+ };
+
+ static const QSet<QByteArray> whitelist{
+ QByteArrayLiteral("gopher"),
+ };
+
+ bool standardSyntax = url::IsStandard(canonicalScheme.data(), url::Component(0, canonicalScheme.size()));
+ bool customScheme = QWebEngineUrlScheme::schemeByName(canonicalScheme) != QWebEngineUrlScheme();
+ bool blacklisted = blacklist.contains(canonicalScheme);
+ bool whitelisted = whitelist.contains(canonicalScheme);
+
+ if (whitelisted)
+ return SchemeType::Overridable;
+ if (blacklisted || (standardSyntax && !customScheme))
+ return SchemeType::Protected;
+ if (customScheme)
+ return SchemeType::Custom;
+ return SchemeType::Unknown;
}
-const QHash<QByteArray, QWebEngineUrlSchemeHandler *> &ProfileAdapter::customUrlSchemeHandlers() const
+QWebEngineUrlSchemeHandler *ProfileAdapter::urlSchemeHandler(const QByteArray &scheme)
{
- return m_customUrlSchemeHandlers;
+ return m_customUrlSchemeHandlers.value(scheme.toLower()).data();
}
const QList<QByteArray> ProfileAdapter::customUrlSchemes() const
@@ -418,16 +468,23 @@ const QList<QByteArray> ProfileAdapter::customUrlSchemes() const
void ProfileAdapter::updateCustomUrlSchemeHandlers()
{
- if (m_profile->m_urlRequestContextGetter.get())
- m_profile->m_profileIOData->updateJobFactory();
+ m_profile->ForEachLoadedStoragePartition(
+ base::BindRepeating([](content::StoragePartition *storage_partition) {
+ storage_partition->ResetURLLoaderFactories();
+ }));
}
-bool ProfileAdapter::removeCustomUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler)
+void ProfileAdapter::removeUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler)
{
+ Q_ASSERT(handler);
bool removedOneOrMore = false;
auto it = m_customUrlSchemeHandlers.begin();
while (it != m_customUrlSchemeHandlers.end()) {
if (it.value() == handler) {
+ if (schemeType(it.key()) == SchemeType::Protected) {
+ qWarning("Cannot remove the URL scheme handler for an internal scheme: %s", it.key().constData());
+ continue;
+ }
it = m_customUrlSchemeHandlers.erase(it);
removedOneOrMore = true;
continue;
@@ -436,61 +493,50 @@ bool ProfileAdapter::removeCustomUrlSchemeHandler(QWebEngineUrlSchemeHandler *ha
}
if (removedOneOrMore)
updateCustomUrlSchemeHandlers();
- return removedOneOrMore;
}
-QWebEngineUrlSchemeHandler *ProfileAdapter::takeCustomUrlSchemeHandler(const QByteArray &scheme)
+void ProfileAdapter::removeUrlScheme(const QByteArray &scheme)
{
- QWebEngineUrlSchemeHandler *handler = m_customUrlSchemeHandlers.take(scheme.toLower());
- if (handler)
+ QByteArray canonicalScheme = scheme.toLower();
+ if (schemeType(canonicalScheme) == SchemeType::Protected) {
+ qWarning("Cannot remove the URL scheme handler for an internal scheme: %s", scheme.constData());
+ return;
+ }
+ if (m_customUrlSchemeHandlers.remove(canonicalScheme))
updateCustomUrlSchemeHandlers();
- return handler;
}
-bool ProfileAdapter::addCustomUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler)
+void ProfileAdapter::installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler)
{
- static const QSet<QByteArray> blacklist{
- QByteArrayLiteral("about"),
- QByteArrayLiteral("blob"),
- QByteArrayLiteral("data"),
- QByteArrayLiteral("javascript"),
- QByteArrayLiteral("qrc"),
- // See also kStandardURLSchemes in url/url_util.cc (through url::IsStandard below)
- };
-
- static const QSet<QByteArray> whitelist{
- QByteArrayLiteral("gopher"),
- };
+ Q_ASSERT(handler);
+ QByteArray canonicalScheme = scheme.toLower();
+ SchemeType type = schemeType(canonicalScheme);
- const QByteArray canonicalScheme = scheme.toLower();
- bool standardSyntax = url::IsStandard(canonicalScheme.data(), url::Component(0, canonicalScheme.size()));
- bool customScheme = QWebEngineUrlScheme::schemeByName(canonicalScheme) != QWebEngineUrlScheme();
- bool blacklisted = blacklist.contains(canonicalScheme) || (standardSyntax && !customScheme);
- bool whitelisted = whitelist.contains(canonicalScheme);
-
- if (blacklisted && !whitelisted) {
+ if (type == SchemeType::Protected) {
qWarning("Cannot install a URL scheme handler overriding internal scheme: %s", scheme.constData());
- return false;
+ return;
}
if (m_customUrlSchemeHandlers.value(canonicalScheme, handler) != handler) {
qWarning("URL scheme handler already installed for the scheme: %s", scheme.constData());
- return false;
+ return;
}
- if (!whitelisted && !customScheme)
+ if (type == SchemeType::Unknown)
qWarning("Please register the custom scheme '%s' via QWebEngineUrlScheme::registerScheme() "
"before installing the custom scheme handler.", scheme.constData());
m_customUrlSchemeHandlers.insert(canonicalScheme, handler);
updateCustomUrlSchemeHandlers();
- return true;
}
-void ProfileAdapter::clearCustomUrlSchemeHandlers()
+void ProfileAdapter::removeAllUrlSchemeHandlers()
{
- m_customUrlSchemeHandlers.clear();
- updateCustomUrlSchemeHandlers();
+ if (m_customUrlSchemeHandlers.size() > 1) {
+ m_customUrlSchemeHandlers.clear();
+ m_customUrlSchemeHandlers.insert(QByteArrayLiteral("qrc"), &m_qrcHandler);
+ updateCustomUrlSchemeHandlers();
+ }
}
UserResourceControllerHost *ProfileAdapter::userResourceController()
@@ -500,7 +546,7 @@ UserResourceControllerHost *ProfileAdapter::userResourceController()
return m_userResourceController.data();
}
-void ProfileAdapter::permissionRequestReply(const QUrl &origin, PermissionType type, bool reply)
+void ProfileAdapter::permissionRequestReply(const QUrl &origin, PermissionType type, PermissionState reply)
{
static_cast<PermissionManagerQt*>(profile()->GetPermissionControllerDelegate())->permissionRequestReply(origin, type, reply);
}
@@ -533,38 +579,143 @@ void ProfileAdapter::setHttpAcceptLanguage(const QString &httpAcceptLanguage)
return;
m_httpAcceptLanguage = httpAcceptLanguage;
+ std::string http_accept_language = httpAcceptLanguageWithoutQualities().toStdString();
+
std::vector<content::WebContentsImpl *> list = content::WebContentsImpl::GetAllWebContents();
for (content::WebContentsImpl *web_contents : list) {
if (web_contents->GetBrowserContext() == m_profile.data()) {
- content::RendererPreferences* rendererPrefs = web_contents->GetMutableRendererPrefs();
- rendererPrefs->accept_languages = httpAcceptLanguageWithoutQualities().toStdString();
- web_contents->GetRenderViewHost()->SyncRendererPrefs();
+ blink::RendererPreferences *rendererPrefs = web_contents->GetMutableRendererPrefs();
+ rendererPrefs->accept_languages = http_accept_language;
+ web_contents->SyncRendererPrefs();
}
}
- if (m_profile->m_urlRequestContextGetter.get())
- m_profile->m_profileIOData->updateUserAgent();
+ m_profile->ForEachLoadedStoragePartition(
+ base::BindRepeating([](std::string accept_language, content::StoragePartition *storage_partition) {
+ storage_partition->GetNetworkContext()->SetAcceptLanguage(accept_language);
+ }, 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()
{
- content::BrowsingDataRemover *remover = content::BrowserContext::GetBrowsingDataRemover(m_profile.data());
- remover->Remove(base::Time(), base::Time::Max(),
- content::BrowsingDataRemover::DATA_TYPE_CACHE,
- content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB | content::BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB);
+ m_profile->m_profileIOData->clearHttpCache();
}
void ProfileAdapter::setSpellCheckLanguages(const QStringList &languages)
{
#if QT_CONFIG(webengine_spellchecker)
- m_profile->setSpellCheckLanguages(languages);
+ m_profile->prefServiceAdapter().setSpellCheckLanguages(languages);
#endif
}
QStringList ProfileAdapter::spellCheckLanguages() const
{
#if QT_CONFIG(webengine_spellchecker)
- return m_profile->spellCheckLanguages();
+ return m_profile->prefServiceAdapter().spellCheckLanguages();
#else
return QStringList();
#endif
@@ -573,19 +724,29 @@ QStringList ProfileAdapter::spellCheckLanguages() const
void ProfileAdapter::setSpellCheckEnabled(bool enabled)
{
#if QT_CONFIG(webengine_spellchecker)
- m_profile->setSpellCheckEnabled(enabled);
+ m_profile->prefServiceAdapter().setSpellCheckEnabled(enabled);
#endif
}
bool ProfileAdapter::isSpellCheckEnabled() const
{
#if QT_CONFIG(webengine_spellchecker)
- return m_profile->isSpellCheckEnabled();
+ return m_profile->prefServiceAdapter().isSpellCheckEnabled();
#else
return false;
#endif
}
+bool ProfileAdapter::pushServiceEnabled() const
+{
+ return m_pushServiceEnabled;
+}
+
+void ProfileAdapter::setPushServiceEnabled(bool enabled)
+{
+ m_pushServiceEnabled = enabled;
+}
+
void ProfileAdapter::addWebContentsAdapterClient(WebContentsAdapterClient *client)
{
m_webContentsAdapterClients.append(client);
@@ -596,9 +757,161 @@ void ProfileAdapter::removeWebContentsAdapterClient(WebContentsAdapterClient *cl
m_webContentsAdapterClients.removeAll(client);
}
+void ProfileAdapter::releaseAllWebContentsAdapterClients()
+{
+ while (!m_webContentsAdapterClients.isEmpty())
+ m_webContentsAdapterClients.first()->releaseProfile();
+}
+
void ProfileAdapter::resetVisitedLinksManager()
{
- m_visitedLinksManager.reset(new VisitedLinksManagerQt(this));
+ m_visitedLinksManager.reset(new VisitedLinksManagerQt(m_profile.data(), persistVisitedLinks()));
+}
+
+void ProfileAdapter::reinitializeHistoryService()
+{
+ Q_ASSERT(!m_offTheRecord);
+ if (ensureDataPathExists()) {
+ favicon::FaviconService *faviconService =
+ FaviconServiceFactoryQt::GetForBrowserContext(m_profile.data());
+ history::HistoryService *historyService = static_cast<history::HistoryService *>(
+ HistoryServiceFactoryQt::GetInstance()->GetForBrowserContext(m_profile.data()));
+ Q_ASSERT(historyService);
+ faviconService->SetHistoryService(historyService);
+ } else {
+ qWarning("Favicon database is not available for this profile.");
+ }
+}
+
+QString ProfileAdapter::determineDownloadPath(const QString &downloadDirectory, const QString &suggestedFilename, const time_t &startTime)
+{
+ QFileInfo suggestedFile(QDir(downloadDirectory).absoluteFilePath(suggestedFilename));
+ QString suggestedFilePath = suggestedFile.absoluteFilePath();
+ base::FilePath tmpFilePath(toFilePath(suggestedFilePath).NormalizePathSeparatorsTo('/'));
+
+ int uniquifier = 0;
+ {
+ base::ScopedAllowBlocking allowBlock;
+ uniquifier = base::GetUniquePathNumber(tmpFilePath);
+ }
+ if (uniquifier > 0)
+ suggestedFilePath = toQt(tmpFilePath.InsertBeforeExtensionASCII(base::StringPrintf(" (%d)", uniquifier)).AsUTF8Unsafe());
+ else if (uniquifier == -1) {
+ base::Time::Exploded exploded;
+ base::Time::FromTimeT(startTime).LocalExplode(&exploded);
+ std::string suffix = base::StringPrintf(
+ " - %04d-%02d-%02dT%02d%02d%02d.%03d", exploded.year, exploded.month,
+ exploded.day_of_month, exploded.hour, exploded.minute,
+ exploded.second, exploded.millisecond);
+ suggestedFilePath = toQt(tmpFilePath.InsertBeforeExtensionASCII(suffix).AsUTF8Unsafe());
+ }
+ return suggestedFilePath;
+}
+
+#if QT_CONFIG(ssl)
+QWebEngineClientCertificateStore *ProfileAdapter::clientCertificateStore()
+{
+ if (!m_clientCertificateStore)
+ m_clientCertificateStore = new QWebEngineClientCertificateStore(m_profile->m_profileIOData->clientCertificateStoreData());
+ return m_clientCertificateStore;
+}
+#endif
+
+static void callbackOnIconAvailableForPageURL(std::function<void (const QIcon &, const QUrl &, const QUrl &)> iconAvailableCallback,
+ const QUrl &pageUrl,
+ const favicon_base::FaviconRawBitmapResult &result)
+{
+ if (!result.is_valid()) {
+ iconAvailableCallback(QIcon(), toQt(result.icon_url), pageUrl);
+ return;
+ }
+ QPixmap pixmap(toQt(result.pixel_size));
+ pixmap.loadFromData(result.bitmap_data->data(), result.bitmap_data->size());
+ iconAvailableCallback(QIcon(pixmap), toQt(result.icon_url), pageUrl);
+}
+
+void ProfileAdapter::requestIconForPageURL(const QUrl &pageUrl,
+ int desiredSizeInPixel,
+ bool touchIconsEnabled,
+ std::function<void (const QIcon &, const QUrl &, const QUrl &)> iconAvailableCallback)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ favicon::FaviconService *service = FaviconServiceFactoryQt::GetForBrowserContext(m_profile.data());
+
+ if (!service->HistoryService()) {
+ callbackOnIconAvailableForPageURL(iconAvailableCallback, pageUrl,
+ favicon_base::FaviconRawBitmapResult());
+ return;
+ }
+
+ favicon_base::IconTypeSet types = { favicon_base::IconType::kFavicon };
+ if (touchIconsEnabled) {
+ types.insert(favicon_base::IconType::kTouchIcon);
+ types.insert(favicon_base::IconType::kTouchPrecomposedIcon);
+ types.insert(favicon_base::IconType::kWebManifestIcon);
+ }
+ service->GetRawFaviconForPageURL(
+ toGurl(pageUrl), types, desiredSizeInPixel, true /* fallback_to_host */,
+ base::BindOnce(&callbackOnIconAvailableForPageURL, iconAvailableCallback, pageUrl),
+ m_cancelableTaskTracker.get());
+}
+
+static void callbackOnIconAvailableForIconURL(std::function<void (const QIcon &, const QUrl &)> iconAvailableCallback,
+ ProfileAdapter *profileAdapter,
+ const QUrl &iconUrl, int iconType,
+ int desiredSizeInPixel,
+ bool touchIconsEnabled,
+ const favicon_base::FaviconRawBitmapResult &result)
+{
+ if (!result.is_valid()) {
+ // If touch icons are disabled there is no need to try further icon types.
+ if (!touchIconsEnabled) {
+ iconAvailableCallback(QIcon(), iconUrl);
+ return;
+ }
+ if (static_cast<favicon_base::IconType>(iconType) != favicon_base::IconType::kMax) {
+ //Q_ASSERT(profileAdapter->profile());
+ favicon::FaviconService *service = FaviconServiceFactoryQt::GetForBrowserContext(profileAdapter->profile());
+ service->GetRawFavicon(toGurl(iconUrl),
+ static_cast<favicon_base::IconType>(iconType + 1),
+ desiredSizeInPixel,
+ base::BindOnce(&callbackOnIconAvailableForIconURL, iconAvailableCallback,
+ profileAdapter, iconUrl, iconType + 1, desiredSizeInPixel,
+ touchIconsEnabled),
+ profileAdapter->cancelableTaskTracker());
+ return;
+ }
+ iconAvailableCallback(QIcon(), iconUrl);
+ return;
+ }
+ QPixmap pixmap(toQt(result.pixel_size));
+ pixmap.loadFromData(result.bitmap_data->data(), result.bitmap_data->size());
+ iconAvailableCallback(QIcon(pixmap), toQt(result.icon_url));
+}
+
+void ProfileAdapter::requestIconForIconURL(const QUrl &iconUrl,
+ int desiredSizeInPixel,
+ bool touchIconsEnabled,
+ std::function<void (const QIcon &, const QUrl &)> iconAvailableCallback)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ favicon::FaviconService *service = FaviconServiceFactoryQt::GetForBrowserContext(m_profile.data());
+
+ if (!service->HistoryService()) {
+ callbackOnIconAvailableForIconURL(iconAvailableCallback,
+ this,
+ iconUrl,
+ static_cast<int>(favicon_base::IconType::kMax), 0,
+ touchIconsEnabled,
+ favicon_base::FaviconRawBitmapResult());
+ return;
+ }
+ service->GetRawFavicon(
+ toGurl(iconUrl), favicon_base::IconType::kFavicon, desiredSizeInPixel,
+ base::BindOnce(&callbackOnIconAvailableForIconURL, iconAvailableCallback, this, iconUrl,
+ static_cast<int>(favicon_base::IconType::kFavicon), desiredSizeInPixel,
+ touchIconsEnabled),
+ m_cancelableTaskTracker.get());
}
} // namespace QtWebEngineCore