diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-01-18 15:40:56 +0100 |
---|---|---|
committer | Michal Klocek <michal.klocek@qt.io> | 2021-01-19 23:13:47 +0100 |
commit | a7510e85e6f53f4e889307edb58f26c8900d2d06 (patch) | |
tree | d4b6208bb8bf7d8288c57d7024c2813b3af1b5aa /src/core | |
parent | 91696b2cb090e5b6147a30465f74d8d37db48615 (diff) | |
parent | f1f763cf3c7254406b7b6f01551b6624210bb834 (diff) |
Merge branch '5.15' into dev
Last commits before 87 update.
Change-Id: Id156b0199a8fd354c946cfe604ae8541ba554658
Diffstat (limited to 'src/core')
30 files changed, 473 insertions, 502 deletions
diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp index aad929611..aa3fba24e 100644 --- a/src/core/api/qwebenginepage.cpp +++ b/src/core/api/qwebenginepage.cpp @@ -313,7 +313,6 @@ void QWebEnginePagePrivate::loadFinished(bool success, const QUrl &url, bool isE Q_UNUSED(errorDescription); if (isErrorPage) { - Q_ASSERT(settings->testAttribute(QWebEngineSettings::ErrorPageEnabled)); QTimer::singleShot(0, q, [q](){ emit q->loadFinished(false); }); diff --git a/src/core/common/qt_messages.h b/src/core/common/qt_messages.h index 43f07c9a6..7713b6286 100644 --- a/src/core/common/qt_messages.h +++ b/src/core/common/qt_messages.h @@ -9,65 +9,18 @@ #include "content/public/common/webplugininfo.h" #include "ipc/ipc_message_macros.h" #include "ppapi/buildflags/buildflags.h" -#include "user_script_data.h" - -IPC_STRUCT_TRAITS_BEGIN(UserScriptData) - IPC_STRUCT_TRAITS_MEMBER(source) - IPC_STRUCT_TRAITS_MEMBER(url) - IPC_STRUCT_TRAITS_MEMBER(injectionPoint) - IPC_STRUCT_TRAITS_MEMBER(injectForSubframes) - IPC_STRUCT_TRAITS_MEMBER(worldId) - IPC_STRUCT_TRAITS_MEMBER(scriptId) - IPC_STRUCT_TRAITS_MEMBER(globs) - IPC_STRUCT_TRAITS_MEMBER(excludeGlobs) - IPC_STRUCT_TRAITS_MEMBER(urlPatterns) -IPC_STRUCT_TRAITS_END() - #define IPC_MESSAGE_START QtMsgStart -//----------------------------------------------------------------------------- -// RenderView messages -// These are messages sent from the browser to the renderer process. - -IPC_MESSAGE_ROUTED1(RenderViewObserverQt_FetchDocumentMarkup, - uint64_t /* requestId */) - -IPC_MESSAGE_ROUTED1(RenderViewObserverQt_FetchDocumentInnerText, - uint64_t /* requestId */) - -IPC_MESSAGE_ROUTED1(RenderViewObserverQt_SetBackgroundColor, - uint32_t /* color */) - -// User scripts messages -IPC_MESSAGE_ROUTED1(RenderFrameObserverHelper_AddScript, - UserScriptData /* script */) -IPC_MESSAGE_ROUTED1(RenderFrameObserverHelper_RemoveScript, - UserScriptData /* script */) -IPC_MESSAGE_ROUTED0(RenderFrameObserverHelper_ClearScripts) - -IPC_MESSAGE_CONTROL1(UserResourceController_AddScript, UserScriptData /* scriptContents */) -IPC_MESSAGE_CONTROL1(UserResourceController_RemoveScript, UserScriptData /* scriptContents */) -IPC_MESSAGE_CONTROL0(UserResourceController_ClearScripts) - // Tells the renderer whether or not a file system access has been allowed. IPC_MESSAGE_ROUTED2(QtWebEngineMsg_RequestFileSystemAccessAsyncResponse, int /* request_id */, bool /* allowed */) - //----------------------------------------------------------------------------- // WebContents messages // These are messages sent from the renderer back to the browser process. -IPC_MESSAGE_ROUTED2(RenderViewObserverHostQt_DidFetchDocumentMarkup, - uint64_t /* requestId */, - base::string16 /* markup */) - -IPC_MESSAGE_ROUTED2(RenderViewObserverHostQt_DidFetchDocumentInnerText, - uint64_t /* requestId */, - base::string16 /* innerText */) - IPC_MESSAGE_ROUTED0(RenderViewObserverHostQt_DidFirstVisuallyNonEmptyLayout) //----------------------------------------------------------------------------- diff --git a/src/core/common/user_script_data.cpp b/src/core/common/user_script_data.cpp deleted file mode 100644 index 68840d2fa..000000000 --- a/src/core/common/user_script_data.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#include "user_script_data.h" -#include "base/pickle.h" - -UserScriptData::UserScriptData() : injectionPoint(AfterLoad) -{ - static uint64_t idCount = 0; - scriptId = idCount++; -} diff --git a/src/core/common/user_script_data.h b/src/core/common/user_script_data.h deleted file mode 100644 index a2ca8c2ea..000000000 --- a/src/core/common/user_script_data.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef USER_SCRIPT_DATA_H -#define USER_SCRIPT_DATA_H - -#include <QtCore/QHash> -#include <string> -#include "ipc/ipc_message_utils.h" -#include "url/gurl.h" - -struct UserScriptData { - enum InjectionPoint { - AfterLoad, - DocumentLoadFinished, - DocumentElementCreation - }; - - UserScriptData(); - - std::string source; - GURL url; - uint8_t injectionPoint = AfterLoad; - bool injectForSubframes = false; - uint worldId = 1; - uint64_t scriptId; - std::vector<std::string> globs; - std::vector<std::string> excludeGlobs; - std::vector<std::string> urlPatterns; -}; - -QT_BEGIN_NAMESPACE - -Q_DECLARE_TYPEINFO(UserScriptData, Q_MOVABLE_TYPE); - -QT_END_NAMESPACE - -#endif // USER_SCRIPT_DATA_H diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri index f7ea8fcd1..63e9718e7 100644 --- a/src/core/core_chromium.pri +++ b/src/core/core_chromium.pri @@ -52,7 +52,6 @@ SOURCES = \ color_chooser_controller.cpp \ common/qt_ipc_logging.cpp \ common/qt_messages.cpp \ - common/user_script_data.cpp \ compositor/compositor.cpp \ compositor/content_gpu_client_qt.cpp \ compositor/display_overrides.cpp \ @@ -113,11 +112,11 @@ SOURCES = \ renderer/content_renderer_client_qt.cpp \ renderer/content_settings_observer_qt.cpp \ renderer/render_frame_observer_qt.cpp \ - renderer/render_view_observer_qt.cpp \ - renderer/render_thread_observer_qt.cpp \ + renderer/web_engine_page_render_frame.cpp \ + renderer/render_configuration.cpp \ renderer/user_resource_controller.cpp \ renderer/plugins/plugin_placeholder_qt.cpp \ - renderer_host/render_view_observer_host_qt.cpp \ + renderer_host/web_engine_page_host.cpp \ renderer_host/user_resource_controller_host.cpp \ resource_bundle_qt.cpp \ resource_context_qt.cpp \ @@ -156,7 +155,6 @@ HEADERS = \ color_chooser_controller_p.h \ color_chooser_controller.h \ common/qt_messages.h \ - common/user_script_data.h \ compositor/compositor.h \ compositor/content_gpu_client_qt.h \ compositor/display_software_output_surface.h \ @@ -220,11 +218,11 @@ HEADERS = \ renderer/content_renderer_client_qt.h \ renderer/content_settings_observer_qt.h \ renderer/render_frame_observer_qt.h \ - renderer/render_view_observer_qt.h \ - renderer/render_thread_observer_qt.h \ + renderer/web_engine_page_render_frame.h \ + renderer/render_configuration.h \ renderer/user_resource_controller.h \ renderer/plugins/plugin_placeholder_qt.h \ - renderer_host/render_view_observer_host_qt.h \ + renderer_host/web_engine_page_host.h \ renderer_host/user_resource_controller_host.h \ request_controller.h \ resource_context_qt.h \ diff --git a/src/core/qtwebengine.gni b/src/core/qtwebengine.gni index a5628bb88..9afdc0e76 100644 --- a/src/core/qtwebengine.gni +++ b/src/core/qtwebengine.gni @@ -41,6 +41,7 @@ deps = [ "//ui/accessibility", "//ui/gl", "//qtwebengine/browser:interfaces", + "//qtwebengine/userscript", "//qtwebengine/browser:service_manifests", "//qtwebengine/common:mojo_bindings", ":qtwebengine_sources", diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 05ac76350..d298511ac 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -352,8 +352,6 @@ void RenderWidgetHostViewQt::UpdateBackgroundColor() content::RenderViewHost *rvh = content::RenderViewHost::From(host()); if (color == SK_ColorTRANSPARENT) host()->owner_delegate()->SetBackgroundOpaque(false); - else - host()->Send(new RenderViewObserverQt_SetBackgroundColor(rvh->GetRoutingID(), color)); } // Return value indicates whether the mouse is locked successfully or not. diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp index 8c70f2e42..154cb36b4 100644 --- a/src/core/renderer/content_renderer_client_qt.cpp +++ b/src/core/renderer/content_renderer_client_qt.cpp @@ -83,8 +83,8 @@ #include "common/qt_messages.h" #include "renderer/render_frame_observer_qt.h" -#include "renderer/render_view_observer_qt.h" -#include "renderer/render_thread_observer_qt.h" +#include "renderer/web_engine_page_render_frame.h" +#include "renderer/render_configuration.h" #include "renderer/user_resource_controller.h" #if QT_CONFIG(webengine_webchannel) #include "renderer/web_channel_ipc_transport.h" @@ -133,12 +133,13 @@ ContentRendererClientQt::~ContentRendererClientQt() {} void ContentRendererClientQt::RenderThreadStarted() { content::RenderThread *renderThread = content::RenderThread::Get(); - m_renderThreadObserver.reset(new RenderThreadObserverQt()); + m_renderConfiguration.reset(new RenderConfiguration()); + m_userResourceController.reset(new UserResourceController()); m_visitedLinkReader.reset(new visitedlink::VisitedLinkReader); m_webCacheImpl.reset(new web_cache::WebCacheImpl()); - renderThread->AddObserver(m_renderThreadObserver.data()); - renderThread->AddObserver(UserResourceController::instance()); + renderThread->AddObserver(m_renderConfiguration.data()); + renderThread->AddObserver(m_userResourceController.data()); #if QT_CONFIG(webengine_spellchecker) if (!m_spellCheck) @@ -187,23 +188,18 @@ void ContentRendererClientQt::ExposeInterfacesToBrowser(mojo::BinderMap* binders #endif } -void ContentRendererClientQt::RenderViewCreated(content::RenderView *render_view) -{ - // RenderViewObservers destroy themselves with their RenderView. - new RenderViewObserverQt(render_view); - UserResourceController::instance()->renderViewCreated(render_view); -} - void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame *render_frame) { QtWebEngineCore::RenderFrameObserverQt *render_frame_observer = new QtWebEngineCore::RenderFrameObserverQt(render_frame, m_webCacheImpl.data()); + if (render_frame->IsMainFrame()) { #if QT_CONFIG(webengine_webchannel) - if (render_frame->IsMainFrame()) new WebChannelIPCTransport(render_frame); #endif + new WebEnginePageRenderFrame(render_frame); + } - UserResourceController::instance()->renderFrameCreated(render_frame); + m_userResourceController->renderFrameCreated(render_frame); new QtWebEngineCore::ContentSettingsObserverQt(render_frame); @@ -234,7 +230,7 @@ void ContentRendererClientQt::RunScriptsAtDocumentEnd(content::RenderFrame *rend RenderFrameObserverQt *render_frame_observer = RenderFrameObserverQt::Get(render_frame); if (render_frame_observer && !render_frame_observer->isFrameDetached()) - UserResourceController::instance()->RunScriptsAtDocumentEnd(render_frame); + m_userResourceController->RunScriptsAtDocumentEnd(render_frame); #if BUILDFLAG(ENABLE_EXTENSIONS) ExtensionsRendererClientQt::GetInstance()->RunScriptsAtDocumentEnd(render_frame); @@ -305,10 +301,11 @@ void ContentRendererClientQt::GetNavigationErrorStringsInternal(content::RenderF // NetErrorHelper::GetErrorStringsForDnsProbe, but that one is harder to untangle. error_page::LocalizedError::PageState errorPageState = - error_page::LocalizedError::GetPageState( - error.reason(), error.domain(), error.url(), isPost, - false, error.stale_copy_in_cache(), false, RenderThreadObserverQt::is_incognito_process(), false, - false, false, locale, std::unique_ptr<error_page::ErrorPageParams>()); + error_page::LocalizedError::GetPageState( + error.reason(), error.domain(), error.url(), isPost, false, + error.stale_copy_in_cache(), false, + RenderConfiguration::is_incognito_process(), false, false, false, locale, + std::unique_ptr<error_page::ErrorPageParams>()); resourceId = IDR_NET_ERROR_HTML; diff --git a/src/core/renderer/content_renderer_client_qt.h b/src/core/renderer/content_renderer_client_qt.h index 24a841cb8..91bce972f 100644 --- a/src/core/renderer/content_renderer_client_qt.h +++ b/src/core/renderer/content_renderer_client_qt.h @@ -75,8 +75,8 @@ struct WebPluginInfo; namespace QtWebEngineCore { -class RenderThreadObserverQt; - +class UserResourceController; +class RenderConfiguration; class ContentRendererClientQt : public content::ContentRendererClient , public service_manager::LocalInterfaceProvider @@ -88,7 +88,6 @@ public: // content::ContentRendererClient: void RenderThreadStarted() override; void ExposeInterfacesToBrowser(mojo::BinderMap* binders) override; - void RenderViewCreated(content::RenderView *render_view) override; void RenderFrameCreated(content::RenderFrame *render_frame) override; bool ShouldSuppressErrorPage(content::RenderFrame *, const GURL &) override; bool HasErrorPage(int http_status_code) override; @@ -147,7 +146,8 @@ private: void GetNavigationErrorStringsInternal(content::RenderFrame *renderFrame, const std::string &httpMethod, const error_page::Error &error, std::string *errorHtml); - QScopedPointer<RenderThreadObserverQt> m_renderThreadObserver; + QScopedPointer<RenderConfiguration> m_renderConfiguration; + QScopedPointer<UserResourceController> m_userResourceController; QScopedPointer<visitedlink::VisitedLinkReader> m_visitedLinkReader; QScopedPointer<web_cache::WebCacheImpl> m_webCacheImpl; #if QT_CONFIG(webengine_spellchecker) diff --git a/src/core/renderer/extensions/extensions_renderer_client_qt.cpp b/src/core/renderer/extensions/extensions_renderer_client_qt.cpp index 7d4c9a83c..fd928df12 100644 --- a/src/core/renderer/extensions/extensions_renderer_client_qt.cpp +++ b/src/core/renderer/extensions/extensions_renderer_client_qt.cpp @@ -45,7 +45,7 @@ #include "extensions_renderer_client_qt.h" #include "extensions_dispatcher_delegate_qt.h" -#include "renderer/render_thread_observer_qt.h" +#include "renderer/render_configuration.h" #include "renderer_permissions_policy_delegate_qt.h" #include "resource_request_policy_qt.h" @@ -88,7 +88,7 @@ ExtensionsRendererClientQt::~ExtensionsRendererClientQt() // Returns true if the current render process was launched incognito. bool ExtensionsRendererClientQt::IsIncognitoProcess() const { - return RenderThreadObserverQt::is_incognito_process(); + return RenderConfiguration::is_incognito_process(); } // Returns the lowest isolated world ID available to extensions. diff --git a/src/core/renderer/render_thread_observer_qt.cpp b/src/core/renderer/render_configuration.cpp index 4912ebfc2..ef9da7af7 100644 --- a/src/core/renderer/render_thread_observer_qt.cpp +++ b/src/core/renderer/render_configuration.cpp @@ -42,31 +42,34 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "renderer/render_thread_observer_qt.h" - +#include "renderer/render_configuration.h" +#include "user_resource_controller.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" namespace QtWebEngineCore { -bool RenderThreadObserverQt::m_isIncognitoProcess = false; +bool RenderConfiguration::m_isIncognitoProcess = false; -void RenderThreadObserverQt::RegisterMojoInterfaces(blink::AssociatedInterfaceRegistry *associated_interfaces) +void RenderConfiguration::RegisterMojoInterfaces( + blink::AssociatedInterfaceRegistry *associated_interfaces) { associated_interfaces->AddInterface( - base::Bind(&RenderThreadObserverQt::OnRendererConfigurationAssociatedRequest, base::Unretained(this))); + base::Bind(&RenderConfiguration::OnRendererConfigurationAssociatedRequest, + base::Unretained(this))); } -void RenderThreadObserverQt::UnregisterMojoInterfaces(blink::AssociatedInterfaceRegistry *associated_interfaces) +void RenderConfiguration::UnregisterMojoInterfaces( + blink::AssociatedInterfaceRegistry *associated_interfaces) { associated_interfaces->RemoveInterface(qtwebengine::mojom::RendererConfiguration::Name_); } -void RenderThreadObserverQt::SetInitialConfiguration(bool is_incognito_process) +void RenderConfiguration::SetInitialConfiguration(bool is_incognito_process) { m_isIncognitoProcess = is_incognito_process; } -void RenderThreadObserverQt::OnRendererConfigurationAssociatedRequest( +void RenderConfiguration::OnRendererConfigurationAssociatedRequest( mojo::PendingAssociatedReceiver<qtwebengine::mojom::RendererConfiguration> receiver) { m_rendererConfigurationReceivers.Add(this, std::move(receiver)); diff --git a/src/core/renderer/render_thread_observer_qt.h b/src/core/renderer/render_configuration.h index 05372049b..138a85bdc 100644 --- a/src/core/renderer/render_thread_observer_qt.h +++ b/src/core/renderer/render_configuration.h @@ -37,8 +37,8 @@ ** ****************************************************************************/ -#ifndef RENDER_THREAD_OBSERVER_QT_H -#define RENDER_THREAD_OBSERVER_QT_H +#ifndef RENDER_CONFIGURATION_H +#define RENDER_CONFIGURATION_H #include "content/public/renderer/render_thread_observer.h" #include "mojo/public/cpp/bindings/associated_receiver_set.h" @@ -47,13 +47,12 @@ namespace QtWebEngineCore { -class RenderThreadObserverQt - : public content::RenderThreadObserver - , public qtwebengine::mojom::RendererConfiguration +class RenderConfiguration : public content::RenderThreadObserver, + public qtwebengine::mojom::RendererConfiguration { public: - RenderThreadObserverQt() = default; - ~RenderThreadObserverQt() override = default; + RenderConfiguration() = default; + ~RenderConfiguration() override = default; static bool is_incognito_process() { return m_isIncognitoProcess; } @@ -70,11 +69,12 @@ private: static bool m_isIncognitoProcess; - mojo::AssociatedReceiverSet<qtwebengine::mojom::RendererConfiguration> m_rendererConfigurationReceivers; + mojo::AssociatedReceiverSet<qtwebengine::mojom::RendererConfiguration> + m_rendererConfigurationReceivers; - DISALLOW_COPY_AND_ASSIGN(RenderThreadObserverQt); + DISALLOW_COPY_AND_ASSIGN(RenderConfiguration); }; } // namespace QtWebEngineCore -#endif // RENDER_THREAD_OBSERVER_QT_H +#endif // RENDER_CONFIGURATION_H diff --git a/src/core/renderer/user_resource_controller.cpp b/src/core/renderer/user_resource_controller.cpp index 3c1ad0477..e17498302 100644 --- a/src/core/renderer/user_resource_controller.cpp +++ b/src/core/renderer/user_resource_controller.cpp @@ -52,9 +52,12 @@ #include "third_party/blink/public/web/web_script_source.h" #include "third_party/blink/public/web/web_view.h" #include "v8/include/v8.h" +#include "mojo/public/cpp/bindings/associated_receiver.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" #include "common/qt_messages.h" -#include "common/user_script_data.h" +#include "qtwebengine/userscript/user_script_data.h" #include "type_conversion.h" #include "user_script.h" @@ -62,9 +65,9 @@ #include <bitset> -Q_GLOBAL_STATIC(UserResourceController, qt_webengine_userResourceController) +namespace QtWebEngineCore { -static content::RenderView *const globalScriptsIndex = nullptr; +static content::RenderFrame *const globalScriptsIndex = nullptr; // Scripts meant to run after the load event will be run 500ms after DOMContentLoaded if the load event doesn't come within that delay. static const int afterLoadTimeout = 500; @@ -97,7 +100,7 @@ static bool includeRuleMatchesURL(const std::string &pat, const GURL &url) return false; } -static bool scriptMatchesURL(const UserScriptData &scriptData, const GURL &url) +static bool scriptMatchesURL(const QtWebEngineCore::UserScriptData &scriptData, const GURL &url) { // Logic taken from Chromium (extensions/common/user_script.cc) bool matchFound; @@ -132,10 +135,18 @@ static bool scriptMatchesURL(const UserScriptData &scriptData, const GURL &url) return true; } -class UserResourceController::RenderFrameObserverHelper : public content::RenderFrameObserver +// using UserScriptDataPtr = mojo::StructPtr<qtwebengine::mojom::UserScriptData>; + +class UserResourceController::RenderFrameObserverHelper + : public content::RenderFrameObserver, + public qtwebengine::mojom::UserResourceControllerRenderFrame { public: - RenderFrameObserverHelper(content::RenderFrame *render_frame); + RenderFrameObserverHelper(content::RenderFrame *render_frame, + UserResourceController *controller); + void BindReceiver( + mojo::PendingAssociatedReceiver<qtwebengine::mojom::UserResourceControllerRenderFrame> + receiver); private: // RenderFrameObserver implementation. @@ -144,14 +155,14 @@ private: void DidFinishLoad() override; void FrameDetached() override; void OnDestruct() override; - bool OnMessageReceived(const IPC::Message &message) override; - - void onUserScriptAdded(const UserScriptData &); - void onUserScriptRemoved(const UserScriptData &); - void onScriptsCleared(); + void AddScript(const QtWebEngineCore::UserScriptData &data) override; + void RemoveScript(const QtWebEngineCore::UserScriptData &data) override; + void ClearScripts() override; class Runner; QScopedPointer<Runner> m_runner; + mojo::AssociatedReceiver<qtwebengine::mojom::UserResourceControllerRenderFrame> m_binding; + UserResourceController *m_userResourceController; }; // Helper class to create WeakPtrs so the AfterLoad tasks can be canceled and to @@ -159,13 +170,16 @@ private: class UserResourceController::RenderFrameObserverHelper::Runner : public base::SupportsWeakPtr<Runner> { public: - explicit Runner(blink::WebLocalFrame *frame) : m_frame(frame) {} + explicit Runner(blink::WebLocalFrame *frame, UserResourceController *controller) + : m_frame(frame), m_userResourceController(controller) + { + } - void run(UserScriptData::InjectionPoint p) + void run(QtWebEngineCore::UserScriptData::InjectionPoint p) { DCHECK_LT(p, m_ran.size()); if (!m_ran[p]) { - UserResourceController::instance()->runScripts(p, m_frame); + m_userResourceController->runScripts(p, m_frame); m_ran[p] = true; } } @@ -173,35 +187,22 @@ public: private: blink::WebLocalFrame *m_frame; std::bitset<3> m_ran; + UserResourceController *m_userResourceController; }; -// Used only for script cleanup on RenderView destruction. -class UserResourceController::RenderViewObserverHelper : public content::RenderViewObserver -{ -public: - RenderViewObserverHelper(content::RenderView *render_view); - -private: - // RenderViewObserver implementation. - void OnDestruct() override; -}; - -void UserResourceController::runScripts(UserScriptData::InjectionPoint p, blink::WebLocalFrame *frame) +void UserResourceController::runScripts(QtWebEngineCore::UserScriptData::InjectionPoint p, + blink::WebLocalFrame *frame) { content::RenderFrame *renderFrame = content::RenderFrame::FromWebFrame(frame); if (!renderFrame) return; const bool isMainFrame = renderFrame->IsMainFrame(); - content::RenderView *renderView = renderFrame->GetRenderView(); - if (!renderView) - return; - - QList<uint64_t> scriptsToRun = m_viewUserScriptMap.value(0).values(); - scriptsToRun.append(m_viewUserScriptMap.value(renderView).values()); + QList<uint64_t> scriptsToRun = m_frameUserScriptMap.value(0).values(); + scriptsToRun.append(m_frameUserScriptMap.value(renderFrame).values()); for (uint64_t id : qAsConst(scriptsToRun)) { - const UserScriptData &script = m_scripts.value(id); + const QtWebEngineCore::UserScriptData &script = m_scripts.value(id); if (script.injectionPoint != p || (!script.injectForSubframes && !isMainFrame)) continue; if (!scriptMatchesURL(script, frame->GetDocument().Url())) @@ -216,16 +217,27 @@ void UserResourceController::runScripts(UserScriptData::InjectionPoint p, blink: void UserResourceController::RunScriptsAtDocumentEnd(content::RenderFrame *render_frame) { - runScripts(UserScriptData::DocumentLoadFinished, render_frame->GetWebFrame()); + runScripts(QtWebEngineCore::UserScriptData::DocumentLoadFinished, render_frame->GetWebFrame()); } -UserResourceController::RenderFrameObserverHelper::RenderFrameObserverHelper(content::RenderFrame *render_frame) +UserResourceController::RenderFrameObserverHelper::RenderFrameObserverHelper( + content::RenderFrame *render_frame, UserResourceController *controller) : content::RenderFrameObserver(render_frame) -{} + , m_binding(this) + , m_userResourceController(controller) +{ + render_frame->GetAssociatedInterfaceRegistry()->AddInterface( + base::BindRepeating(&UserResourceController::RenderFrameObserverHelper::BindReceiver, + base::Unretained(this))); +} -UserResourceController::RenderViewObserverHelper::RenderViewObserverHelper(content::RenderView *render_view) - : content::RenderViewObserver(render_view) -{} + +void UserResourceController::RenderFrameObserverHelper::BindReceiver( + mojo::PendingAssociatedReceiver<qtwebengine::mojom::UserResourceControllerRenderFrame> + receiver) +{ + m_binding.Bind(std::move(receiver)); +} void UserResourceController::RenderFrameObserverHelper::DidCommitProvisionalLoad(bool is_same_document_navigation, ui::PageTransition /*transitionbool*/) @@ -237,10 +249,12 @@ void UserResourceController::RenderFrameObserverHelper::DidCommitProvisionalLoad // process has been notified of the DidCommitProvisionalLoad event to ensure // that the WebChannelTransportHost is ready to receive messages. - m_runner.reset(new Runner(render_frame()->GetWebFrame())); + m_runner.reset(new Runner(render_frame()->GetWebFrame(), m_userResourceController)); base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&Runner::run, m_runner->AsWeakPtr(), UserScriptData::DocumentElementCreation)); + FROM_HERE, + base::BindOnce(&Runner::run, m_runner->AsWeakPtr(), + QtWebEngineCore::UserScriptData::DocumentElementCreation)); } void UserResourceController::RenderFrameObserverHelper::DidFinishDocumentLoad() @@ -249,7 +263,9 @@ void UserResourceController::RenderFrameObserverHelper::DidFinishDocumentLoad() // called instead of DidCommitProvisionalLoad). if (m_runner) base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, base::BindOnce(&Runner::run, m_runner->AsWeakPtr(), UserScriptData::AfterLoad), + FROM_HERE, + base::BindOnce(&Runner::run, m_runner->AsWeakPtr(), + QtWebEngineCore::UserScriptData::AfterLoad), base::TimeDelta::FromMilliseconds(afterLoadTimeout)); } @@ -257,7 +273,9 @@ void UserResourceController::RenderFrameObserverHelper::DidFinishLoad() { if (m_runner) base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&Runner::run, m_runner->AsWeakPtr(), UserScriptData::AfterLoad)); + FROM_HERE, + base::BindOnce(&Runner::run, m_runner->AsWeakPtr(), + QtWebEngineCore::UserScriptData::AfterLoad)); } void UserResourceController::RenderFrameObserverHelper::FrameDetached() @@ -267,68 +285,39 @@ void UserResourceController::RenderFrameObserverHelper::FrameDetached() void UserResourceController::RenderFrameObserverHelper::OnDestruct() { + if (content::RenderFrame *frame = render_frame()) { + m_userResourceController->renderFrameDestroyed(frame); + } delete this; } -void UserResourceController::RenderViewObserverHelper::OnDestruct() -{ - // Remove all scripts associated with the render view. - if (content::RenderView *view = render_view()) - UserResourceController::instance()->renderViewDestroyed(view); - delete this; -} - -bool UserResourceController::RenderFrameObserverHelper::OnMessageReceived(const IPC::Message &message) -{ - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(UserResourceController::RenderFrameObserverHelper, message) - IPC_MESSAGE_HANDLER(RenderFrameObserverHelper_AddScript, onUserScriptAdded) - IPC_MESSAGE_HANDLER(RenderFrameObserverHelper_RemoveScript, onUserScriptRemoved) - IPC_MESSAGE_HANDLER(RenderFrameObserverHelper_ClearScripts, onScriptsCleared) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -void UserResourceController::RenderFrameObserverHelper::onUserScriptAdded(const UserScriptData &script) +void UserResourceController::RenderFrameObserverHelper::AddScript( + const QtWebEngineCore::UserScriptData &script) { if (content::RenderFrame *frame = render_frame()) - if (content::RenderView *view = frame->GetRenderView()) - UserResourceController::instance()->addScriptForView(script, view); + m_userResourceController->addScriptForFrame(script, frame); } -void UserResourceController::RenderFrameObserverHelper::onUserScriptRemoved(const UserScriptData &script) +void UserResourceController::RenderFrameObserverHelper::RemoveScript( + const QtWebEngineCore::UserScriptData &script) { if (content::RenderFrame *frame = render_frame()) - if (content::RenderView *view = frame->GetRenderView()) - UserResourceController::instance()->removeScriptForView(script, view); + m_userResourceController->removeScriptForFrame(script, frame); } -void UserResourceController::RenderFrameObserverHelper::onScriptsCleared() +void UserResourceController::RenderFrameObserverHelper::ClearScripts() { if (content::RenderFrame *frame = render_frame()) - if (content::RenderView *view = frame->GetRenderView()) - UserResourceController::instance()->clearScriptsForView(view); + m_userResourceController->clearScriptsForFrame(frame); } -UserResourceController *UserResourceController::instance() +void UserResourceController::BindReceiver( + mojo::PendingAssociatedReceiver<qtwebengine::mojom::UserResourceController> receiver) { - return qt_webengine_userResourceController(); + m_binding.Bind(std::move(receiver)); } -bool UserResourceController::OnControlMessageReceived(const IPC::Message &message) -{ - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(UserResourceController, message) - IPC_MESSAGE_HANDLER(UserResourceController_AddScript, onAddScript) - IPC_MESSAGE_HANDLER(UserResourceController_RemoveScript, onRemoveScript) - IPC_MESSAGE_HANDLER(UserResourceController_ClearScripts, onClearScripts) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -UserResourceController::UserResourceController() +UserResourceController::UserResourceController() : m_binding(this) { #if !defined(QT_NO_DEBUG) || defined(QT_FORCE_ASSERTS) static bool onlyCalledOnce = true; @@ -340,68 +329,79 @@ UserResourceController::UserResourceController() void UserResourceController::renderFrameCreated(content::RenderFrame *renderFrame) { // Will destroy itself when the RenderFrame is destroyed. - new RenderFrameObserverHelper(renderFrame); + new RenderFrameObserverHelper(renderFrame, this); } -void UserResourceController::renderViewCreated(content::RenderView *renderView) +void UserResourceController::renderFrameDestroyed(content::RenderFrame *renderFrame) { - // Will destroy itself when the RenderView is destroyed. - new RenderViewObserverHelper(renderView); -} - -void UserResourceController::renderViewDestroyed(content::RenderView *renderView) -{ - ViewUserScriptMap::iterator it = m_viewUserScriptMap.find(renderView); - if (it == m_viewUserScriptMap.end()) // ASSERT maybe? + FrameUserScriptMap::iterator it = m_frameUserScriptMap.find(renderFrame); + if (it == m_frameUserScriptMap.end()) // ASSERT maybe? return; for (uint64_t id : qAsConst(it.value())) { m_scripts.remove(id); } - m_viewUserScriptMap.remove(renderView); + m_frameUserScriptMap.remove(renderFrame); } -void UserResourceController::addScriptForView(const UserScriptData &script, content::RenderView *view) +void UserResourceController::addScriptForFrame(const QtWebEngineCore::UserScriptData &script, + content::RenderFrame *frame) { - ViewUserScriptMap::iterator it = m_viewUserScriptMap.find(view); - if (it == m_viewUserScriptMap.end()) - it = m_viewUserScriptMap.insert(view, UserScriptSet()); + FrameUserScriptMap::iterator it = m_frameUserScriptMap.find(frame); + if (it == m_frameUserScriptMap.end()) + it = m_frameUserScriptMap.insert(frame, UserScriptSet()); (*it).insert(script.scriptId); m_scripts.insert(script.scriptId, script); } -void UserResourceController::removeScriptForView(const UserScriptData &script, content::RenderView *view) +void UserResourceController::removeScriptForFrame(const QtWebEngineCore::UserScriptData &script, + content::RenderFrame *frame) { - ViewUserScriptMap::iterator it = m_viewUserScriptMap.find(view); - if (it == m_viewUserScriptMap.end()) + FrameUserScriptMap::iterator it = m_frameUserScriptMap.find(frame); + if (it == m_frameUserScriptMap.end()) return; (*it).remove(script.scriptId); m_scripts.remove(script.scriptId); } -void UserResourceController::clearScriptsForView(content::RenderView *view) +void UserResourceController::clearScriptsForFrame(content::RenderFrame *frame) { - ViewUserScriptMap::iterator it = m_viewUserScriptMap.find(view); - if (it == m_viewUserScriptMap.end()) + FrameUserScriptMap::iterator it = m_frameUserScriptMap.find(frame); + if (it == m_frameUserScriptMap.end()) return; for (uint64_t id : qAsConst(it.value())) m_scripts.remove(id); - m_viewUserScriptMap.remove(view); + m_frameUserScriptMap.remove(frame); +} + +void UserResourceController::AddScript(const QtWebEngineCore::UserScriptData &script) +{ + addScriptForFrame(script, globalScriptsIndex); } -void UserResourceController::onAddScript(const UserScriptData &script) +void UserResourceController::RemoveScript(const QtWebEngineCore::UserScriptData &script) { - addScriptForView(script, globalScriptsIndex); + removeScriptForFrame(script, globalScriptsIndex); } -void UserResourceController::onRemoveScript(const UserScriptData &script) +void UserResourceController::ClearScripts() { - removeScriptForView(script, globalScriptsIndex); + clearScriptsForFrame(globalScriptsIndex); } -void UserResourceController::onClearScripts() +void UserResourceController::RegisterMojoInterfaces( + blink::AssociatedInterfaceRegistry *associated_interfaces) { - clearScriptsForView(globalScriptsIndex); + associated_interfaces->AddInterface( + base::Bind(&UserResourceController::BindReceiver, base::Unretained(this))); } + +void UserResourceController::UnregisterMojoInterfaces( + blink::AssociatedInterfaceRegistry *associated_interfaces) +{ + associated_interfaces->RemoveInterface(qtwebengine::mojom::UserResourceController::Name_); +} + +} // namespace diff --git a/src/core/renderer/user_resource_controller.h b/src/core/renderer/user_resource_controller.h index 3a493b9b7..6c79d96fc 100644 --- a/src/core/renderer/user_resource_controller.h +++ b/src/core/renderer/user_resource_controller.h @@ -41,8 +41,9 @@ #define USER_RESOURCE_CONTROLLER_H #include "content/public/renderer/render_thread_observer.h" - -#include "common/user_script_data.h" +#include "qtwebengine/userscript/userscript.mojom.h" +#include "qtwebengine/userscript/user_script_data.h" +#include "mojo/public/cpp/bindings/associated_receiver.h" #include <QtCore/QHash> #include <QtCore/QSet> @@ -56,42 +57,46 @@ class RenderFrame; class RenderView; } -class UserResourceController : public content::RenderThreadObserver +namespace QtWebEngineCore { + +class UserResourceController : public content::RenderThreadObserver, + qtwebengine::mojom::UserResourceController { public: - static UserResourceController *instance(); UserResourceController(); void renderFrameCreated(content::RenderFrame *); - void renderViewCreated(content::RenderView *); - void renderViewDestroyed(content::RenderView *renderView); - void addScriptForView(const UserScriptData &, content::RenderView *); - void removeScriptForView(const UserScriptData &, content::RenderView *); - void clearScriptsForView(content::RenderView *); + void renderFrameDestroyed(content::RenderFrame *); + void addScriptForFrame(const QtWebEngineCore::UserScriptData &, content::RenderFrame *); + void removeScriptForFrame(const QtWebEngineCore::UserScriptData &, content::RenderFrame *); + void clearScriptsForFrame(content::RenderFrame *); void RunScriptsAtDocumentEnd(content::RenderFrame *render_frame); + void BindReceiver( + mojo::PendingAssociatedReceiver<qtwebengine::mojom::UserResourceController> receiver); private: Q_DISABLE_COPY(UserResourceController) + // content::RenderThreadObserver: + void RegisterMojoInterfaces(blink::AssociatedInterfaceRegistry *associated_interfaces) override; + void UnregisterMojoInterfaces(blink::AssociatedInterfaceRegistry *associated_interfaces) override; + class RenderFrameObserverHelper; class RenderViewObserverHelper; - // RenderProcessObserver implementation. - bool OnControlMessageReceived(const IPC::Message &message) override; + void AddScript(const QtWebEngineCore::UserScriptData &data) override; + void RemoveScript(const QtWebEngineCore::UserScriptData &data) override; + void ClearScripts() override; - void onAddScript(const UserScriptData &); - void onRemoveScript(const UserScriptData &); - void onClearScripts(); - - void runScripts(UserScriptData::InjectionPoint, blink::WebLocalFrame *); + void runScripts(QtWebEngineCore::UserScriptData::InjectionPoint, blink::WebLocalFrame *); typedef QSet<uint64_t> UserScriptSet; - typedef QHash<const content::RenderView *, UserScriptSet> ViewUserScriptMap; - ViewUserScriptMap m_viewUserScriptMap; - QHash<uint64_t, UserScriptData> m_scripts; - + typedef QHash<const content::RenderFrame *, UserScriptSet> FrameUserScriptMap; + FrameUserScriptMap m_frameUserScriptMap; + QHash<uint64_t, QtWebEngineCore::UserScriptData> m_scripts; + mojo::AssociatedReceiver<qtwebengine::mojom::UserResourceController> m_binding; friend class RenderFrameObserverHelper; }; - +} // namespace #endif // USER_RESOURCE_CONTROLLER_H diff --git a/src/core/renderer/web_channel_ipc_transport.cpp b/src/core/renderer/web_channel_ipc_transport.cpp index 496417329..1efefc1d0 100644 --- a/src/core/renderer/web_channel_ipc_transport.cpp +++ b/src/core/renderer/web_channel_ipc_transport.cpp @@ -74,7 +74,8 @@ private: // gin::WrappableBase gin::ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate *isolate) override; - + mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportHost> m_remote; + content::RenderFrame *m_renderFrame = nullptr; DISALLOW_COPY_AND_ASSIGN(WebChannelTransport); }; @@ -156,9 +157,13 @@ void WebChannelTransport::NativeQtSendMessage(gin::Arguments *args) jsonString->WriteUtf8(isolate, reinterpret_cast<char *>(json.data()), json.size(), nullptr, v8::String::REPLACE_INVALID_UTF8); - mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportHost> webChannelTransport; - renderFrame->GetRemoteAssociatedInterfaces()->GetInterface(&webChannelTransport); - webChannelTransport->DispatchWebChannelMessage(json); + if (!m_remote) { + renderFrame->GetRemoteAssociatedInterfaces()->GetInterface(&m_remote); + m_renderFrame = renderFrame; + } + DCHECK(renderFrame == m_renderFrame); + + m_remote->DispatchWebChannelMessage(json); } gin::ObjectTemplateBuilder WebChannelTransport::GetObjectTemplateBuilder(v8::Isolate *isolate) @@ -168,7 +173,10 @@ gin::ObjectTemplateBuilder WebChannelTransport::GetObjectTemplateBuilder(v8::Iso } WebChannelIPCTransport::WebChannelIPCTransport(content::RenderFrame *renderFrame) - : content::RenderFrameObserver(renderFrame), m_worldId(0), m_worldInitialized(false) + : content::RenderFrameObserver(renderFrame) + , m_worldId(0) + , m_worldInitialized(false) + , m_binding(this) { renderFrame->GetAssociatedInterfaceRegistry()->AddInterface( base::BindRepeating(&WebChannelIPCTransport::BindReceiver, base::Unretained(this))); @@ -177,7 +185,7 @@ WebChannelIPCTransport::WebChannelIPCTransport(content::RenderFrame *renderFrame void WebChannelIPCTransport::BindReceiver( mojo::PendingAssociatedReceiver<qtwebchannel::mojom::WebChannelTransportRender> receiver) { - m_receivers.Add(this, std::move(receiver)); + m_binding.Bind(std::move(receiver)); } void WebChannelIPCTransport::SetWorldId(uint32_t worldId) diff --git a/src/core/renderer/web_channel_ipc_transport.h b/src/core/renderer/web_channel_ipc_transport.h index 7c3b21eec..276167a67 100644 --- a/src/core/renderer/web_channel_ipc_transport.h +++ b/src/core/renderer/web_channel_ipc_transport.h @@ -76,7 +76,7 @@ private: bool m_worldInitialized; // True means it's currently OK to manipulate the frame's script context. bool m_canUseContext = false; - mojo::AssociatedReceiverSet<qtwebchannel::mojom::WebChannelTransportRender> m_receivers; + mojo::AssociatedReceiver<qtwebchannel::mojom::WebChannelTransportRender> m_binding; }; } // namespace diff --git a/src/core/renderer/render_view_observer_qt.cpp b/src/core/renderer/web_engine_page_render_frame.cpp index 5b0b9a77d..add1788d6 100644 --- a/src/core/renderer/render_view_observer_qt.cpp +++ b/src/core/renderer/web_engine_page_render_frame.cpp @@ -37,11 +37,11 @@ ** ****************************************************************************/ -#include "renderer/render_view_observer_qt.h" +#include "renderer/web_engine_page_render_frame.h" +#include "content/public/renderer/render_frame.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" -#include "common/qt_messages.h" - -#include "content/public/renderer/render_view.h" #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_element.h" #include "third_party/blink/public/web/web_frame.h" @@ -50,45 +50,45 @@ #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_view.h" -RenderViewObserverQt::RenderViewObserverQt(content::RenderView *render_view) : content::RenderViewObserver(render_view) -{} +namespace QtWebEngineCore { -void RenderViewObserverQt::onFetchDocumentMarkup(quint64 requestId) +WebEnginePageRenderFrame::WebEnginePageRenderFrame(content::RenderFrame *render_frame) + : content::RenderFrameObserver(render_frame), m_binding(this) { - blink::WebString markup; - if (render_view()->GetWebView()->MainFrame()->IsWebLocalFrame()) - markup = blink::WebFrameContentDumper::DumpAsMarkup( - static_cast<blink::WebLocalFrame *>(render_view()->GetWebView()->MainFrame())); - Send(new RenderViewObserverHostQt_DidFetchDocumentMarkup(routing_id(), requestId, markup.Utf16())); + render_frame->GetAssociatedInterfaceRegistry()->AddInterface( + base::BindRepeating(&WebEnginePageRenderFrame::BindReceiver, base::Unretained(this))); } -void RenderViewObserverQt::onFetchDocumentInnerText(quint64 requestId) +void WebEnginePageRenderFrame::BindReceiver( + mojo::PendingAssociatedReceiver<qtwebenginepage::mojom::WebEnginePageRenderFrame> receiver) { - blink::WebString text; - if (render_view()->GetWebView()->MainFrame()->IsWebLocalFrame()) - text = blink::WebFrameContentDumper::DumpWebViewAsText(render_view()->GetWebView(), - std::numeric_limits<std::size_t>::max()); - Send(new RenderViewObserverHostQt_DidFetchDocumentInnerText(routing_id(), requestId, text.Utf16())); + m_binding.Bind(std::move(receiver)); } -void RenderViewObserverQt::onSetBackgroundColor(quint32 color) +void WebEnginePageRenderFrame::FetchDocumentMarkup(uint64_t requestId, + FetchDocumentMarkupCallback callback) { - render_view()->GetWebView()->SetBaseBackgroundColorOverride(color); + blink::WebString markup = + blink::WebFrameContentDumper::DumpAsMarkup(render_frame()->GetWebFrame()); + std::move(callback).Run(requestId, markup.Utf8()); } -void RenderViewObserverQt::OnDestruct() +void WebEnginePageRenderFrame::FetchDocumentInnerText(uint64_t requestId, + FetchDocumentInnerTextCallback callback) { - delete this; + blink::WebString text = blink::WebFrameContentDumper::DumpWebViewAsText( + render_frame()->GetWebFrame()->View(), std::numeric_limits<std::size_t>::max()); + std::move(callback).Run(requestId, text.Utf8()); +} + +void WebEnginePageRenderFrame::SetBackgroundColor(uint32_t color) +{ + render_frame()->GetWebFrame()->View()->SetBaseBackgroundColorOverride(color); } -bool RenderViewObserverQt::OnMessageReceived(const IPC::Message &message) +void WebEnginePageRenderFrame::OnDestruct() { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(RenderViewObserverQt, message) - IPC_MESSAGE_HANDLER(RenderViewObserverQt_FetchDocumentMarkup, onFetchDocumentMarkup) - IPC_MESSAGE_HANDLER(RenderViewObserverQt_FetchDocumentInnerText, onFetchDocumentInnerText) - IPC_MESSAGE_HANDLER(RenderViewObserverQt_SetBackgroundColor, onSetBackgroundColor) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; + delete this; +} + } diff --git a/src/core/renderer/render_view_observer_qt.h b/src/core/renderer/web_engine_page_render_frame.h index 5c555b222..3fb4657c5 100644 --- a/src/core/renderer/render_view_observer_qt.h +++ b/src/core/renderer/web_engine_page_render_frame.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtWebEngine module of the Qt Toolkit. @@ -36,28 +36,40 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#ifndef RENDER_VIEW_OBSERVER_QT_H -#define RENDER_VIEW_OBSERVER_QT_H +#ifndef WEB_ENGINE_PAGE_RENDER_FRAME_H +#define WEB_ENGINE_PAGE_RENDER_FRAME_H -#include "content/public/renderer/render_view_observer.h" +#include "content/public/renderer/render_frame_observer.h" +#include "mojo/public/cpp/bindings/associated_receiver.h" +#include "qtwebengine/browser/qtwebenginepage.mojom.h" -#include <QtGlobal> +namespace content { +class RenderFrame; +} -class RenderViewObserverQt : public content::RenderViewObserver +namespace QtWebEngineCore { + +class WebEnginePageRenderFrame : private content::RenderFrameObserver, + public qtwebenginepage::mojom::WebEnginePageRenderFrame { public: - RenderViewObserverQt(content::RenderView *render_view); + WebEnginePageRenderFrame(content::RenderFrame *render_frame); + WebEnginePageRenderFrame(const WebEnginePageRenderFrame &) = delete; + WebEnginePageRenderFrame &operator=(const WebEnginePageRenderFrame &) = delete; private: - void onFetchDocumentMarkup(quint64 requestId); - void onFetchDocumentInnerText(quint64 requestId); - void onSetBackgroundColor(quint32 color); - + void FetchDocumentMarkup(uint64_t requestId, FetchDocumentMarkupCallback callback) override; + void FetchDocumentInnerText(uint64_t requestId, + FetchDocumentInnerTextCallback callback) override; + void SetBackgroundColor(uint32_t color) override; void OnDestruct() override; + void + BindReceiver(mojo::PendingAssociatedReceiver<qtwebenginepage::mojom::WebEnginePageRenderFrame> + receiver); - bool OnMessageReceived(const IPC::Message &message) override; - - DISALLOW_COPY_AND_ASSIGN(RenderViewObserverQt); +private: + mojo::AssociatedReceiver<qtwebenginepage::mojom::WebEnginePageRenderFrame> m_binding; }; +} // namespace -#endif // RENDER_VIEW_OBSERVER_QT_H +#endif // WEB_ENGINE_PAGE_RENDER_FRAME_H diff --git a/src/core/renderer_host/user_resource_controller_host.cpp b/src/core/renderer_host/user_resource_controller_host.cpp index 0c0818ba9..58559848f 100644 --- a/src/core/renderer_host/user_resource_controller_host.cpp +++ b/src/core/renderer_host/user_resource_controller_host.cpp @@ -48,6 +48,8 @@ #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" +#include "qtwebengine/userscript/userscript.mojom.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" namespace QtWebEngineCore { @@ -59,6 +61,7 @@ public: // WebContentsObserver overrides: void RenderFrameCreated(content::RenderFrameHost *renderFrameHost) override; void RenderFrameHostChanged(content::RenderFrameHost *oldHost, content::RenderFrameHost *newHost) override; + void RenderFrameDeleted(content::RenderFrameHost *render_frame_host) override; void WebContentsDestroyed() override; private: @@ -75,16 +78,25 @@ UserResourceControllerHost::WebContentsObserverHelper::WebContentsObserverHelper void UserResourceControllerHost::WebContentsObserverHelper::RenderFrameCreated(content::RenderFrameHost *renderFrameHost) { content::WebContents *contents = web_contents(); + auto &remote = m_controllerHost->GetUserResourceControllerRenderFrame(renderFrameHost); const QList<UserScript> scripts = m_controllerHost->m_perContentsScripts.value(contents); for (const UserScript &script : scripts) - renderFrameHost->Send(new RenderFrameObserverHelper_AddScript(renderFrameHost->GetRoutingID(), script.data())); + remote->AddScript(script.data()); } void UserResourceControllerHost::WebContentsObserverHelper::RenderFrameHostChanged(content::RenderFrameHost *oldHost, content::RenderFrameHost *newHost) { - if (oldHost) - oldHost->Send(new RenderFrameObserverHelper_ClearScripts(oldHost->GetRoutingID())); + if (oldHost) { + auto &remote = m_controllerHost->GetUserResourceControllerRenderFrame(oldHost); + remote->ClearScripts(); + } +} + +void UserResourceControllerHost::WebContentsObserverHelper::RenderFrameDeleted( + content::RenderFrameHost *render_frame_host) +{ + m_controllerHost->m_renderFrames.erase(render_frame_host); } void UserResourceControllerHost::WebContentsObserverHelper::WebContentsDestroyed() @@ -111,6 +123,7 @@ UserResourceControllerHost::RenderProcessObserverHelper::RenderProcessObserverHe void UserResourceControllerHost::RenderProcessObserverHelper::RenderProcessHostDestroyed(content::RenderProcessHost *renderer) { Q_ASSERT(m_controllerHost); + delete m_controllerHost->m_observedProcesses[renderer]; m_controllerHost->m_observedProcesses.remove(renderer); } @@ -121,8 +134,8 @@ void UserResourceControllerHost::addUserScript(const UserScript &script, WebCont if (isProfileWideScript) { if (!m_profileWideScripts.contains(script)) { m_profileWideScripts.append(script); - for (content::RenderProcessHost *renderer : qAsConst(m_observedProcesses)) - renderer->Send(new UserResourceController_AddScript(script.data())); + for (auto controller : m_observedProcesses.values()) + (*controller)->AddScript(script.data()); } } else { content::WebContents *contents = adapter->webContents(); @@ -139,10 +152,8 @@ void UserResourceControllerHost::addUserScript(const UserScript &script, WebCont m_perContentsScripts.insert(contents, currentScripts); } } - contents->GetRenderViewHost()->Send( - new RenderFrameObserverHelper_AddScript( - contents->GetRenderViewHost()->GetMainFrame()->GetRoutingID(), - script.data())); + GetUserResourceControllerRenderFrame(contents->GetRenderViewHost()->GetMainFrame()) + ->AddScript(script.data()); } } @@ -153,8 +164,8 @@ bool UserResourceControllerHost::removeUserScript(const UserScript &script, WebC QList<UserScript>::iterator it = std::find(m_profileWideScripts.begin(), m_profileWideScripts.end(), script); if (it == m_profileWideScripts.end()) return false; - for (content::RenderProcessHost *renderer : qAsConst(m_observedProcesses)) - renderer->Send(new UserResourceController_RemoveScript((*it).data())); + for (auto controller : m_observedProcesses.values()) + (*controller)->RemoveScript((*it).data()); m_profileWideScripts.erase(it); } else { content::WebContents *contents = adapter->webContents(); @@ -164,8 +175,8 @@ bool UserResourceControllerHost::removeUserScript(const UserScript &script, WebC QList<UserScript>::iterator it = std::find(list.begin(), list.end(), script); if (it == list.end()) return false; - contents->GetRenderViewHost()->Send( - new RenderFrameObserverHelper_RemoveScript(contents->GetMainFrame()->GetRoutingID(), (*it).data())); + GetUserResourceControllerRenderFrame(contents->GetRenderViewHost()->GetMainFrame()) + ->RemoveScript((*it).data()); list.erase(it); } return true; @@ -176,13 +187,15 @@ void UserResourceControllerHost::clearAllScripts(WebContentsAdapter *adapter) const bool isProfileWideScript = !adapter; if (isProfileWideScript) { m_profileWideScripts.clear(); - for (content::RenderProcessHost *renderer : qAsConst(m_observedProcesses)) - renderer->Send(new UserResourceController_ClearScripts); + for (auto controller : m_observedProcesses.values()) + (*controller)->ClearScripts(); } else { content::WebContents *contents = adapter->webContents(); m_perContentsScripts.remove(contents); - contents->GetRenderViewHost()->Send( - new RenderFrameObserverHelper_ClearScripts(contents->GetMainFrame()->GetRoutingID())); + mojo::AssociatedRemote<qtwebengine::mojom::UserResourceControllerRenderFrame> + userResourceController; + GetUserResourceControllerRenderFrame(contents->GetRenderViewHost()->GetMainFrame()) + ->ClearScripts(); } } @@ -197,15 +210,18 @@ void UserResourceControllerHost::reserve(WebContentsAdapter *adapter, int count) void UserResourceControllerHost::renderProcessStartedWithHost(content::RenderProcessHost *renderer) { - if (m_observedProcesses.contains(renderer)) + if (m_observedProcesses.keys().contains(renderer)) return; if (m_renderProcessObserver.isNull()) m_renderProcessObserver.reset(new RenderProcessObserverHelper(this)); renderer->AddObserver(m_renderProcessObserver.data()); - m_observedProcesses.insert(renderer); - for (const UserScript &script : qAsConst(m_profileWideScripts)) - renderer->Send(new UserResourceController_AddScript(script.data())); + auto userResourceController = new UserResourceControllerRemote; + renderer->GetChannel()->GetRemoteAssociatedInterface(userResourceController); + m_observedProcesses.insert(renderer, userResourceController); + for (const UserScript &script : qAsConst(m_profileWideScripts)) { + (*userResourceController)->AddScript(script.data()); + } } void UserResourceControllerHost::webContentsDestroyed(content::WebContents *contents) @@ -219,8 +235,26 @@ UserResourceControllerHost::UserResourceControllerHost() UserResourceControllerHost::~UserResourceControllerHost() { - for (content::RenderProcessHost *renderer : qAsConst(m_observedProcesses)) + for (content::RenderProcessHost *renderer : m_observedProcesses.keys()) { renderer->RemoveObserver(m_renderProcessObserver.data()); + delete m_observedProcesses[renderer]; + } +} + +const UserResourceControllerRenderFrameRemote & +UserResourceControllerHost::GetUserResourceControllerRenderFrame(content::RenderFrameHost *rfh) +{ + auto it = m_renderFrames.find(rfh); + if (it == m_renderFrames.end()) { + UserResourceControllerRenderFrameRemote remote; + rfh->GetRemoteAssociatedInterfaces()->GetInterface(remote.BindNewEndpointAndPassReceiver()); + it = m_renderFrames.insert(std::make_pair(rfh, std::move(remote))).first; + } else if (it->second.is_bound() && !it->second.is_connected()) { + it->second.reset(); + rfh->GetRemoteAssociatedInterfaces()->GetInterface(&it->second); + } + + return it->second; } } // namespace diff --git a/src/core/renderer_host/user_resource_controller_host.h b/src/core/renderer_host/user_resource_controller_host.h index 76954e0cc..a88264f2d 100644 --- a/src/core/renderer_host/user_resource_controller_host.h +++ b/src/core/renderer_host/user_resource_controller_host.h @@ -53,18 +53,34 @@ #include "qtwebenginecoreglobal_p.h" -#include <QtCore/QSet> +#include <QtCore/QHash> #include <QtCore/QScopedPointer> +#include <map> #include "user_script.h" namespace content { class RenderProcessHost; class WebContents; +class RenderFrameHost; +} + +namespace mojo { +template <typename Type> +class AssociatedRemote; +} + +namespace qtwebengine { +namespace mojom { +class UserResourceController; +class UserResourceControllerRenderFrame; +} } namespace QtWebEngineCore { class UserScript; +using UserResourceControllerRemote = mojo::AssociatedRemote<qtwebengine::mojom::UserResourceController>; +using UserResourceControllerRenderFrameRemote = mojo::AssociatedRemote<qtwebengine::mojom::UserResourceControllerRenderFrame>; class WebContentsAdapter; class Q_WEBENGINECORE_PRIVATE_EXPORT UserResourceControllerHost @@ -87,12 +103,15 @@ private: class RenderProcessObserverHelper; void webContentsDestroyed(content::WebContents *); + const UserResourceControllerRenderFrameRemote & + GetUserResourceControllerRenderFrame(content::RenderFrameHost *rfh); QList<UserScript> m_profileWideScripts; typedef QHash<content::WebContents *, QList<UserScript>> ContentsScriptsMap; ContentsScriptsMap m_perContentsScripts; - QSet<content::RenderProcessHost *> m_observedProcesses; + QHash<content::RenderProcessHost *, UserResourceControllerRemote *> m_observedProcesses; QScopedPointer<RenderProcessObserverHelper> m_renderProcessObserver; + std::map<content::RenderFrameHost *, UserResourceControllerRenderFrameRemote> m_renderFrames; }; } // namespace diff --git a/src/core/renderer_host/web_channel_ipc_transport_host.cpp b/src/core/renderer_host/web_channel_ipc_transport_host.cpp index 5d4356533..ca6fb895e 100644 --- a/src/core/renderer_host/web_channel_ipc_transport_host.cpp +++ b/src/core/renderer_host/web_channel_ipc_transport_host.cpp @@ -95,11 +95,9 @@ void WebChannelIPCTransportHost::sendMessage(const QJsonObject &message) QJsonDocument doc(message); QByteArray json = doc.toJson(QJsonDocument::Compact); content::RenderFrameHost *frame = web_contents()->GetMainFrame(); - mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportRender> webChannelTransport; - frame->GetRemoteAssociatedInterfaces()->GetInterface(&webChannelTransport); qCDebug(log).nospace() << "sending webchannel message to " << frame << ": " << doc; - webChannelTransport->DispatchWebChannelMessage(std::vector<uint8_t>(json.begin(), json.end()), - m_worldId); + GetWebChannelIPCTransportRemote(frame)->DispatchWebChannelMessage( + std::vector<uint8_t>(json.begin(), json.end()), m_worldId); } void WebChannelIPCTransportHost::setWorldId(uint32_t worldId) @@ -116,9 +114,7 @@ void WebChannelIPCTransportHost::setWorldId(content::RenderFrameHost *frame, uin if (!frame->IsRenderFrameLive()) return; qCDebug(log).nospace() << "sending setWorldId(" << worldId << ") message to " << frame; - mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportRender> webChannelTransport; - frame->GetRemoteAssociatedInterfaces()->GetInterface(&webChannelTransport); - webChannelTransport->SetWorldId(worldId); + GetWebChannelIPCTransportRemote(frame)->SetWorldId(worldId); } void WebChannelIPCTransportHost::resetWorldId() @@ -126,9 +122,7 @@ void WebChannelIPCTransportHost::resetWorldId() for (content::RenderFrameHost *frame : web_contents()->GetAllFrames()) { if (!frame->IsRenderFrameLive()) return; - mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportRender> webChannelTransport; - frame->GetRemoteAssociatedInterfaces()->GetInterface(&webChannelTransport); - webChannelTransport->ResetWorldId(); + GetWebChannelIPCTransportRemote(frame)->ResetWorldId(); } } @@ -157,4 +151,25 @@ void WebChannelIPCTransportHost::RenderFrameCreated(content::RenderFrameHost *fr setWorldId(frame, m_worldId); } +void WebChannelIPCTransportHost::RenderFrameDeleted(content::RenderFrameHost *rfh) +{ + m_renderFrames.erase(rfh); +} + +const mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportRender> & +WebChannelIPCTransportHost::GetWebChannelIPCTransportRemote(content::RenderFrameHost *rfh) +{ + auto it = m_renderFrames.find(rfh); + if (it == m_renderFrames.end()) { + mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportRender> remote; + rfh->GetRemoteAssociatedInterfaces()->GetInterface(remote.BindNewEndpointAndPassReceiver()); + it = m_renderFrames.insert(std::make_pair(rfh, std::move(remote))).first; + } else if (it->second.is_bound() && !it->second.is_connected()) { + it->second.reset(); + rfh->GetRemoteAssociatedInterfaces()->GetInterface(&it->second); + } + + return it->second; +} + } // namespace QtWebEngineCore diff --git a/src/core/renderer_host/web_channel_ipc_transport_host.h b/src/core/renderer_host/web_channel_ipc_transport_host.h index 3d15082b8..794238667 100644 --- a/src/core/renderer_host/web_channel_ipc_transport_host.h +++ b/src/core/renderer_host/web_channel_ipc_transport_host.h @@ -47,6 +47,7 @@ #include "qtwebengine/browser/qtwebchannel.mojom.h" #include <QWebChannelAbstractTransport> +#include <map> QT_FORWARD_DECLARE_CLASS(QString) @@ -71,8 +72,12 @@ private: void setWorldId(content::RenderFrameHost *frame, uint32_t worldId); void resetWorldId(); + const mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportRender> & + GetWebChannelIPCTransportRemote(content::RenderFrameHost *rfh); + // WebContentsObserver void RenderFrameCreated(content::RenderFrameHost *frame) override; + void RenderFrameDeleted(content::RenderFrameHost *render_frame_host) override; // qtwebchannel::mojom::WebChannelTransportHost void DispatchWebChannelMessage(const std::vector<uint8_t> &json) override; @@ -81,6 +86,9 @@ private: // WebChannelIPCTransports/RenderFrames in the observed WebContents. uint32_t m_worldId; content::WebContentsFrameReceiverSet<qtwebchannel::mojom::WebChannelTransportHost> m_receiver; + std::map<content::RenderFrameHost *, + mojo::AssociatedRemote<qtwebchannel::mojom::WebChannelTransportRender>> + m_renderFrames; }; } // namespace diff --git a/src/core/renderer_host/render_view_observer_host_qt.cpp b/src/core/renderer_host/web_engine_page_host.cpp index 165a9d86a..36907ef5a 100644 --- a/src/core/renderer_host/render_view_observer_host_qt.cpp +++ b/src/core/renderer_host/web_engine_page_host.cpp @@ -37,59 +37,76 @@ ** ****************************************************************************/ -#include "render_view_observer_host_qt.h" +#include "web_engine_page_host.h" -#include "common/qt_messages.h" -#include "content/public/browser/render_view_host.h" +#include "qtwebengine/browser/qtwebenginepage.mojom.h" #include "content/public/browser/web_contents.h" #include "render_widget_host_view_qt.h" #include "type_conversion.h" #include "web_contents_adapter_client.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" namespace QtWebEngineCore { -RenderViewObserverHostQt::RenderViewObserverHostQt(content::WebContents *webContents, WebContentsAdapterClient *adapterClient) - : content::WebContentsObserver(webContents) - , m_adapterClient(adapterClient) +WebEnginePageHost::WebEnginePageHost(content::WebContents *webContents, + WebContentsAdapterClient *adapterClient) + : content::WebContentsObserver(webContents), m_adapterClient(adapterClient) { } -void RenderViewObserverHostQt::fetchDocumentMarkup(quint64 requestId) +void WebEnginePageHost::FetchDocumentMarkup(uint64_t requestId) { - web_contents()->GetRenderViewHost()->Send( - new RenderViewObserverQt_FetchDocumentMarkup( - web_contents()->GetRenderViewHost()->GetRoutingID(), requestId)); + auto &remote = GetWebEnginePageRenderFrame(web_contents()->GetMainFrame()); + remote->FetchDocumentMarkup( + requestId, + base::BindOnce(&WebEnginePageHost::OnDidFetchDocumentMarkup, base::Unretained(this))); } -void RenderViewObserverHostQt::fetchDocumentInnerText(quint64 requestId) +void WebEnginePageHost::FetchDocumentInnerText(uint64_t requestId) { - web_contents()->GetRenderViewHost()->Send( - new RenderViewObserverQt_FetchDocumentInnerText( - web_contents()->GetRenderViewHost()->GetRoutingID(), requestId)); + auto &remote = GetWebEnginePageRenderFrame(web_contents()->GetMainFrame()); + remote->FetchDocumentInnerText(requestId, + base::BindOnce(&WebEnginePageHost::OnDidFetchDocumentInnerText, + base::Unretained(this))); } -bool RenderViewObserverHostQt::OnMessageReceived(const IPC::Message &message) +void WebEnginePageHost::OnDidFetchDocumentMarkup(uint64_t requestId, const std::string &markup) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(RenderViewObserverHostQt, message) - IPC_MESSAGE_HANDLER(RenderViewObserverHostQt_DidFetchDocumentMarkup, - onDidFetchDocumentMarkup) - IPC_MESSAGE_HANDLER(RenderViewObserverHostQt_DidFetchDocumentInnerText, - onDidFetchDocumentInnerText) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; + m_adapterClient->didFetchDocumentMarkup(requestId, toQt(markup)); } -void RenderViewObserverHostQt::onDidFetchDocumentMarkup(quint64 requestId, const base::string16 &markup) +void WebEnginePageHost::OnDidFetchDocumentInnerText(uint64_t requestId, + const std::string &innerText) { - m_adapterClient->didFetchDocumentMarkup(requestId, toQt(markup)); + m_adapterClient->didFetchDocumentInnerText(requestId, toQt(innerText)); } -void RenderViewObserverHostQt::onDidFetchDocumentInnerText(quint64 requestId, const base::string16 &innerText) +void WebEnginePageHost::RenderFrameDeleted(content::RenderFrameHost *render_frame) { - m_adapterClient->didFetchDocumentInnerText(requestId, toQt(innerText)); + m_renderFrames.erase(render_frame); +} + +void WebEnginePageHost::SetBackgroundColor(uint32_t color) +{ + auto &remote = GetWebEnginePageRenderFrame(web_contents()->GetMainFrame()); + remote->SetBackgroundColor(color); +} + +const WebEnginePageRenderFrameRemote & +WebEnginePageHost::GetWebEnginePageRenderFrame(content::RenderFrameHost *rfh) +{ + auto it = m_renderFrames.find(rfh); + if (it == m_renderFrames.end()) { + WebEnginePageRenderFrameRemote remote; + rfh->GetRemoteAssociatedInterfaces()->GetInterface(remote.BindNewEndpointAndPassReceiver()); + it = m_renderFrames.insert(std::make_pair(rfh, std::move(remote))).first; + } else if (it->second.is_bound() && !it->second.is_connected()) { + it->second.reset(); + rfh->GetRemoteAssociatedInterfaces()->GetInterface(&it->second); + } + + return it->second; } } // namespace QtWebEngineCore diff --git a/src/core/renderer_host/render_view_observer_host_qt.h b/src/core/renderer_host/web_engine_page_host.h index 8590ecbc5..f305d22ea 100644 --- a/src/core/renderer_host/render_view_observer_host_qt.h +++ b/src/core/renderer_host/web_engine_page_host.h @@ -37,8 +37,8 @@ ** ****************************************************************************/ -#ifndef RENDER_VIEW_OBSERVER_HOST_QT_H -#define RENDER_VIEW_OBSERVER_HOST_QT_H +#ifndef WEB_ENGINE_PAGE_HOST_H +#define WEB_ENGINE_PAGE_HOST_H #include "content/public/browser/web_contents_observer.h" @@ -48,25 +48,43 @@ namespace content { class WebContents; } +namespace mojo { +template<typename Type> +class AssociatedRemote; +} + +namespace qtwebenginepage { +namespace mojom { +class WebEnginePageRenderFrame; +} +} + namespace QtWebEngineCore { +using WebEnginePageRenderFrameRemote = mojo::AssociatedRemote<qtwebenginepage::mojom::WebEnginePageRenderFrame>; + class WebContentsAdapterClient; -class RenderViewObserverHostQt : public content::WebContentsObserver +class WebEnginePageHost : public content::WebContentsObserver { public: - RenderViewObserverHostQt(content::WebContents *, WebContentsAdapterClient *adapterClient); - void fetchDocumentMarkup(quint64 requestId); - void fetchDocumentInnerText(quint64 requestId); + WebEnginePageHost(content::WebContents *, WebContentsAdapterClient *adapterClient); + void FetchDocumentMarkup(uint64_t requestId); + void FetchDocumentInnerText(uint64_t requestId); + void RenderFrameDeleted(content::RenderFrameHost *render_frame) override; + void SetBackgroundColor(uint32_t color); private: - bool OnMessageReceived(const IPC::Message &message) override; - void onDidFetchDocumentMarkup(quint64 requestId, const base::string16 &markup); - void onDidFetchDocumentInnerText(quint64 requestId, const base::string16 &innerText); + void OnDidFetchDocumentMarkup(uint64_t requestId, const std::string &markup); + void OnDidFetchDocumentInnerText(uint64_t requestId, const std::string &innerText); + const WebEnginePageRenderFrameRemote & + GetWebEnginePageRenderFrame(content::RenderFrameHost *rfh); +private: WebContentsAdapterClient *m_adapterClient; + std::map<content::RenderFrameHost *, WebEnginePageRenderFrameRemote> m_renderFrames; }; } // namespace QtWebEngineCore -#endif // RENDER_VIEW_OBSERVER_HOST_QT_H +#endif // WEB_ENGINE_PAGE_HOST_H diff --git a/src/core/user_script.cpp b/src/core/user_script.cpp index f4f320d4c..c0fcd0aea 100644 --- a/src/core/user_script.cpp +++ b/src/core/user_script.cpp @@ -37,7 +37,7 @@ ** ****************************************************************************/ -#include "common/user_script_data.h" +#include "qtwebengine/userscript/user_script_data.h" #include "user_script.h" #include "type_conversion.h" @@ -72,6 +72,8 @@ ASSERT_ENUMS_MATCH(UserScript::DocumentElementCreation, UserScriptData::Document UserScript::UserScript() : QSharedData() { + static uint64_t idCount = 0; + m_scriptData.scriptId = idCount++; } UserScript::UserScript(const UserScript &other) = default; diff --git a/src/core/user_script.h b/src/core/user_script.h index 4970641e1..2be1b4ed0 100644 --- a/src/core/user_script.h +++ b/src/core/user_script.h @@ -52,16 +52,16 @@ #define USER_SCRIPT_H #include "qtwebenginecoreglobal_p.h" -#include "common/user_script_data.h" + +#include "qtwebengine/userscript/user_script_data.h" + #include <QtCore/QScopedPointer> #include <QtCore/QSharedData> #include <QtCore/QString> #include <QtCore/QUrl> -struct UserScriptData; namespace QtWebEngineCore { - class UserResourceControllerHost; class UserScript : public QSharedData diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index db2069fe7..7ba65f2bb 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -53,7 +53,7 @@ #include "profile_adapter.h" #include "profile_qt.h" #include "qwebenginecallback_p.h" -#include "renderer_host/render_view_observer_host_qt.h" +#include "renderer_host/web_engine_page_host.h" #include "render_widget_host_view_qt.h" #include "type_conversion.h" #include "web_contents_view_qt.h" @@ -96,6 +96,7 @@ #include "ui/base/clipboard/clipboard_constants.h" #include "ui/base/clipboard/custom_data_helper.h" #include "ui/gfx/font_render_params.h" +#include "qtwebengine/browser/qtwebenginepage.mojom.h" #if QT_CONFIG(webengine_webchannel) #include "renderer_host/web_channel_ipc_transport_host.h" @@ -512,7 +513,7 @@ void WebContentsAdapter::initialize(content::SiteInstance *site) // Create and attach observers to the WebContents. m_webContentsDelegate.reset(new WebContentsDelegateQt(m_webContents.get(), m_adapterClient)); - m_renderViewObserverHost.reset(new RenderViewObserverHostQt(m_webContents.get(), m_adapterClient)); + m_pageHost.reset(new WebEnginePageHost(m_webContents.get(), m_adapterClient)); // Let the WebContent's view know about the WebContentsAdapterClient. WebContentsViewQt* contentsView = static_cast<WebContentsViewQt*>(static_cast<content::WebContentsImpl*>(m_webContents.get())->GetView()); @@ -1078,14 +1079,14 @@ quint64 WebContentsAdapter::runJavaScriptCallbackResult(const QString &javaScrip quint64 WebContentsAdapter::fetchDocumentMarkup() { CHECK_INITIALIZED(0); - m_renderViewObserverHost->fetchDocumentMarkup(m_nextRequestId); + m_pageHost->FetchDocumentMarkup(m_nextRequestId); return m_nextRequestId++; } quint64 WebContentsAdapter::fetchDocumentInnerText() { CHECK_INITIALIZED(0); - m_renderViewObserverHost->fetchDocumentInnerText(m_nextRequestId); + m_pageHost->FetchDocumentInnerText(m_nextRequestId); return m_nextRequestId++; } @@ -1414,8 +1415,11 @@ void WebContentsAdapter::handlePendingMouseLockPermission() void WebContentsAdapter::setBackgroundColor(const QColor &color) { CHECK_INITIALIZED(); + SkColor c = toSk(color); if (content::RenderWidgetHostView *rwhv = m_webContents->GetRenderWidgetHostView()) - rwhv->SetBackgroundColor(toSk(color)); + rwhv->SetBackgroundColor(c); + if (color != Qt::transparent) + m_pageHost->SetBackgroundColor(c); } content::WebContents *WebContentsAdapter::webContents() const @@ -1989,14 +1993,14 @@ void WebContentsAdapter::discard() m_webChannel = nullptr; m_webChannelWorld = 0; #endif - m_renderViewObserverHost.reset(); + m_pageHost.reset(); m_webContentsDelegate.reset(); m_webContents.reset(); m_webContents = std::move(nullContents); initializeRenderPrefs(); m_webContentsDelegate = std::move(nullDelegate); - m_renderViewObserverHost.reset(new RenderViewObserverHostQt(m_webContents.get(), m_adapterClient)); + m_pageHost.reset(new WebEnginePageHost(m_webContents.get(), m_adapterClient)); WebContentsViewQt *contentsView = static_cast<WebContentsViewQt *>(static_cast<content::WebContentsImpl *>(m_webContents.get())->GetView()); contentsView->setClient(m_adapterClient); diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h index acf65f4d5..941a815c0 100644 --- a/src/core/web_contents_adapter.h +++ b/src/core/web_contents_adapter.h @@ -91,7 +91,7 @@ class FaviconManager; class FindTextHelper; class MessagePassingInterface; class ProfileQt; -class RenderViewObserverHostQt; +class WebEnginePageHost; class WebChannelIPCTransportHost; class WebEngineContext; @@ -262,7 +262,7 @@ private: ProfileAdapter *m_profileAdapter; std::unique_ptr<content::WebContents> m_webContents; std::unique_ptr<WebContentsDelegateQt> m_webContentsDelegate; - std::unique_ptr<RenderViewObserverHostQt> m_renderViewObserverHost; + std::unique_ptr<WebEnginePageHost> m_pageHost; #if QT_CONFIG(webengine_webchannel) std::unique_ptr<WebChannelIPCTransportHost> m_webChannelTransport; QWebChannel *m_webChannel; diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index 2a0484234..e2ab94610 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -380,8 +380,6 @@ void WebContentsDelegateQt::DidStartNavigation(content::NavigationHandle *naviga if (!navigation_handle->IsInMainFrame()) return; - // Error-pages are not reported as separate started navigations. - Q_ASSERT(!navigation_handle->IsErrorPage()); m_loadingErrorFrameList.clear(); m_faviconManager->resetCandidates(); @@ -390,6 +388,8 @@ void WebContentsDelegateQt::DidStartNavigation(content::NavigationHandle *naviga void WebContentsDelegateQt::EmitLoadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode, const QString &errorDescription) { + Q_ASSERT(!isErrorPage || webEngineSettings()->testAttribute(QWebEngineSettings::ErrorPageEnabled)); + // When error page enabled we don't need to send the error page load finished signal if (m_loadProgressMap[url] == 100) return; @@ -544,10 +544,8 @@ void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame m_viewClient->iconChanged(QUrl()); content::NavigationEntry *entry = web_contents()->GetController().GetActiveEntry(); - int http_statuscode = 0; - if (entry) - http_statuscode = entry->GetHttpStatusCode(); - EmitLoadFinished(true /* success */ , toQt(validated_url), false /* isErrorPage */, http_statuscode); + int http_statuscode = entry ? http_statuscode = entry->GetHttpStatusCode() : 0; + EmitLoadFinished(http_statuscode < 400, toQt(validated_url), false /* isErrorPage */, http_statuscode); } void WebContentsDelegateQt::DidUpdateFaviconURL(const std::vector<blink::mojom::FaviconURLPtr> &candidates) diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index 5c125bb8f..012a36ae7 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -698,6 +698,9 @@ WebEngineContext::WebEngineContext() // When enabled, event.movement is calculated in blink instead of in browser. appendToFeatureList(disableFeatures, features::kConsolidatedMovementXY.name); + // Avoid crashing when websites tries using this feature (since 83) + appendToFeatureList(disableFeatures, features::kInstalledApp.name); + // Explicitly tell Chromium about default-on features we do not support appendToFeatureList(disableFeatures, features::kBackgroundFetch.name); appendToFeatureList(disableFeatures, features::kSmsReceiver.name); |