summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/api/qwebengineurlrequestinfo.cpp10
-rw-r--r--src/core/api/qwebengineurlrequestinterceptor.h2
-rw-r--r--src/core/command_line_pref_store_qt.cpp90
-rw-r--r--src/core/command_line_pref_store_qt.h56
-rw-r--r--src/core/content_browser_client_qt.cpp12
-rw-r--r--src/core/content_browser_client_qt.h1
-rw-r--r--src/core/core_chromium.pri4
-rw-r--r--src/core/net/network_delegate_qt.cpp185
-rw-r--r--src/core/net/proxy_config_service_qt.cpp14
-rw-r--r--src/core/net/proxy_config_service_qt.h10
-rw-r--r--src/core/net/url_request_notification.cpp187
-rw-r--r--src/core/net/url_request_notification.h85
-rw-r--r--src/core/permission_manager_qt.cpp49
-rw-r--r--src/core/profile_adapter.h2
-rw-r--r--src/core/profile_io_data_qt.cpp18
-rw-r--r--src/core/profile_io_data_qt.h2
-rw-r--r--src/core/profile_qt.cpp7
-rw-r--r--src/core/qtwebengine.gni1
-rw-r--r--src/core/web_engine_context.cpp56
-rw-r--r--src/core/web_engine_context.h2
-rw-r--r--src/webengine/api/qquickwebengineprofile.cpp27
-rw-r--r--src/webengine/api/qquickwebengineprofile.h3
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp2
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h4
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp28
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.h3
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp23
-rw-r--r--tests/auto/quick/qquickwebengineview/BLACKLIST4
-rw-r--r--tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp40
-rw-r--r--tests/auto/widgets/proxypac/proxypac.pro24
-rw-r--r--tests/auto/widgets/qwebengineview/BLACKLIST3
-rw-r--r--tests/auto/widgets/widgets.pro6
32 files changed, 707 insertions, 253 deletions
diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp
index c3e5b5445..dc2d07740 100644
--- a/src/core/api/qwebengineurlrequestinfo.cpp
+++ b/src/core/api/qwebengineurlrequestinfo.cpp
@@ -96,8 +96,8 @@ ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::OtherNavigation, Q
interceptor on the profile enables intercepting, blocking, and modifying URL requests
before they reach the networking stack of Chromium.
- You can install the interceptor on a profile via QWebEngineProfile::setRequestInterceptor()
- or QQuickWebEngineProfile::setRequestInterceptor().
+ You can install the interceptor on a profile via QWebEngineProfile::setUrlRequestInterceptor()
+ or QQuickWebEngineProfile::setUrlRequestInterceptor().
When using the \l{Qt WebEngine Widgets Module}, \l{QWebEnginePage::acceptNavigationRequest()}
offers further options to accept or block requests.
@@ -115,11 +115,7 @@ ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::OtherNavigation, Q
\fn void QWebEngineUrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info)
Reimplementing this virtual function makes it possible to intercept URL
- requests. For interceptors installed on a QWebEngineProfile, the function is executed
- on the I/O thread, and thus it may not be thread-safe to interact with pages. If the
- interceptor was installed on a QWebEnginePage, the function is executed on the main
- application thread, and can safely interact with other user classes. Both versions will
- be stalling the URL request until handled.
+ requests. This method will be stalling the URL request until handled.
\a info contains the information about the URL request and will track internally
whether its members have been altered.
diff --git a/src/core/api/qwebengineurlrequestinterceptor.h b/src/core/api/qwebengineurlrequestinterceptor.h
index dc2a15ee3..2b07681ca 100644
--- a/src/core/api/qwebengineurlrequestinterceptor.h
+++ b/src/core/api/qwebengineurlrequestinterceptor.h
@@ -55,7 +55,7 @@ class QWEBENGINECORE_EXPORT QWebEngineUrlRequestInterceptor : public QObject
Q_OBJECT
Q_DISABLE_COPY(QWebEngineUrlRequestInterceptor)
public:
- explicit QWebEngineUrlRequestInterceptor(QObject *p = Q_NULLPTR)
+ explicit QWebEngineUrlRequestInterceptor(QObject *p = nullptr)
: QObject (p)
{
}
diff --git a/src/core/command_line_pref_store_qt.cpp b/src/core/command_line_pref_store_qt.cpp
new file mode 100644
index 000000000..5c5c82e1a
--- /dev/null
+++ b/src/core/command_line_pref_store_qt.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "command_line_pref_store_qt.h"
+
+#include "chrome/common/chrome_switches.h"
+#include "components/proxy_config/proxy_config_dictionary.h"
+#include "components/proxy_config/proxy_config_pref_names.h"
+#include "content/public/common/content_switches.h"
+#include <QDebug>
+
+CommandLinePrefStoreQt::CommandLinePrefStoreQt(const base::CommandLine *commandLine)
+ : CommandLinePrefStore(commandLine)
+{
+
+ if (commandLine->HasSwitch(switches::kNoProxyServer)) {
+ SetValue(proxy_config::prefs::kProxy,
+ std::make_unique<base::Value>(ProxyConfigDictionary::CreateDirect()),
+ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+ } else if (commandLine->HasSwitch(switches::kProxyPacUrl)) {
+ std::string pac_script_url =
+ commandLine->GetSwitchValueASCII(switches::kProxyPacUrl);
+ SetValue(proxy_config::prefs::kProxy,
+ std::make_unique<base::Value>(ProxyConfigDictionary::CreatePacScript(
+ pac_script_url, false)),
+ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+ } else if (commandLine->HasSwitch(switches::kProxyAutoDetect)) {
+ SetValue(proxy_config::prefs::kProxy,
+ std::make_unique<base::Value>(
+ ProxyConfigDictionary::CreateAutoDetect()),
+ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+ } else if (commandLine->HasSwitch(switches::kProxyServer)) {
+ std::string proxy_server =
+ commandLine->GetSwitchValueASCII(switches::kProxyServer);
+ std::string bypass_list =
+ commandLine->GetSwitchValueASCII(switches::kProxyBypassList);
+ SetValue(
+ proxy_config::prefs::kProxy,
+ std::make_unique<base::Value>(ProxyConfigDictionary::CreateFixedServers(
+ proxy_server, bypass_list)),
+ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+ }
+
+ if (commandLine->HasSwitch(switches::kNoProxyServer) && (commandLine->HasSwitch(switches::kProxyAutoDetect) || commandLine->HasSwitch(switches::kProxyServer) || commandLine->HasSwitch(switches::kProxyPacUrl) || commandLine->HasSwitch(switches::kProxyBypassList))) {
+ qWarning("Additional command-line proxy switches specified when --%s was also specified",
+ qPrintable(switches::kNoProxyServer));
+ }
+}
+
+CommandLinePrefStoreQt::~CommandLinePrefStoreQt() = default;
diff --git a/src/core/command_line_pref_store_qt.h b/src/core/command_line_pref_store_qt.h
new file mode 100644
index 000000000..a509f8ca9
--- /dev/null
+++ b/src/core/command_line_pref_store_qt.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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$
+**
+****************************************************************************/
+
+#ifndef COMMAND_LINE_PREF_STORE_QT_H
+#define COMMAND_LINE_PREF_STORE_QT_H
+
+#include "base/command_line.h"
+#include "components/prefs/command_line_pref_store.h"
+
+class CommandLinePrefStoreQt : public CommandLinePrefStore
+{
+public:
+ explicit CommandLinePrefStoreQt(const base::CommandLine *commandLine);
+
+protected:
+ ~CommandLinePrefStoreQt() override;
+ DISALLOW_COPY_AND_ASSIGN(CommandLinePrefStoreQt);
+};
+
+#endif // COMMAND_LINE_PREF_STORE_QT_H
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index 846f3b908..3861d1c95 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -760,13 +760,19 @@ scoped_refptr<content::LoginDelegate> ContentBrowserClientQt::CreateLoginDelegat
return loginDelegate;
}
+bool ContentBrowserClientQt::ShouldIsolateErrorPage(bool in_main_frame)
+{
+ Q_UNUSED(in_main_frame);
+ return false;
+}
+
bool ContentBrowserClientQt::ShouldUseProcessPerSite(content::BrowserContext* browser_context, const GURL& effective_url)
{
#if BUILDFLAG(ENABLE_EXTENSIONS)
- return true;
-#else
- return ContentBrowserClient::ShouldUseProcessPerSite(browser_context, effective_url);
+ if (effective_url.SchemeIs(extensions::kExtensionScheme))
+ return true;
#endif
+ return ContentBrowserClient::ShouldUseProcessPerSite(browser_context, effective_url);
}
} // namespace QtWebEngineCore
diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h
index e90b687cc..fc938f882 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -175,6 +175,7 @@ public:
#if QT_CONFIG(webengine_geolocation)
std::unique_ptr<device::LocationProvider> OverrideSystemLocationProvider() override;
#endif
+ bool ShouldIsolateErrorPage(bool in_main_frame) override;
bool ShouldUseProcessPerSite(content::BrowserContext* browser_context, const GURL& effective_url) override;
#if defined(Q_OS_LINUX)
diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri
index 18cedc63e..edf6806a3 100644
--- a/src/core/core_chromium.pri
+++ b/src/core/core_chromium.pri
@@ -53,6 +53,7 @@ SOURCES = \
clipboard_qt.cpp \
color_chooser_qt.cpp \
color_chooser_controller.cpp \
+ command_line_pref_store_qt.cpp \
common/qt_ipc_logging.cpp \
common/qt_messages.cpp \
common/user_script_data.cpp \
@@ -86,6 +87,7 @@ SOURCES = \
net/url_request_custom_job.cpp \
net/url_request_custom_job_delegate.cpp \
net/url_request_custom_job_proxy.cpp \
+ net/url_request_notification.cpp \
net/webui_controller_factory_qt.cpp \
ozone/gl_context_qt.cpp \
ozone/gl_ozone_egl_qt.cpp \
@@ -150,6 +152,7 @@ HEADERS = \
client_cert_override_p.h \
client_cert_select_controller.h \
clipboard_qt.h \
+ command_line_pref_store_qt.h \
color_chooser_qt.h \
color_chooser_controller_p.h \
color_chooser_controller.h \
@@ -187,6 +190,7 @@ HEADERS = \
net/url_request_custom_job.h \
net/url_request_custom_job_delegate.h \
net/url_request_custom_job_proxy.h \
+ net/url_request_notification.h \
net/webui_controller_factory_qt.h \
ozone/gl_context_qt.h \
ozone/gl_ozone_egl_qt.h \
diff --git a/src/core/net/network_delegate_qt.cpp b/src/core/net/network_delegate_qt.cpp
index 73f3ff818..3641cb845 100644
--- a/src/core/net/network_delegate_qt.cpp
+++ b/src/core/net/network_delegate_qt.cpp
@@ -58,6 +58,7 @@
#include "type_conversion.h"
#include "web_contents_adapter_client.h"
#include "web_contents_view_qt.h"
+#include "url_request_notification.h"
namespace QtWebEngineCore {
@@ -91,146 +92,11 @@ static QWebEngineUrlRequestInfo::ResourceType toQt(content::ResourceType resourc
return QWebEngineUrlRequestInfo::ResourceTypeUnknown;
}
-static content::ResourceType fromQt(QWebEngineUrlRequestInfo::ResourceType resourceType)
-{
- return static_cast<content::ResourceType>(resourceType);
-}
-
static QWebEngineUrlRequestInfo::NavigationType toQt(WebContentsAdapterClient::NavigationType navigationType)
{
return static_cast<QWebEngineUrlRequestInfo::NavigationType>(navigationType);
}
-// Notifies WebContentsAdapterClient of a new URLRequest.
-class URLRequestNotification {
-public:
- URLRequestNotification(net::URLRequest *request,
- bool isMainFrameRequest,
- GURL *newUrl,
- QWebEngineUrlRequestInfo &&requestInfo,
- content::ResourceRequestInfo::WebContentsGetter webContentsGetter,
- net::CompletionOnceCallback callback)
- : m_request(request)
- , m_isMainFrameRequest(isMainFrameRequest)
- , m_newUrl(newUrl)
- , m_originalUrl(requestInfo.requestUrl())
- , m_requestInfo(std::move(requestInfo))
- , m_webContentsGetter(webContentsGetter)
- , m_callback(std::move(callback))
- {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- m_request->SetUserData(UserData::key, std::make_unique<UserData>(this));
-
- base::PostTaskWithTraits(
- FROM_HERE,
- {content::BrowserThread::UI},
- base::BindOnce(&URLRequestNotification::notify, base::Unretained(this)));
- }
-
-private:
- // Calls cancel() when the URLRequest is destroyed.
- class UserData : public base::SupportsUserData::Data {
- public:
- UserData(URLRequestNotification *ptr) : m_ptr(ptr) {}
- ~UserData() { m_ptr->cancel(); }
- static const char key[];
- private:
- URLRequestNotification *m_ptr;
- };
-
- void cancel()
- {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- // May run concurrently with notify() but we only touch m_request here.
-
- m_request = nullptr;
- }
-
- void notify()
- {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
- // May run concurrently with cancel() so no peeking at m_request here.
-
- int error = net::OK;
- content::WebContents *webContents = m_webContentsGetter.Run();
-
- if (webContents) {
- WebContentsAdapterClient *client =
- WebContentsViewQt::from(static_cast<content::WebContentsImpl*>(webContents)->GetView())->client();
-
- client->interceptRequest(m_requestInfo);
- if (m_requestInfo.changed()) {
- error = m_requestInfo.d_ptr->shouldBlockRequest ? net::ERR_BLOCKED_BY_CLIENT : net::OK;
- // We handle the rest of the changes later when we are back in I/O thread
- }
-
- // Only do navigationRequested on MAIN_FRAME and SUB_FRAME resources
- if (error == net::OK && content::IsResourceTypeFrame(fromQt(m_requestInfo.resourceType()))) {
- int navigationRequestAction = WebContentsAdapterClient::AcceptRequest;
- client->navigationRequested(m_requestInfo.navigationType(),
- m_requestInfo.requestUrl(),
- navigationRequestAction,
- m_isMainFrameRequest);
- error = net::ERR_FAILED;
- switch (static_cast<WebContentsAdapterClient::NavigationRequestAction>(navigationRequestAction)) {
- case WebContentsAdapterClient::AcceptRequest:
- error = net::OK;
- break;
- case WebContentsAdapterClient::IgnoreRequest:
- error = net::ERR_ABORTED;
- break;
- }
- DCHECK(error != net::ERR_FAILED);
- }
- }
-
- // Run the callback on the IO thread.
- base::PostTaskWithTraits(
- FROM_HERE,
- {content::BrowserThread::IO},
- base::BindOnce(&URLRequestNotification::complete, base::Unretained(this), error));
- }
-
- void complete(int error)
- {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- if (m_request) {
- if (m_requestInfo.changed()) {
- if (m_originalUrl != m_requestInfo.d_ptr->url)
- *m_newUrl = toGurl(m_requestInfo.d_ptr->url);
-
- if (!m_requestInfo.d_ptr->extraHeaders.isEmpty()) {
- auto end = m_requestInfo.d_ptr->extraHeaders.constEnd();
- for (auto header = m_requestInfo.d_ptr->extraHeaders.constBegin(); header != end; ++header)
- m_request->SetExtraRequestHeaderByName(header.key().toStdString(), header.value().toStdString(), /* overwrite */ true);
- }
- }
-
- if (m_request->status().status() != net::URLRequestStatus::CANCELED)
- std::move(m_callback).Run(error);
- m_request->RemoveUserData(UserData::key);
- }
-
- delete this;
- }
-
- ~URLRequestNotification() {}
-
- net::URLRequest *m_request;
- bool m_isMainFrameRequest;
- GURL *m_newUrl;
- const QUrl m_originalUrl;
- QWebEngineUrlRequestInfo m_requestInfo;
- content::ResourceRequestInfo::WebContentsGetter m_webContentsGetter;
- net::CompletionOnceCallback m_callback;
-};
-
-const char URLRequestNotification::UserData::key[] = "QtWebEngineCore::URLRequestNotification";
-
NetworkDelegateQt::NetworkDelegateQt(ProfileIODataQt *data)
: m_profileIOData(data)
{
@@ -265,33 +131,41 @@ int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, net::Complet
QByteArray::fromStdString(request->method()));
QWebEngineUrlRequestInfo requestInfo(infoPrivate);
- if (QWebEngineUrlRequestInterceptor* interceptor = m_profileIOData->acquireInterceptor()) {
- interceptor->interceptRequest(requestInfo);
- m_profileIOData->releaseInterceptor();
- if (requestInfo.changed()) {
- int result = infoPrivate->shouldBlockRequest ? net::ERR_BLOCKED_BY_CLIENT : net::OK;
+ // Deprecated =begin
+ // quick peek if deprecated
+ QWebEngineUrlRequestInterceptor* profileInterceptor = m_profileIOData->requestInterceptor();
+ if (profileInterceptor && profileInterceptor->property("deprecated").toBool()) {
+ profileInterceptor = nullptr;
+ if (QWebEngineUrlRequestInterceptor* interceptor = m_profileIOData->acquireInterceptor()) {
+ interceptor->interceptRequest(requestInfo);
+ m_profileIOData->releaseInterceptor();
+ if (requestInfo.changed()) {
+ int result = infoPrivate->shouldBlockRequest ? net::ERR_BLOCKED_BY_CLIENT : net::OK;
+
+ if (qUrl != infoPrivate->url)
+ *newUrl = toGurl(infoPrivate->url);
+
+ if (!infoPrivate->extraHeaders.isEmpty()) {
+ auto end = infoPrivate->extraHeaders.constEnd();
+ for (auto header = infoPrivate->extraHeaders.constBegin(); header != end; ++header)
+ request->SetExtraRequestHeaderByName(header.key().toStdString(), header.value().toStdString(), /* overwrite */ true);
+ }
- if (qUrl != infoPrivate->url)
- *newUrl = toGurl(infoPrivate->url);
+ if (result != net::OK)
+ return result;
- if (!infoPrivate->extraHeaders.isEmpty()) {
- auto end = infoPrivate->extraHeaders.constEnd();
- for (auto header = infoPrivate->extraHeaders.constBegin(); header != end; ++header)
- request->SetExtraRequestHeaderByName(header.key().toStdString(), header.value().toStdString(), /* overwrite */ true);
+ requestInfo.resetChanged();
}
-
- if (result != net::OK)
- return result;
-
- requestInfo.resetChanged();
+ } else {
+ m_profileIOData->releaseInterceptor();
}
- } else
- m_profileIOData->releaseInterceptor();
+ }
+ // Deprecated =cut
if (!resourceInfo)
return net::OK;
- if (!m_profileIOData->hasPageInterceptors() && !content::IsResourceTypeFrame(resourceType))
+ if (!m_profileIOData->hasPageInterceptors() && !profileInterceptor && !content::IsResourceTypeFrame(resourceType))
return net::OK;
auto webContentsGetter = resourceInfo->GetWebContentsGetterForRequest();
@@ -301,7 +175,8 @@ int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, net::Complet
newUrl,
std::move(requestInfo),
webContentsGetter,
- std::move(callback)
+ std::move(callback),
+ profileInterceptor ? m_profileIOData->profileAdapter() : nullptr
);
// We'll run the callback after we notified the UI thread.
diff --git a/src/core/net/proxy_config_service_qt.cpp b/src/core/net/proxy_config_service_qt.cpp
index 13b969281..ff8ab20aa 100644
--- a/src/core/net/proxy_config_service_qt.cpp
+++ b/src/core/net/proxy_config_service_qt.cpp
@@ -47,6 +47,7 @@
#include "base/bind.h"
#include "content/public/browser/browser_thread.h"
+#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
using content::BrowserThread;
@@ -68,10 +69,13 @@ net::ProxyServer ProxyConfigServiceQt::fromQNetworkProxy(const QNetworkProxy &qt
}
}
-ProxyConfigServiceQt::ProxyConfigServiceQt(std::unique_ptr<ProxyConfigService> baseService)
+ProxyConfigServiceQt::ProxyConfigServiceQt(std::unique_ptr<ProxyConfigService> baseService,
+ const net::ProxyConfigWithAnnotation& initialConfig, ProxyPrefs::ConfigState initialState)
: m_baseService(baseService.release()),
m_usesSystemConfiguration(false),
- m_registeredObserver(false)
+ m_registeredObserver(false),
+ m_prefConfig(initialConfig),
+ m_perfState(initialState)
{
}
@@ -100,8 +104,10 @@ net::ProxyConfigService::ConfigAvailability ProxyConfigServiceQt::GetLatestProxy
ConfigAvailability systemAvailability = net::ProxyConfigService::CONFIG_UNSET;
if (m_baseService.get())
systemAvailability = m_baseService->GetLatestProxyConfig(&systemConfig);
- *config = systemConfig;
- // make sure to get updates via OnProxyConfigChanged
+ ProxyPrefs::ConfigState configState;
+ systemAvailability = PrefProxyConfigTrackerImpl::GetEffectiveProxyConfig(
+ m_perfState, m_prefConfig, systemAvailability, systemConfig,
+ false, &configState, config);
RegisterObserver();
return systemAvailability;
}
diff --git a/src/core/net/proxy_config_service_qt.h b/src/core/net/proxy_config_service_qt.h
index 961927b89..09e88d445 100644
--- a/src/core/net/proxy_config_service_qt.h
+++ b/src/core/net/proxy_config_service_qt.h
@@ -43,8 +43,10 @@
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
+#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_service.h"
#include "net/proxy_resolution/proxy_config_with_annotation.h"
+#include "components/proxy_config/proxy_prefs.h"
#include <QNetworkProxy>
@@ -55,7 +57,9 @@ public:
static net::ProxyServer fromQNetworkProxy(const QNetworkProxy &);
- explicit ProxyConfigServiceQt(std::unique_ptr<ProxyConfigService> baseService);
+ explicit ProxyConfigServiceQt(std::unique_ptr<ProxyConfigService> baseService,
+ const net::ProxyConfigWithAnnotation& initialConfig,
+ ProxyPrefs::ConfigState initialState);
~ProxyConfigServiceQt() override;
// ProxyConfigService implementation:
@@ -86,6 +90,10 @@ private:
// Indicates whether the base service registration is done.
bool m_registeredObserver;
+ // Configuration as defined by prefs.
+ net::ProxyConfigWithAnnotation m_prefConfig;
+ ProxyPrefs::ConfigState m_perfState;
+
DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceQt);
};
diff --git a/src/core/net/url_request_notification.cpp b/src/core/net/url_request_notification.cpp
new file mode 100644
index 000000000..6da661cff
--- /dev/null
+++ b/src/core/net/url_request_notification.cpp
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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$
+**
+****************************************************************************/
+
+#include "url_request_notification.h"
+
+#include "base/supports_user_data.h"
+#include "base/task/post_task.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_thread.h"
+#include "net/url_request/url_request.h"
+#include "web_contents_adapter_client.h"
+#include "web_contents_view_qt.h"
+#include "profile_io_data_qt.h"
+#include "qwebengineurlrequestinfo_p.h"
+#include "type_conversion.h"
+
+namespace QtWebEngineCore {
+
+// Calls cancel() when the URLRequest is destroyed.
+class UserData : public base::SupportsUserData::Data {
+public:
+ UserData(URLRequestNotification *ptr) : m_ptr(ptr) {}
+ ~UserData() { m_ptr->cancel(); }
+ static const char key[];
+private:
+ URLRequestNotification *m_ptr;
+};
+
+const char UserData::key[] = "QtWebEngineCore::URLRequestNotification";
+
+static content::ResourceType fromQt(QWebEngineUrlRequestInfo::ResourceType resourceType)
+{
+ return static_cast<content::ResourceType>(resourceType);
+}
+
+URLRequestNotification::URLRequestNotification(net::URLRequest *request,
+ bool isMainFrameRequest,
+ GURL *newUrl,
+ QWebEngineUrlRequestInfo &&requestInfo,
+ content::ResourceRequestInfo::WebContentsGetter webContentsGetter,
+ net::CompletionOnceCallback callback,
+ QPointer<ProfileAdapter> adapter)
+ : m_request(request)
+ , m_isMainFrameRequest(isMainFrameRequest)
+ , m_newUrl(newUrl)
+ , m_originalUrl(requestInfo.requestUrl())
+ , m_requestInfo(std::move(requestInfo))
+ , m_webContentsGetter(webContentsGetter)
+ , m_callback(std::move(callback))
+ , m_profileAdapter(adapter)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ m_request->SetUserData(UserData::key, std::make_unique<UserData>(this));
+
+ base::PostTaskWithTraits(
+ FROM_HERE,
+ {content::BrowserThread::UI},
+ base::BindOnce(&URLRequestNotification::notify, base::Unretained(this)));
+}
+
+
+void URLRequestNotification::notify()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ // May run concurrently with cancel() so no peeking at m_request here.
+
+ int result = net::OK;
+ content::WebContents *webContents = m_webContentsGetter.Run();
+
+ if (webContents) {
+
+ if (m_profileAdapter) {
+ QWebEngineUrlRequestInterceptor* interceptor = m_profileAdapter->requestInterceptor();
+ interceptor->interceptRequest(m_requestInfo);
+ }
+
+ WebContentsAdapterClient *client =
+ WebContentsViewQt::from(static_cast<content::WebContentsImpl*>(webContents)->GetView())->client();
+
+ if (!m_requestInfo.changed()) {
+ client->interceptRequest(m_requestInfo);
+ }
+
+ if (m_requestInfo.changed()) {
+ result = m_requestInfo.d_ptr->shouldBlockRequest ? net::ERR_BLOCKED_BY_CLIENT : net::OK;
+ // We handle the rest of the changes later when we are back in I/O thread
+ }
+
+ // Only do navigationRequested on MAIN_FRAME and SUB_FRAME resources
+ if (result == net::OK && content::IsResourceTypeFrame(fromQt(m_requestInfo.resourceType()))) {
+ int navigationRequestAction = WebContentsAdapterClient::AcceptRequest;
+ client->navigationRequested(m_requestInfo.navigationType(),
+ m_requestInfo.requestUrl(),
+ navigationRequestAction,
+ m_isMainFrameRequest);
+ result = net::ERR_FAILED;
+ switch (static_cast<WebContentsAdapterClient::NavigationRequestAction>(navigationRequestAction)) {
+ case WebContentsAdapterClient::AcceptRequest:
+ result = net::OK;
+ break;
+ case WebContentsAdapterClient::IgnoreRequest:
+ result = net::ERR_ABORTED;
+ break;
+ }
+ DCHECK(result != net::ERR_FAILED);
+ }
+ }
+
+ // Run the callback on the IO thread.
+ base::PostTaskWithTraits(
+ FROM_HERE,
+ {content::BrowserThread::IO},
+ base::BindOnce(&URLRequestNotification::complete, base::Unretained(this), result));
+}
+
+void URLRequestNotification::cancel()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ // May run concurrently with notify() but we only touch m_request here.
+
+ m_request = nullptr;
+}
+
+void URLRequestNotification::complete(int error)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ if (m_request) {
+ if (m_requestInfo.changed()) {
+ if (m_originalUrl != m_requestInfo.d_ptr->url)
+ *m_newUrl = toGurl(m_requestInfo.d_ptr->url);
+
+ if (!m_requestInfo.d_ptr->extraHeaders.isEmpty()) {
+ auto end = m_requestInfo.d_ptr->extraHeaders.constEnd();
+ for (auto header = m_requestInfo.d_ptr->extraHeaders.constBegin(); header != end; ++header)
+ m_request->SetExtraRequestHeaderByName(header.key().toStdString(), header.value().toStdString(), /* overwrite */ true);
+ }
+ }
+
+ if (m_request->status().status() != net::URLRequestStatus::CANCELED)
+ std::move(m_callback).Run(error);
+ m_request->RemoveUserData(UserData::key);
+ }
+
+ delete this;
+}
+
+}
diff --git a/src/core/net/url_request_notification.h b/src/core/net/url_request_notification.h
new file mode 100644
index 000000000..1d9acf12f
--- /dev/null
+++ b/src/core/net/url_request_notification.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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$
+**
+****************************************************************************/
+
+#ifndef URL_REQUEST_NOTIFIACTION_H
+#define URL_REQUEST_NOTIFIACTION_H
+
+#include "content/public/browser/resource_request_info.h"
+#include "net/base/completion_once_callback.h"
+#include "qwebengineurlrequestinfo.h"
+#include <QPointer>
+
+class GURL;
+
+namespace net {
+class URLRequest;
+}
+
+namespace QtWebEngineCore {
+
+class ProfileAdapter;
+class ProfileIoDataQt;
+
+// Notifies WebContentsAdapterClient of a new URLRequest.
+class URLRequestNotification {
+public:
+ URLRequestNotification(net::URLRequest *request,
+ bool isMainFrameRequest,
+ GURL *newUrl,
+ QWebEngineUrlRequestInfo &&requestInfo,
+ content::ResourceRequestInfo::WebContentsGetter webContentsGetter,
+ net::CompletionOnceCallback callback,
+ QPointer<ProfileAdapter> adapter);
+ ~URLRequestNotification() = default;
+ void cancel();
+ void notify();
+ void complete(int error);
+
+private:
+ net::URLRequest *m_request; //used only by io thread
+ bool m_isMainFrameRequest;
+ GURL *m_newUrl;
+ const QUrl m_originalUrl;
+ QWebEngineUrlRequestInfo m_requestInfo;
+ content::ResourceRequestInfo::WebContentsGetter m_webContentsGetter;
+ net::CompletionOnceCallback m_callback;
+ QPointer<ProfileAdapter> m_profileAdapter;
+};
+}
+#endif
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index b6d055e27..cf3041e7a 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -48,6 +48,7 @@
#include "type_conversion.h"
#include "web_contents_delegate_qt.h"
+#include "web_engine_settings.h"
namespace QtWebEngineCore {
@@ -69,8 +70,11 @@ ProfileAdapter::PermissionType toQt(content::PermissionType type)
case content::PermissionType::BACKGROUND_SYNC:
case content::PermissionType::SENSORS:
case content::PermissionType::ACCESSIBILITY_EVENTS:
+ break;
case content::PermissionType::CLIPBOARD_READ:
+ return ProfileAdapter::ClipboardRead;
case content::PermissionType::CLIPBOARD_WRITE:
+ return ProfileAdapter::ClipboardWrite;
case content::PermissionType::PAYMENT_HANDLER:
case content::PermissionType::BACKGROUND_FETCH:
case content::PermissionType::NUM:
@@ -154,19 +158,28 @@ int PermissionManagerQt::RequestPermission(content::PermissionType permission,
bool /*user_gesture*/,
const base::Callback<void(blink::mojom::PermissionStatus)>& callback)
{
- int request_id = ++m_requestIdCount;
+ WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt *>(
+ content::WebContents::FromRenderFrameHost(frameHost)->GetDelegate());
+ Q_ASSERT(contentsDelegate);
+
ProfileAdapter::PermissionType permissionType = toQt(permission);
if (permissionType == ProfileAdapter::UnsupportedPermission) {
callback.Run(blink::mojom::PermissionStatus::DENIED);
return content::PermissionController::kNoPendingOperation;
+ } else if (permissionType == ProfileAdapter::ClipboardRead) {
+ WebEngineSettings *settings = contentsDelegate->webEngineSettings();
+ if (settings->testAttribute(WebEngineSettings::JavascriptCanAccessClipboard)
+ && settings->testAttribute(WebEngineSettings::JavascriptCanPaste))
+ callback.Run(blink::mojom::PermissionStatus::GRANTED);
+ else
+ callback.Run(blink::mojom::PermissionStatus::DENIED);
+ return content::PermissionController::kNoPendingOperation;
}
// Audio and video-capture should not come this way currently
Q_ASSERT(permissionType != ProfileAdapter::AudioCapturePermission
&& permissionType != ProfileAdapter::VideoCapturePermission);
- content::WebContents *webContents = frameHost->GetRenderViewHost()->GetDelegate()->GetAsWebContents();
- WebContentsDelegateQt* contentsDelegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
- Q_ASSERT(contentsDelegate);
+ int request_id = ++m_requestIdCount;
RequestOrSubscription request = {
permissionType,
toQt(requesting_origin),
@@ -184,6 +197,10 @@ int PermissionManagerQt::RequestPermissions(const std::vector<content::Permissio
bool /*user_gesture*/,
const base::Callback<void(const std::vector<blink::mojom::PermissionStatus>&)>& callback)
{
+ WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt *>(
+ content::WebContents::FromRenderFrameHost(frameHost)->GetDelegate());
+ Q_ASSERT(contentsDelegate);
+
bool answerable = true;
std::vector<blink::mojom::PermissionStatus> result;
result.reserve(permissions.size());
@@ -191,7 +208,14 @@ int PermissionManagerQt::RequestPermissions(const std::vector<content::Permissio
const ProfileAdapter::PermissionType permissionType = toQt(permission);
if (permissionType == ProfileAdapter::UnsupportedPermission)
result.push_back(blink::mojom::PermissionStatus::DENIED);
- else {
+ else if (permissionType == ProfileAdapter::ClipboardRead) {
+ WebEngineSettings *settings = contentsDelegate->webEngineSettings();
+ if (settings->testAttribute(WebEngineSettings::JavascriptCanAccessClipboard)
+ && settings->testAttribute(WebEngineSettings::JavascriptCanPaste))
+ result.push_back(blink::mojom::PermissionStatus::GRANTED);
+ else
+ result.push_back(blink::mojom::PermissionStatus::DENIED);
+ } else {
answerable = false;
break;
}
@@ -202,9 +226,6 @@ int PermissionManagerQt::RequestPermissions(const std::vector<content::Permissio
}
int request_id = ++m_requestIdCount;
- content::WebContents *webContents = frameHost->GetRenderViewHost()->GetDelegate()->GetAsWebContents();
- WebContentsDelegateQt* contentsDelegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate());
- Q_ASSERT(contentsDelegate);
MultiRequest request = {
permissions,
toQt(requesting_origin),
@@ -241,6 +262,18 @@ blink::mojom::PermissionStatus PermissionManagerQt::GetPermissionStatusForFrame(
content::RenderFrameHost *render_frame_host,
const GURL &requesting_origin)
{
+ if (permission == content::PermissionType::CLIPBOARD_READ ||
+ permission == content::PermissionType::CLIPBOARD_WRITE) {
+ WebContentsDelegateQt *delegate = static_cast<WebContentsDelegateQt *>(
+ content::WebContents::FromRenderFrameHost(render_frame_host)->GetDelegate());
+ if (!delegate->webEngineSettings()->testAttribute(WebEngineSettings::JavascriptCanAccessClipboard))
+ return blink::mojom::PermissionStatus::DENIED;
+ if (permission == content::PermissionType::CLIPBOARD_READ &&
+ !delegate->webEngineSettings()->testAttribute(WebEngineSettings::JavascriptCanPaste))
+ return blink::mojom::PermissionStatus::DENIED;
+ return blink::mojom::PermissionStatus::GRANTED;
+ }
+
return GetPermissionStatus(
permission,
requesting_origin,
diff --git a/src/core/profile_adapter.h b/src/core/profile_adapter.h
index 3b1b9bc91..800058bc5 100644
--- a/src/core/profile_adapter.h
+++ b/src/core/profile_adapter.h
@@ -157,6 +157,8 @@ public:
// NotificationPermission = 2,
AudioCapturePermission = 3,
VideoCapturePermission = 4,
+ ClipboardRead = 5,
+ ClipboardWrite = 6,
};
HttpCacheType httpCacheType() const;
diff --git a/src/core/profile_io_data_qt.cpp b/src/core/profile_io_data_qt.cpp
index 83886ca54..4815b8749 100644
--- a/src/core/profile_io_data_qt.cpp
+++ b/src/core/profile_io_data_qt.cpp
@@ -49,6 +49,7 @@
#include "content/public/common/content_features.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
#include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h"
+#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/ct_log_verifier.h"
#include "net/cert/ct_policy_enforcer.h"
@@ -194,6 +195,11 @@ ProfileIODataQt::~ProfileIODataQt()
delete m_proxyConfigService.fetchAndStoreAcquire(0);
}
+QPointer<ProfileAdapter> ProfileIODataQt::profileAdapter()
+{
+ return m_profileAdapter;
+}
+
void ProfileIODataQt::shutdownOnUIThread()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
@@ -647,10 +653,15 @@ void ProfileIODataQt::updateStorageSettings()
// must synchronously run on the glib message loop. This will be passed to
// the URLRequestContextStorage on the IO thread in GetURLRequestContext().
Q_ASSERT(m_proxyConfigService == 0);
+ net::ProxyConfigWithAnnotation initialConfig;
+ ProxyPrefs::ConfigState initialConfigState = PrefProxyConfigTrackerImpl::ReadPrefConfig(
+ m_profileAdapter->profile()->GetPrefs(), &initialConfig);
+
m_proxyConfigService =
new ProxyConfigServiceQt(
net::ProxyResolutionService::CreateSystemProxyConfigService(
- base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::IO})));
+ base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::IO})),
+ initialConfig, initialConfigState);
//pass interface to io thread
m_proxyResolverFactoryInterface = ChromeMojoProxyResolverFactory::CreateWithStrongBinding().PassInterface();
if (m_initialized)
@@ -742,6 +753,11 @@ QWebEngineUrlRequestInterceptor *ProfileIODataQt::acquireInterceptor()
return m_requestInterceptor;
}
+QWebEngineUrlRequestInterceptor *ProfileIODataQt::requestInterceptor()
+{
+ return m_requestInterceptor;
+}
+
bool ProfileIODataQt::hasPageInterceptors()
{
// used in NetworkDelegateQt::OnBeforeURLRequest
diff --git a/src/core/profile_io_data_qt.h b/src/core/profile_io_data_qt.h
index 23497c476..407d0d6f2 100644
--- a/src/core/profile_io_data_qt.h
+++ b/src/core/profile_io_data_qt.h
@@ -80,6 +80,7 @@ public:
ProfileIODataQt(ProfileQt *profile); // runs on ui thread
virtual ~ProfileIODataQt();
+ QPointer<ProfileAdapter> profileAdapter();
content::ResourceContext *resourceContext();
net::URLRequestContext *urlRequestContext();
#if BUILDFLAG(ENABLE_EXTENSIONS)
@@ -105,6 +106,7 @@ public:
// Used in NetworkDelegateQt::OnBeforeURLRequest.
QWebEngineUrlRequestInterceptor *acquireInterceptor();
void releaseInterceptor();
+ QWebEngineUrlRequestInterceptor *requestInterceptor();
void setRequestContextData(content::ProtocolHandlerMap *protocolHandlers,
content::URLRequestInterceptorScopedVector request_interceptors);
diff --git a/src/core/profile_qt.cpp b/src/core/profile_qt.cpp
index 68e933d85..0ede1df55 100644
--- a/src/core/profile_qt.cpp
+++ b/src/core/profile_qt.cpp
@@ -41,6 +41,7 @@
#include "profile_adapter.h"
#include "browsing_data_remover_delegate_qt.h"
+#include "command_line_pref_store_qt.h"
#include "download_manager_delegate_qt.h"
#include "net/ssl_host_state_delegate_qt.h"
#include "net/url_request_context_getter_qt.h"
@@ -48,6 +49,7 @@
#include "qtwebenginecoreglobal_p.h"
#include "type_conversion.h"
#include "web_engine_library_info.h"
+#include "web_engine_context.h"
#include "base/time/time.h"
#include "content/public/browser/browser_thread.h"
@@ -62,6 +64,7 @@
#include "components/prefs/pref_service_factory.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/user_prefs/user_prefs.h"
+#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
#if QT_CONFIG(webengine_spellchecker)
#include "chrome/browser/spellchecker/spellcheck_service.h"
#include "chrome/common/pref_names.h"
@@ -89,8 +92,10 @@ ProfileQt::ProfileQt(ProfileAdapter *profileAdapter)
{
PrefServiceFactory factory;
factory.set_user_prefs(new InMemoryPrefStore);
+ factory.set_command_line_prefs(base::MakeRefCounted<CommandLinePrefStoreQt>(
+ WebEngineContext::commandLine()));
PrefRegistrySimple *registry = new PrefRegistrySimple();
-
+ PrefProxyConfigTrackerImpl::RegisterPrefs(registry);
#if QT_CONFIG(webengine_spellchecker)
// Initial spellcheck settings
registry->RegisterStringPref(prefs::kAcceptLanguages, std::string());
diff --git a/src/core/qtwebengine.gni b/src/core/qtwebengine.gni
index b7f10833a..7c0ca763e 100644
--- a/src/core/qtwebengine.gni
+++ b/src/core/qtwebengine.gni
@@ -27,6 +27,7 @@ deps = [
"//components/web_cache/browser",
"//components/web_cache/renderer",
"//components/spellcheck:buildflags",
+ "//components/proxy_config",
"//content/public/app:browser",
"//content",
"//media:media_buildflags",
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 9bf767437..63a1637fe 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -361,6 +361,7 @@ WebEngineContext::WebEngineContext()
base::TaskScheduler::Create("Browser");
m_contentRunner.reset(content::ContentMainRunner::Create());
m_browserRunner.reset(content::BrowserMainRunner::Create());
+
#ifdef Q_OS_LINUX
// Call qputenv before BrowserMainRunnerImpl::Initialize is called.
// http://crbug.com/245466
@@ -376,33 +377,18 @@ WebEngineContext::WebEngineContext()
// Allow us to inject javascript like any webview toolkit.
content::RenderFrameHost::AllowInjectingJavaScriptForAndroidWebView();
- base::CommandLine::CreateEmpty();
- base::CommandLine* parsedCommandLine = base::CommandLine::ForCurrentProcess();
QStringList appArgs = QCoreApplication::arguments();
- if (qEnvironmentVariableIsSet(kChromiumFlagsEnv)) {
- appArgs = appArgs.mid(0, 1); // Take application name and drop the rest
- appArgs.append(QString::fromLocal8Bit(qgetenv(kChromiumFlagsEnv)).split(' '));
- }
- bool enableWebGLSoftwareRendering =
- appArgs.removeAll(QStringLiteral("--enable-webgl-software-rendering"));
+ bool enableWebGLSoftwareRendering = appArgs.contains(QStringLiteral("--enable-webgl-software-rendering"));
bool useEmbeddedSwitches = false;
#if defined(QTWEBENGINE_EMBEDDED_SWITCHES)
- useEmbeddedSwitches = !appArgs.removeAll(QStringLiteral("--disable-embedded-switches"));
-#else
- useEmbeddedSwitches = appArgs.removeAll(QStringLiteral("--enable-embedded-switches"));
-#endif
- base::CommandLine::StringVector argv;
- argv.resize(appArgs.size());
-#if defined(Q_OS_WIN)
- for (int i = 0; i < appArgs.size(); ++i)
- argv[i] = toString16(appArgs[i]);
+ useEmbeddedSwitches = !appArgs.contains(QStringLiteral("--disable-embedded-switches"));
#else
- for (int i = 0; i < appArgs.size(); ++i)
- argv[i] = appArgs[i].toStdString();
+ useEmbeddedSwitches = appArgs.contains(QStringLiteral("--enable-embedded-switches"));
#endif
- parsedCommandLine->InitFromArgv(argv);
+
+ base::CommandLine* parsedCommandLine = commandLine();
parsedCommandLine->AppendSwitchPath(switches::kBrowserSubprocessPath, WebEngineLibraryInfo::getPath(content::CHILD_PROCESS_EXE));
@@ -665,4 +651,34 @@ gpu::SyncPointManager *WebEngineContext::syncPointManager()
return s_syncPointManager.load();
}
+base::CommandLine* WebEngineContext::commandLine() {
+ if (base::CommandLine::CreateEmpty()) {
+ base::CommandLine* parsedCommandLine = base::CommandLine::ForCurrentProcess();
+ QStringList appArgs = QCoreApplication::arguments();
+ if (qEnvironmentVariableIsSet(kChromiumFlagsEnv)) {
+ appArgs = appArgs.mid(0, 1); // Take application name and drop the rest
+ appArgs.append(QString::fromLocal8Bit(qgetenv(kChromiumFlagsEnv)).split(' '));
+ }
+#ifdef Q_OS_WIN
+ appArgs.removeAll(QStringLiteral("--enable-webgl-software-rendering"));
+#endif
+ appArgs.removeAll(QStringLiteral("--disable-embedded-switches"));
+ appArgs.removeAll(QStringLiteral("--enable-embedded-switches"));
+
+ base::CommandLine::StringVector argv;
+ argv.resize(appArgs.size());
+#if defined(Q_OS_WIN)
+ for (int i = 0; i < appArgs.size(); ++i)
+ argv[i] = toString16(appArgs[i]);
+#else
+ for (int i = 0; i < appArgs.size(); ++i)
+ argv[i] = appArgs[i].toStdString();
+#endif
+ parsedCommandLine->InitFromArgv(argv);
+ return parsedCommandLine;
+ } else {
+ return base::CommandLine::ForCurrentProcess();
+ }
+}
+
} // namespace
diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h
index ad02ddf4d..4dc5251cc 100644
--- a/src/core/web_engine_context.h
+++ b/src/core/web_engine_context.h
@@ -47,6 +47,7 @@
namespace base {
class RunLoop;
+class CommandLine;
}
namespace content {
@@ -95,6 +96,7 @@ public:
void addProfileAdapter(ProfileAdapter *profileAdapter);
void removeProfileAdapter(ProfileAdapter *profileAdapter);
void destroy();
+ static base::CommandLine* commandLine();
static gpu::SyncPointManager *syncPointManager();
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
index 4448d44d1..8a6c20f67 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -922,20 +922,45 @@ void QQuickWebEngineProfile::clearHttpCache()
d->profileAdapter()->clearHttpCache();
}
-
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
Registers a request interceptor singleton \a interceptor to intercept URL requests.
The profile does not take ownership of the pointer.
+ \obsolete
+
+ Interceptors installed with this method will call
+ QWebEngineUrlRequestInterceptor::interceptRequest on the I/O thread. Therefore
+ the user has to provide thread-safe interaction with the other user classes.
+ Use setUrlRequestInterceptor instead.
+
\sa QWebEngineUrlRequestInterceptor
+
*/
void QQuickWebEngineProfile::setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
{
Q_D(QQuickWebEngineProfile);
+ interceptor->setProperty("deprecated", true);
+ d->profileAdapter()->setRequestInterceptor(interceptor);
+ qWarning("Use of deprecated not tread-safe setter, use setUrlRequestInterceptor instead.");
+}
+#endif
+
+/*!
+ Registers a request interceptor singleton \a interceptor to intercept URL requests.
+
+ The profile does not take ownership of the pointer.
+
+ \sa QWebEngineUrlRequestInfo QWebEngineUrlRequestInterceptor
+*/
+void QQuickWebEngineProfile::setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
+{
+ Q_D(QQuickWebEngineProfile);
d->profileAdapter()->setRequestInterceptor(interceptor);
}
+
/*!
Returns the custom URL scheme handler register for the URL scheme \a scheme.
*/
diff --git a/src/webengine/api/qquickwebengineprofile.h b/src/webengine/api/qquickwebengineprofile.h
index 1e2e3e030..f4460ba18 100644
--- a/src/webengine/api/qquickwebengineprofile.h
+++ b/src/webengine/api/qquickwebengineprofile.h
@@ -126,7 +126,10 @@ public:
QWebEngineCookieStore *cookieStore() const;
+#if QT_DEPRECATED_SINCE(5, 13)
void setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor);
+#endif
+ void setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor);
const QWebEngineUrlSchemeHandler *urlSchemeHandler(const QByteArray &) const;
void installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *);
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 3bc1a0b80..22ef8fffe 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -1797,7 +1797,7 @@ void QWebEnginePagePrivate::printRequested()
\sa QWebEngineUrlRequestInfo, QWebEngineProfile::setRequestInterceptor()
*/
-void QWebEnginePage::setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
+void QWebEnginePage::setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
{
Q_D(QWebEnginePage);
bool hadInterceptorChanged = bool(d->requestInterceptor) != bool(interceptor);
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index 4fd195074..55450e438 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -77,8 +77,6 @@ class QWEBENGINEWIDGETS_EXPORT QWebEnginePage : public QObject {
Q_OBJECT
Q_PROPERTY(QString selectedText READ selectedText)
Q_PROPERTY(bool hasSelection READ hasSelection)
-
- // Ex-QWebFrame properties
Q_PROPERTY(QUrl requestedUrl READ requestedUrl)
Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor)
Q_PROPERTY(QString title READ title)
@@ -306,7 +304,7 @@ public:
void setDevToolsPage(QWebEnginePage *page);
QWebEnginePage *devToolsPage() const;
- void setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor);
+ void setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor);
const QWebEngineContextMenuData &contextMenuData() const;
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index 7e80f9720..e9703ffe8 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -550,19 +550,43 @@ QWebEngineCookieStore* QWebEngineProfile::cookieStore()
return d->profileAdapter()->cookieStore();
}
-
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
Registers a request interceptor singleton \a interceptor to intercept URL requests.
The profile does not take ownership of the pointer.
+ \obsolete
+
+ Interceptors installed with this method will call
+ QWebEngineUrlRequestInterceptor::interceptRequest on the I/O thread. Therefore
+ the user has to provide thread-safe interaction with the other user classes.
+ Use setUrlRequestInterceptor instead.
+
\since 5.6
\sa QWebEngineUrlRequestInfo
-*/
+*/
void QWebEngineProfile::setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
{
Q_D(QWebEngineProfile);
+ interceptor->setProperty("deprecated", true);
+ d->profileAdapter()->setRequestInterceptor(interceptor);
+ qWarning("Use of deprecated not tread-safe setter, use setUrlRequestInterceptor instead.");
+}
+#endif
+/*!
+ Registers a request interceptor singleton \a interceptor to intercept URL requests.
+
+ The profile does not take ownership of the pointer.
+
+ \since 5.13
+ \sa QWebEngineUrlRequestInfo QWebEngineUrlRequestInterceptor
+*/
+
+void QWebEngineProfile::setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
+{
+ Q_D(QWebEngineProfile);
d->profileAdapter()->setRequestInterceptor(interceptor);
}
diff --git a/src/webenginewidgets/api/qwebengineprofile.h b/src/webenginewidgets/api/qwebengineprofile.h
index 9fc509851..79e83c377 100644
--- a/src/webenginewidgets/api/qwebengineprofile.h
+++ b/src/webenginewidgets/api/qwebengineprofile.h
@@ -106,7 +106,10 @@ public:
void setHttpCacheMaximumSize(int maxSize);
QWebEngineCookieStore* cookieStore();
+#if QT_DEPRECATED_SINCE(5, 13)
void setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor);
+#endif
+ void setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor);
void clearAllVisitedLinks();
void clearVisitedLinks(const QList<QUrl> &urls);
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
index 7b7fec6f4..5629998fd 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
@@ -107,6 +107,7 @@ public:
void interceptRequest(QWebEngineUrlRequestInfo &info) override
{
+ QVERIFY(QThread::currentThread() == QCoreApplication::instance()->thread());
// Since 63 we also intercept some unrelated blob requests..
if (info.requestUrl().scheme() == QLatin1String("blob"))
return;
@@ -167,7 +168,7 @@ void tst_QWebEngineUrlRequestInterceptor::interceptRequest()
QWebEngineProfile profile;
profile.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
TestRequestInterceptor interceptor(/* intercept */ true);
- profile.setRequestInterceptor(&interceptor);
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
@@ -197,7 +198,7 @@ void tst_QWebEngineUrlRequestInterceptor::interceptRequest()
// Make sure that registering an observer does not modify the request.
TestRequestInterceptor observer(/* intercept */ false);
- profile.setRequestInterceptor(&observer);
+ profile.setUrlRequestInterceptor(&observer);
page.load(QUrl("qrc:///resources/__placeholder__"));
QTRY_COMPARE(loadSpy.count(), 1);
success = loadSpy.takeFirst().takeFirst();
@@ -230,7 +231,7 @@ void tst_QWebEngineUrlRequestInterceptor::ipv6HostEncoding()
{
QWebEngineProfile profile;
LocalhostContentProvider contentProvider;
- profile.setRequestInterceptor(&contentProvider);
+ profile.setUrlRequestInterceptor(&contentProvider);
QWebEnginePage page(&profile);
QSignalSpy spyLoadFinished(&page, SIGNAL(loadFinished(bool)));
@@ -264,11 +265,11 @@ void tst_QWebEngineUrlRequestInterceptor::requestedUrl()
profile.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
TestRequestInterceptor interceptor(/* intercept */ true);
if (!interceptInPage)
- profile.setRequestInterceptor(&interceptor);
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
if (interceptInPage)
- page.setRequestInterceptor(&interceptor);
+ page.setUrlRequestInterceptor(&interceptor);
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
page.setUrl(QUrl("qrc:///resources/__placeholder__"));
@@ -303,11 +304,11 @@ void tst_QWebEngineUrlRequestInterceptor::setUrlSameUrl()
QWebEngineProfile profile;
TestRequestInterceptor interceptor(/* intercept */ true);
if (!interceptInPage)
- profile.setRequestInterceptor(&interceptor);
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
if (interceptInPage)
- page.setRequestInterceptor(&interceptor);
+ page.setUrlRequestInterceptor(&interceptor);
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
page.setUrl(QUrl("qrc:///resources/__placeholder__"));
@@ -336,7 +337,7 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrl()
{
QWebEngineProfile profile;
TestRequestInterceptor interceptor(/* intercept */ false);
- profile.setRequestInterceptor(&interceptor);
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
@@ -370,7 +371,7 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlNestedIframes()
QWebEngineProfile profile;
TestRequestInterceptor interceptor(/* intercept */ false);
- profile.setRequestInterceptor(&interceptor);
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
@@ -431,7 +432,7 @@ void tst_QWebEngineUrlRequestInterceptor::requestInterceptorByResourceType()
QWebEngineProfile profile;
TestRequestInterceptor interceptor(/* intercept */ false);
- profile.setRequestInterceptor(&interceptor);
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
@@ -449,7 +450,7 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlHttp()
{
QWebEngineProfile profile;
TestRequestInterceptor interceptor(/* intercept */ false);
- profile.setRequestInterceptor(&interceptor);
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
diff --git a/tests/auto/quick/qquickwebengineview/BLACKLIST b/tests/auto/quick/qquickwebengineview/BLACKLIST
index 5bb38576a..166a6894e 100644
--- a/tests/auto/quick/qquickwebengineview/BLACKLIST
+++ b/tests/auto/quick/qquickwebengineview/BLACKLIST
@@ -15,7 +15,3 @@ opensuse-leap
[javascriptClipboard:canPaste]
opensuse-leap
-
-[changeLocale]
-*
-
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index d467cd8ae..9817e7d6c 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -1001,6 +1001,7 @@ void tst_QQuickWebEngineView::changeLocale()
viewDE->setUrl(url);
QVERIFY(waitForLoadFailed(viewDE.data()));
+ QTRY_VERIFY(!evaluateJavaScriptSync(viewDE.data(), "document.body").isNull());
QTRY_VERIFY(!evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").isNull());
errorLines = evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").toString().split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar Die Server-IP-Adresse von non.existent wurde nicht gefunden."));
@@ -1010,9 +1011,10 @@ void tst_QQuickWebEngineView::changeLocale()
viewEN->setUrl(url);
QVERIFY(waitForLoadFailed(viewEN.data()));
+ QTRY_VERIFY(!evaluateJavaScriptSync(viewEN.data(), "document.body").isNull());
QTRY_VERIFY(!evaluateJavaScriptSync(viewEN.data(), "document.body.innerText").isNull());
errorLines = evaluateJavaScriptSync(viewEN.data(), "document.body.innerText").toString().split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
- QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("This site can\xE2\x80\x99t be reached"));
+ QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("This site can\xE2\x80\x99t be reached non.existent\xE2\x80\x99s server IP address could not be found."));
// Reset error page
viewDE->setUrl(QUrl("about:blank"));
@@ -1022,9 +1024,10 @@ void tst_QQuickWebEngineView::changeLocale()
viewDE->setUrl(url);
QVERIFY(waitForLoadFailed(viewDE.data()));
+ QTRY_VERIFY(!evaluateJavaScriptSync(viewDE.data(), "document.body").isNull());
QTRY_VERIFY(!evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").isNull());
errorLines = evaluateJavaScriptSync(viewDE.data(), "document.body.innerText").toString().split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts);
- QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar"));
+ QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar Die Server-IP-Adresse von non.existent wurde nicht gefunden."));
}
void tst_QQuickWebEngineView::userScripts()
@@ -1110,6 +1113,39 @@ void tst_QQuickWebEngineView::javascriptClipboard()
QCOMPARE(evaluateJavaScriptSync(view, "document.execCommand('paste')").toBool(), pasteResult);
QCOMPARE(evaluateJavaScriptSync(view, "document.getElementById('myInput').value").toString(),
(pasteResult ? QString("AnotherText") : QString("OriginalText")));
+
+ // Test settings on clipboard permissions
+ evaluateJavaScriptSync(view,
+ QStringLiteral(
+ "var accessGranted = false;"
+ "var accessDenied = false;"
+ "var accessPrompt = false;"
+ "navigator.permissions.query({name:'clipboard-write'})"
+ ".then(result => {"
+ "if (result.state == 'granted') accessGranted = true;"
+ "if (result.state == 'denied') accessDenied = true;"
+ "if (result.state == 'prompt') accessPrompt = true;"
+ "})"));
+
+ QTRY_COMPARE(evaluateJavaScriptSync(view, "accessGranted").toBool(), copyResult);
+ QTRY_COMPARE(evaluateJavaScriptSync(view, "accessDenied").toBool(), !javascriptCanAccessClipboard);
+ QTRY_COMPARE(evaluateJavaScriptSync(view, "accessPrompt").toBool(), false);
+
+ evaluateJavaScriptSync(view,
+ QStringLiteral(
+ "accessGranted = false;"
+ "accessDenied = false;"
+ "accessPrompt = false;"
+ "navigator.permissions.query({name:'clipboard-read'})"
+ ".then(result => {"
+ "if (result.state == 'granted') accessGranted = true;"
+ "if (result.state == 'denied') accessDenied = true;"
+ "if (result.state == 'prompt') accessPrompt = true;"
+ "})"));
+
+ QTRY_COMPARE(evaluateJavaScriptSync(view, "accessGranted").toBool(), pasteResult);
+ QTRY_COMPARE(evaluateJavaScriptSync(view, "accessDenied").toBool(), !javascriptCanAccessClipboard || !javascriptCanPaste);
+ QTRY_COMPARE(evaluateJavaScriptSync(view, "accessPrompt").toBool(), false);
}
QTEST_MAIN(tst_QQuickWebEngineView)
diff --git a/tests/auto/widgets/proxypac/proxypac.pro b/tests/auto/widgets/proxypac/proxypac.pro
index 00ae90977..1c2958d3a 100644
--- a/tests/auto/widgets/proxypac/proxypac.pro
+++ b/tests/auto/widgets/proxypac/proxypac.pro
@@ -3,26 +3,8 @@ QT += webengine
HEADERS += proxyserver.h
SOURCES += proxyserver.cpp
-# QTBUG-71229
-xgd_desktop.name=XDG_CURRENT_DESKTOP
-xgd_desktop.value=KDE
-QT_TOOL_ENV += xgd_desktop
+proxy_pac.name = QTWEBENGINE_CHROMIUM_FLAGS
+proxy_pac.value = --proxy-pac-url="file://$$PWD/proxy.pac"
-kde_home.name=KDEHOME
-kde_home.value=$$OUT_PWD
-QT_TOOL_ENV += kde_home
-
-PROXY_CONFIG= \
- "[Proxy Settings]" \
- "Proxy Config Script=$$PWD/proxy.pac" \
- "ProxyType=2"
-
-mkpath($$OUT_PWD/share/config)
-KDE_FILE = $$OUT_PWD/share/config/kioslaverc
-
-!build_pass {
- write_file($$KDE_FILE, PROXY_CONFIG)
-}
-
-QMAKE_DISTCLEAN += $$KDE_FILE
+QT_TOOL_ENV += proxy_pac
diff --git a/tests/auto/widgets/qwebengineview/BLACKLIST b/tests/auto/widgets/qwebengineview/BLACKLIST
index e8758abcc..7c86a72d6 100644
--- a/tests/auto/widgets/qwebengineview/BLACKLIST
+++ b/tests/auto/widgets/qwebengineview/BLACKLIST
@@ -6,6 +6,3 @@ osx
[textSelectionOutOfInputField]
*
-
-[changeLocale]
-*
diff --git a/tests/auto/widgets/widgets.pro b/tests/auto/widgets/widgets.pro
index eec8bb389..0addb9671 100644
--- a/tests/auto/widgets/widgets.pro
+++ b/tests/auto/widgets/widgets.pro
@@ -9,6 +9,7 @@ SUBDIRS += \
faviconmanager \
loadsignals \
origins \
+ proxypac \
schemes \
shutdown \
qwebenginedownloaditem \
@@ -27,9 +28,6 @@ qtConfig(webengine-printing-and-pdf) {
SUBDIRS += printing
}
-# QTBUG-71229
-linux:!boot2qt: SUBDIRS += proxypac
-
qtConfig(webengine-spellchecker):!cross_compile {
!qtConfig(webengine-native-spellchecker) {
SUBDIRS += spellchecking
@@ -43,4 +41,4 @@ boot2qt: SUBDIRS -= accessibility defaultsurfaceformat devtools \
faviconmanager qwebenginepage qwebenginehistory \
qwebengineprofile qwebenginescript \
qwebengineview qwebenginedownloaditem qwebenginesettings \
- schemes origins loadsignals
+ schemes origins loadsignals proxypac