From 5b865551348e695187f4d7c3bbcd77ebd8736248 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 22 Oct 2018 14:54:26 +0200 Subject: Clean-up BrowserMainPartsQt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move to a separate file and cleanup the code. Change-Id: I33d9536c7e40315b6bf271e33bdc3f838ab4b671 Reviewed-by: Jüri Valdmann --- src/core/browser_main_parts_qt.cpp | 231 +++++++++++++++++++++++++++++++++ src/core/browser_main_parts_qt.h | 80 ++++++++++++ src/core/content_browser_client_qt.cpp | 184 +------------------------- src/core/core_chromium.pri | 2 + 4 files changed, 315 insertions(+), 182 deletions(-) create mode 100644 src/core/browser_main_parts_qt.cpp create mode 100644 src/core/browser_main_parts_qt.h diff --git a/src/core/browser_main_parts_qt.cpp b/src/core/browser_main_parts_qt.cpp new file mode 100644 index 000000000..38e048470 --- /dev/null +++ b/src/core/browser_main_parts_qt.cpp @@ -0,0 +1,231 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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 "browser_main_parts_qt.h" + +#include "base/message_loop/message_loop.h" +#include "base/process/process.h" +#include "base/threading/thread_restrictions.h" +#include "content/public/browser/browser_main_parts.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/common/service_manager_connection.h" +#include "services/resource_coordinator/public/cpp/process_resource_coordinator.h" +#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h" +#include "services/service_manager/public/cpp/connector.h" +#include "services/service_manager/public/cpp/service.h" +#include "ui/display/screen.h" + +#include "service/service_qt.h" +#include "web_engine_context.h" + +#include +#include +#include +#include +#include + +#if defined(Q_OS_WIN) +#include "ui/display/win/screen_win.h" +#else +#include "desktop_screen_qt.h" +#endif + + +namespace QtWebEngineCore { + +namespace { + +// Return a timeout suitable for the glib loop, -1 to block forever, +// 0 to return right away, or a timeout in milliseconds from now. +int GetTimeIntervalMilliseconds(const base::TimeTicks &from) +{ + if (from.is_null()) + return -1; + + // Be careful here. TimeDelta has a precision of microseconds, but we want a + // value in milliseconds. If there are 5.5ms left, should the delay be 5 or + // 6? It should be 6 to avoid executing delayed work too early. + int delay = static_cast(std::ceil((from - base::TimeTicks::Now()).InMillisecondsF())); + + // If this value is negative, then we need to run delayed work soon. + return delay < 0 ? 0 : delay; +} + +class MessagePumpForUIQt : public QObject, + public base::MessagePump +{ +public: + MessagePumpForUIQt() + : m_delegate(nullptr) + , m_explicitLoop(nullptr) + , m_timerId(0) + { + } + + void Run(Delegate *delegate) override + { + if (!m_delegate) + m_delegate = delegate; + else + Q_ASSERT(delegate == m_delegate); + // This is used only when MessagePumpForUIQt is used outside of the GUI thread. + QEventLoop loop; + m_explicitLoop = &loop; + loop.exec(); + m_explicitLoop = nullptr; + } + + void Quit() override + { + Q_ASSERT(m_explicitLoop); + m_explicitLoop->quit(); + } + + void ScheduleWork() override + { + if (!m_delegate) + m_delegate = base::MessageLoopForUI::current(); + QCoreApplication::postEvent(this, new QTimerEvent(0)); + m_timerScheduledTime = base::TimeTicks::Now(); + } + + void ScheduleDelayedWork(const base::TimeTicks &delayed_work_time) override + { + if (!m_delegate) + m_delegate = base::MessageLoopForUI::current(); + if (delayed_work_time.is_null()) { + killTimer(m_timerId); + m_timerId = 0; + m_timerScheduledTime = base::TimeTicks(); + } else if (!m_timerId || delayed_work_time < m_timerScheduledTime) { + killTimer(m_timerId); + m_timerId = startTimer(GetTimeIntervalMilliseconds(delayed_work_time)); + m_timerScheduledTime = delayed_work_time; + } + } + +protected: + void timerEvent(QTimerEvent *ev) override + { + Q_ASSERT(!ev->timerId() || m_timerId == ev->timerId()); + killTimer(m_timerId); + m_timerId = 0; + m_timerScheduledTime = base::TimeTicks(); + + handleScheduledWork(); + } + +private: + void handleScheduledWork() + { + bool more_work_is_plausible = m_delegate->DoWork(); + + base::TimeTicks delayed_work_time; + more_work_is_plausible |= m_delegate->DoDelayedWork(&delayed_work_time); + + if (more_work_is_plausible) + return ScheduleWork(); + + more_work_is_plausible |= m_delegate->DoIdleWork(); + if (more_work_is_plausible) + return ScheduleWork(); + + ScheduleDelayedWork(delayed_work_time); + } + + Delegate *m_delegate; + QEventLoop *m_explicitLoop; + int m_timerId; + base::TimeTicks m_timerScheduledTime; +}; + +} // anonymous namespace + +std::unique_ptr messagePumpFactory() +{ + return base::WrapUnique(new MessagePumpForUIQt); +} + +BrowserMainPartsQt::BrowserMainPartsQt() : content::BrowserMainParts() +{ } + +BrowserMainPartsQt::~BrowserMainPartsQt() = default; + + +int BrowserMainPartsQt::PreEarlyInitialization() +{ + base::MessageLoop::InitMessagePumpForUIFactory(messagePumpFactory); + return 0; +} + +void BrowserMainPartsQt::PreMainMessageLoopStart() +{ +} + +void BrowserMainPartsQt::PostMainMessageLoopRun() +{ + // The BrowserContext's destructor uses the MessageLoop so it should be deleted + // right before the RenderProcessHostImpl's destructor destroys it. + WebEngineContext::current()->destroyBrowserContext(); +} + +int BrowserMainPartsQt::PreCreateThreads() +{ + base::ThreadRestrictions::SetIOAllowed(true); + // Like ChromeBrowserMainExtraPartsViews::PreCreateThreads does. +#if defined(Q_OS_WIN) + display::Screen::SetScreenInstance(new display::win::ScreenWin); +#else + display::Screen::SetScreenInstance(new DesktopScreenQt); +#endif + return 0; +} + +void BrowserMainPartsQt::ServiceManagerConnectionStarted(content::ServiceManagerConnection *connection) +{ + ServiceQt::GetInstance()->InitConnector(); + connection->GetConnector()->StartService(service_manager::Identity("qtwebengine")); + if (resource_coordinator::IsResourceCoordinatorEnabled()) { + m_processResourceCoordinator = std::make_unique(connection->GetConnector()); + m_processResourceCoordinator->SetLaunchTime(base::Time::Now()); + m_processResourceCoordinator->SetPID(base::Process::Current().Pid()); + } +} + +} // namespace QtWebEngineCore diff --git a/src/core/browser_main_parts_qt.h b/src/core/browser_main_parts_qt.h new file mode 100644 index 000000000..04ca9483d --- /dev/null +++ b/src/core/browser_main_parts_qt.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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 BROWSER_MAIN_PARTS_QT_H +#define BROWSER_MAIN_PARTS_QT_H + +#include "content/public/browser/browser_main_parts.h" + +namespace base { +class MessagePump; +} + +namespace content { +class ServiceManagerConnection; +} + +namespace resource_coordinator { +class ProcessResourceCoordinator; +} + +namespace QtWebEngineCore { + +std::unique_ptr messagePumpFactory(); + +class BrowserMainPartsQt : public content::BrowserMainParts +{ +public: + BrowserMainPartsQt(); + ~BrowserMainPartsQt(); + + int PreEarlyInitialization() override; + void PreMainMessageLoopStart() override; + void PostMainMessageLoopRun() override; + int PreCreateThreads() override; + void ServiceManagerConnectionStarted(content::ServiceManagerConnection *connection) override; + +private: + DISALLOW_COPY_AND_ASSIGN(BrowserMainPartsQt); + std::unique_ptr m_processResourceCoordinator; +}; + +} // namespace QtWebEngineCore + +#endif // BROWSER_MAIN_PARTS_QT_H diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp index a169576b0..0a51cc261 100644 --- a/src/core/content_browser_client_qt.cpp +++ b/src/core/content_browser_client_qt.cpp @@ -41,16 +41,13 @@ #include "base/json/json_reader.h" #include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" #include "base/strings/utf_string_conversions.h" -#include "base/threading/thread_restrictions.h" #if QT_CONFIG(webengine_spellchecker) #include "chrome/browser/spellchecker/spell_check_host_chrome_impl.h" #endif #include "components/network_hints/browser/network_hints_message_filter.h" #include "content/browser/renderer_host/render_view_host_delegate.h" #include "content/common/url_schemes.h" -#include "content/public/browser/browser_main_parts.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/client_certificate_delegate.h" @@ -73,8 +70,6 @@ #include "mojo/public/cpp/bindings/binding_set.h" #include "printing/buildflags/buildflags.h" #include "net/ssl/client_cert_identity.h" -#include "services/resource_coordinator/public/cpp/process_resource_coordinator.h" -#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h" #include "services/proxy_resolver/proxy_resolver_service.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/service.h" @@ -82,22 +77,20 @@ #include "third_party/blink/public/platform/modules/insecure_input/insecure_input_service.mojom.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/ui_base_switches.h" -#include "ui/display/screen.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_share_group.h" #include "ui/gl/gpu_timing.h" #include "url/url_util_qt.h" -#include "service/service_qt.h" #include "qtwebengine/grit/qt_webengine_resources.h" #include "profile_adapter.h" +#include "browser_main_parts_qt.h" #include "browser_message_filter_qt.h" #include "certificate_error_controller.h" #include "certificate_error_controller_p.h" #include "client_cert_select_controller.h" -#include "desktop_screen_qt.h" #include "devtools_manager_delegate_qt.h" #include "login_delegate_qt.h" #include "media_capture_devices_dispatcher.h" @@ -110,15 +103,12 @@ #include "profile_qt.h" #include "quota_permission_context_qt.h" #include "renderer_host/user_resource_controller_host.h" +#include "service/service_qt.h" #include "type_conversion.h" #include "web_contents_delegate_qt.h" #include "web_engine_context.h" #include "web_engine_library_info.h" -#if defined(Q_OS_WIN) -#include "ui/display/win/screen_win.h" -#endif - #if defined(Q_OS_LINUX) #include "global_descriptors_qt.h" #include "ui/base/resource/resource_bundle.h" @@ -159,176 +149,6 @@ QT_END_NAMESPACE namespace QtWebEngineCore { -namespace { - -// Return a timeout suitable for the glib loop, -1 to block forever, -// 0 to return right away, or a timeout in milliseconds from now. -int GetTimeIntervalMilliseconds(const base::TimeTicks& from) { - if (from.is_null()) - return -1; - - // Be careful here. TimeDelta has a precision of microseconds, but we want a - // value in milliseconds. If there are 5.5ms left, should the delay be 5 or - // 6? It should be 6 to avoid executing delayed work too early. - int delay = static_cast( - ceil((from - base::TimeTicks::Now()).InMillisecondsF())); - - // If this value is negative, then we need to run delayed work soon. - return delay < 0 ? 0 : delay; -} - -class MessagePumpForUIQt : public QObject, - public base::MessagePump -{ -public: - MessagePumpForUIQt() - : m_delegate(nullptr) - , m_explicitLoop(0) - , m_timerId(0) - { - } - - void Run(Delegate *delegate) override - { - if (!m_delegate) - m_delegate = delegate; - else - Q_ASSERT(delegate == m_delegate); - // This is used only when MessagePumpForUIQt is used outside of the GUI thread. - QEventLoop loop; - m_explicitLoop = &loop; - loop.exec(); - m_explicitLoop = 0; - } - - void Quit() override - { - Q_ASSERT(m_explicitLoop); - m_explicitLoop->quit(); - } - - void ScheduleWork() override - { - if (!m_delegate) - m_delegate = base::MessageLoopForUI::current(); - QCoreApplication::postEvent(this, new QEvent(QEvent::User)); - } - - void ScheduleDelayedWork(const base::TimeTicks &delayed_work_time) override - { - if (!m_delegate) - m_delegate = base::MessageLoopForUI::current(); - if (delayed_work_time.is_null()) { - killTimer(m_timerId); - m_timerId = 0; - m_timerScheduledTime = base::TimeTicks(); - } else if (!m_timerId || delayed_work_time < m_timerScheduledTime) { - killTimer(m_timerId); - m_timerId = startTimer(GetTimeIntervalMilliseconds(delayed_work_time)); - m_timerScheduledTime = delayed_work_time; - } - } - -protected: - void customEvent(QEvent *ev) override - { - if (handleScheduledWork()) - QCoreApplication::postEvent(this, new QEvent(QEvent::User)); - } - - void timerEvent(QTimerEvent *ev) override - { - Q_ASSERT(m_timerId == ev->timerId()); - killTimer(m_timerId); - m_timerId = 0; - m_timerScheduledTime = base::TimeTicks(); - - base::TimeTicks next_delayed_work_time; - m_delegate->DoDelayedWork(&next_delayed_work_time); - ScheduleDelayedWork(next_delayed_work_time); - } - -private: - bool handleScheduledWork() { - bool more_work_is_plausible = m_delegate->DoWork(); - - base::TimeTicks delayed_work_time; - more_work_is_plausible |= m_delegate->DoDelayedWork(&delayed_work_time); - - if (more_work_is_plausible) - return true; - - more_work_is_plausible |= m_delegate->DoIdleWork(); - if (!more_work_is_plausible) - ScheduleDelayedWork(delayed_work_time); - - return more_work_is_plausible; - } - - Delegate *m_delegate; - QEventLoop *m_explicitLoop; - int m_timerId; - base::TimeTicks m_timerScheduledTime; -}; - -std::unique_ptr messagePumpFactory() -{ - return base::WrapUnique(new MessagePumpForUIQt); -} - -} // anonymous namespace - -class BrowserMainPartsQt : public content::BrowserMainParts -{ -public: - BrowserMainPartsQt() - : content::BrowserMainParts() - { } - - int PreEarlyInitialization() override - { - base::MessageLoop::InitMessagePumpForUIFactory(messagePumpFactory); - return 0; - } - - void PreMainMessageLoopStart() override - { - } - - void PostMainMessageLoopRun() override - { - // The BrowserContext's destructor uses the MessageLoop so it should be deleted - // right before the RenderProcessHostImpl's destructor destroys it. - WebEngineContext::current()->destroyBrowserContext(); - } - - int PreCreateThreads() override - { - base::ThreadRestrictions::SetIOAllowed(true); - // Like ChromeBrowserMainExtraPartsViews::PreCreateThreads does. -#if defined(Q_OS_WIN) - display::Screen::SetScreenInstance(new display::win::ScreenWin); -#else - display::Screen::SetScreenInstance(new DesktopScreenQt); -#endif - return 0; - } - void ServiceManagerConnectionStarted(content::ServiceManagerConnection *connection) override - { - ServiceQt::GetInstance()->InitConnector(); - connection->GetConnector()->StartService(service_manager::Identity("qtwebengine")); - if (resource_coordinator::IsResourceCoordinatorEnabled()) { - m_processResourceCoordinator = std::make_unique(connection->GetConnector()); - m_processResourceCoordinator->SetLaunchTime(base::Time::Now()); - m_processResourceCoordinator->SetPID(base::Process::Current().Pid()); - } - } - -private: - DISALLOW_COPY_AND_ASSIGN(BrowserMainPartsQt); - std::unique_ptr m_processResourceCoordinator; -}; - class QtShareGLContext : public gl::GLContext { public: QtShareGLContext(QOpenGLContext *qtContext) diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri index b4d1f2b8e..ae529d86a 100644 --- a/src/core/core_chromium.pri +++ b/src/core/core_chromium.pri @@ -43,6 +43,7 @@ SOURCES = \ browser_accessibility_manager_qt.cpp \ browser_accessibility_qt.cpp \ browsing_data_remover_delegate_qt.cpp \ + browser_main_parts_qt.cpp \ browser_message_filter_qt.cpp \ certificate_error_controller.cpp \ chromium_gpu_helper.cpp \ @@ -131,6 +132,7 @@ HEADERS = \ browser_accessibility_manager_qt.h \ browser_accessibility_qt.h \ browsing_data_remover_delegate_qt.h \ + browser_main_parts_qt.h \ browser_message_filter_qt.h \ certificate_error_controller_p.h \ certificate_error_controller.h \ -- cgit v1.2.3