diff options
Diffstat (limited to 'src/core/web_contents_adapter.cpp')
-rw-r--r-- | src/core/web_contents_adapter.cpp | 663 |
1 files changed, 365 insertions, 298 deletions
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index ef482ef08..7ffeaaa5b 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only // Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -43,17 +7,19 @@ #include "web_contents_adapter.h" +#include "autofill_client_qt.h" +#include "content_browser_client_qt.h" #include "devtools_frontend_qt.h" #include "download_manager_delegate_qt.h" +#include "favicon_driver_qt.h" +#include "favicon_service_factory_qt.h" +#include "find_text_helper.h" #include "media_capture_devices_dispatcher.h" -#if QT_CONFIG(webengine_printing_and_pdf) -#include "printing/print_view_manager_qt.h" -#endif -#include "profile_adapter_client.h" +#include "pdf_util_qt.h" #include "profile_adapter.h" #include "profile_qt.h" -#include "qwebenginecallback_p.h" -#include "renderer_host/render_view_observer_host_qt.h" +#include "qwebengineloadinginfo.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" @@ -61,39 +27,62 @@ #include "web_engine_settings.h" #include "base/command_line.h" -#include "base/run_loop.h" -#include "base/task/post_task.h" +#include "base/metrics/user_metrics.h" +#include "base/task/current_thread.h" #include "base/task/sequence_manager/sequence_manager_impl.h" #include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h" #include "base/values.h" +#include "chrome/browser/tab_contents/form_interaction_tab_helper.h" +#include "components/autofill/core/browser/autofill_manager.h" +#include "components/autofill/content/browser/content_autofill_driver_factory.h" +#include "components/embedder_support/user_agent_utils.h" +#include "components/favicon/core/favicon_service.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/renderer_host/text_input_manager.h" #include "content/browser/web_contents/web_contents_impl.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/download_manager.h" #include "content/public/browser/download_request_utils.h" #include "content/public/browser/host_zoom_map.h" #include "content/public/browser/navigation_entry.h" +#include "content/public/browser/navigation_entry_restore_context.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/favicon_status.h" -#include "content/public/common/content_constants.h" #include "content/public/common/content_switches.h" #include "content/public/common/drop_data.h" -#include "content/public/common/page_state.h" -#include "content/public/common/page_zoom.h" #include "content/public/common/url_constants.h" -#include "content/public/common/web_preferences.h" #include "extensions/buildflags/buildflags.h" -#include "third_party/blink/public/common/media/media_player_action.h" #include "third_party/blink/public/common/page/page_zoom.h" +#include "third_party/blink/public/common/page_state/page_state.h" #include "third_party/blink/public/common/peerconnection/webrtc_ip_handling_policy.h" -#include "printing/buildflags/buildflags.h" -#include "ui/base/clipboard/clipboard.h" +#include "third_party/blink/public/common/web_preferences/web_preferences.h" +#include "third_party/blink/public/mojom/frame/media_player_action.mojom.h" #include "ui/base/clipboard/clipboard_constants.h" #include "ui/base/clipboard/custom_data_helper.h" #include "ui/gfx/font_render_params.h" +#include "ui/native_theme/native_theme.h" +#include "qtwebengine/browser/qtwebenginepage.mojom.h" + +#include <QtCore/QVariant> +#include <QtCore/QElapsedTimer> +#include <QtCore/QMimeData> +#include <QtCore/QTemporaryDir> +#include <QtGui/QDrag> +#include <QtGui/QDragEnterEvent> +#include <QtGui/QGuiApplication> +#include <QtGui/QPageLayout> +#include <QtGui/QPixmap> +#include <QtGui/QStyleHints> + +#if QT_CONFIG(accessibility) +#include "browser_accessibility_qt.h" +#include "content/browser/accessibility/browser_accessibility_manager.h" +#include <QtGui/qaccessible.h> +#endif + +#if QT_CONFIG(webengine_printing_and_pdf) +#include "printing/print_view_manager_qt.h" +#endif #if QT_CONFIG(webengine_webchannel) #include "renderer_host/web_channel_ipc_transport_host.h" @@ -104,38 +93,18 @@ #include "extensions/extension_web_contents_observer_qt.h" #endif -#include <QDir> -#include <QGuiApplication> -#include <QPageLayout> -#include <QStringList> -#include <QStyleHints> -#include <QTimer> -#include <QVariant> -#include <QtCore/qelapsedtimer.h> -#include <QtCore/qmimedata.h> -#include <QtCore/qtemporarydir.h> -#include <QtGui/qdrag.h> -#include <QtGui/qpixmap.h> - -// Can't include headers as qaccessible.h conflicts with Chromium headers. -namespace content { -extern QAccessibleInterface *toQAccessibleInterface(BrowserAccessibility *acc); -} - namespace QtWebEngineCore { #define CHECK_INITIALIZED(return_value) \ if (!isInitialized()) \ return return_value -#define CHECK_VALID_RENDER_WIDGET_HOST_VIEW(render_view_host) \ - if (!render_view_host->IsRenderViewLive() && render_view_host->GetWidget()->GetView()) { \ +#define CHECK_VALID_RENDER_WIDGET_HOST_VIEW(render_frame_host) \ + if (!render_frame_host->IsRenderFrameLive() && render_frame_host->GetView()) { \ LOG(WARNING) << "Ignore navigation due to terminated render process with invalid RenderWidgetHostView."; \ return; \ } -static const int kTestWindowWidth = 800; -static const int kTestWindowHeight = 600; static const int kHistoryStreamVersion = 4; static QVariant fromJSValue(const base::Value *result) @@ -146,57 +115,48 @@ static QVariant fromJSValue(const base::Value *result) break; case base::Value::Type::BOOLEAN: { - bool out; - if (result->GetAsBoolean(&out)) - ret.setValue(out); + if (auto out = result->GetIfBool()) + ret.setValue(*out); break; } case base::Value::Type::INTEGER: { - int out; - if (result->GetAsInteger(&out)) - ret.setValue(out); + if (auto out = result->GetIfInt()) + ret.setValue(*out); break; } case base::Value::Type::DOUBLE: { - double out; - if (result->GetAsDouble(&out)) - ret.setValue(out); + if (auto out = result->GetIfDouble()) + ret.setValue(*out); break; } case base::Value::Type::STRING: { - base::string16 out; - if (result->GetAsString(&out)) - ret.setValue(toQt(out)); + if (auto out = result->GetIfString()) + ret.setValue(toQt(*out)); break; } case base::Value::Type::LIST: { - const base::ListValue *out; - if (result->GetAsList(&out)) { + if (const auto out = result->GetIfList()) { + size_t size = out->size(); QVariantList list; - list.reserve(out->GetSize()); - for (size_t i = 0; i < out->GetSize(); ++i) { - const base::Value *outVal = 0; - if (out->Get(i, &outVal) && outVal) - list.insert(i, fromJSValue(outVal)); + list.reserve(size); + for (size_t i = 0; i < size; ++i) { + auto &outVal = (*out)[i]; + list.insert(i, fromJSValue(&outVal)); } ret.setValue(list); } break; } - case base::Value::Type::DICTIONARY: + case base::Value::Type::DICT: { - const base::DictionaryValue *out; - if (result->GetAsDictionary(&out)) { + if (const auto dict = result->GetIfDict()) { QVariantMap map; - base::DictionaryValue::Iterator it(*out); - while (!it.IsAtEnd()) { - map.insert(toQt(it.key()), fromJSValue(&it.value())); - it.Advance(); - } + for (const auto pair : *dict) + map.insert(toQt(pair.first), fromJSValue(&pair.second)); ret.setValue(map); } break; @@ -240,7 +200,6 @@ static void callbackOnPdfSavingFinished(WebContentsAdapterClient *adapterClient, static std::unique_ptr<content::WebContents> createBlankWebContents(WebContentsAdapterClient *adapterClient, content::BrowserContext *browserContext) { content::WebContents::CreateParams create_params(browserContext, nullptr); - create_params.routing_id = MSG_ROUTING_NONE; create_params.initially_hidden = true; std::unique_ptr<content::WebContents> webContents = content::WebContents::Create(create_params); @@ -250,10 +209,28 @@ static std::unique_ptr<content::WebContents> createBlankWebContents(WebContentsA return webContents; } +static int navigationListSize(content::NavigationController &controller) { + // If we're currently on the initial NavigationEntry, no navigation has + // committed, so the initial NavigationEntry should not be part of the + // "Navigation List", and we should return 0 as the navigation list size. + if (controller.GetLastCommittedEntry()->IsInitialEntry()) + return 0; + return controller.GetEntryCount(); +} + +static int navigationListCurrentIndex(content::NavigationController &controller) { + // If we're currently on the initial NavigationEntry, no navigation has + // committed, so the initial NavigationEntry should not be part of the + // "Navigation List", and we should return -1 as the current index. + if (controller.GetLastCommittedEntry()->IsInitialEntry()) + return -1; + return controller.GetCurrentEntryIndex(); +} + static void serializeNavigationHistory(content::NavigationController &controller, QDataStream &output) { - const int currentIndex = controller.GetCurrentEntryIndex(); - const int count = controller.GetEntryCount(); + const int currentIndex = navigationListCurrentIndex(controller); + const int count = navigationListSize(controller); const int pendingIndex = controller.GetPendingEntryIndex(); output << kHistoryStreamVersion; @@ -302,6 +279,8 @@ static void deserializeNavigationHistory(QDataStream &input, int *currentIndex, int count; input >> count >> *currentIndex; + std::unique_ptr<content::NavigationEntryRestoreContext> context = content::NavigationEntryRestoreContext::Create(); + entries->reserve(count); // Logic taken from SerializedNavigationEntry::ReadFromPickle and ToNavigationEntries. for (int i = 0; i < count; ++i) { @@ -341,7 +320,8 @@ static void deserializeNavigationHistory(QDataStream &input, int *currentIndex, std::unique_ptr<content::NavigationEntry> entry = content::NavigationController::CreateNavigationEntry( toGurl(virtualUrl), content::Referrer(toGurl(referrerUrl), static_cast<network::mojom::ReferrerPolicy>(referrerPolicy)), - base::nullopt, // optional initiator_origin + absl::nullopt, // optional initiator_origin + absl::nullopt, // optional initiator_base_url // Use a transition type of reload so that we don't incorrectly // increase the typed count. ui::PAGE_TRANSITION_RELOAD, @@ -352,7 +332,7 @@ static void deserializeNavigationHistory(QDataStream &input, int *currentIndex, nullptr); entry->SetTitle(toString16(title)); - entry->SetPageState(content::PageState::CreateFromEncodedData(std::string(pageState.data(), pageState.size()))); + entry->SetPageState(blink::PageState::CreateFromEncodedData(std::string(pageState.data(), pageState.size())), context.get()); entry->SetHasPostData(hasPostData); entry->SetOriginalRequestURL(toGurl(originalRequestUrl)); entry->SetIsOverridingUserAgent(isOverridingUserAgent); @@ -370,15 +350,18 @@ static void deserializeNavigationHistory(QDataStream &input, int *currentIndex, } } -static void Navigate(WebContentsAdapter *adapter, const content::NavigationController::LoadURLParams ¶ms) +namespace { + +void Navigate(WebContentsAdapter *adapter, const content::NavigationController::LoadURLParams ¶ms) { Q_ASSERT(adapter); adapter->webContents()->GetController().LoadURLWithParams(params); adapter->focusIfNecessary(); adapter->resetSelection(); + adapter->findTextHelper()->stopFinding(); } -static void NavigateTask(QWeakPointer<WebContentsAdapter> weakAdapter, const content::NavigationController::LoadURLParams ¶ms) +void NavigateTask(QWeakPointer<WebContentsAdapter> weakAdapter, const content::NavigationController::LoadURLParams ¶ms) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); const auto adapter = weakAdapter.toStrongRef(); @@ -387,7 +370,6 @@ static void NavigateTask(QWeakPointer<WebContentsAdapter> weakAdapter, const con Navigate(adapter.get(), params); } -namespace { static QList<WebContentsAdapter *> recursive_guard_loading_adapters; class LoadRecursionGuard { @@ -423,52 +405,30 @@ QSharedPointer<WebContentsAdapter> WebContentsAdapter::createFromSerializedNavig // Unlike WebCore, Chromium only supports Restoring to a new WebContents instance. std::unique_ptr<content::WebContents> newWebContents = createBlankWebContents(adapterClient, adapterClient->profileAdapter()->profile()); content::NavigationController &controller = newWebContents->GetController(); - controller.Restore(currentIndex, content::RestoreType::LAST_SESSION_EXITED_CLEANLY, &entries); - - if (controller.GetActiveEntry()) { - // Set up the file access rights for the selected navigation entry. - // TODO(joth): This is duplicated from chrome/.../session_restore.cc and - // should be shared e.g. in NavigationController. http://crbug.com/68222 - const int id = newWebContents->GetMainFrame()->GetProcess()->GetID(); - const content::PageState& pageState = controller.GetActiveEntry()->GetPageState(); - const std::vector<base::FilePath>& filePaths = pageState.GetReferencedFiles(); - for (std::vector<base::FilePath>::const_iterator file = filePaths.begin(); file != filePaths.end(); ++file) - content::ChildProcessSecurityPolicy::GetInstance()->GrantReadFile(id, *file); - } + controller.Restore(currentIndex, content::RestoreType::kRestored, &entries); return QSharedPointer<WebContentsAdapter>::create(std::move(newWebContents)); } -WebContentsAdapter::WebContentsAdapter() +WebContentsAdapter::WebContentsAdapter(std::unique_ptr<content::WebContents> webContents) : m_profileAdapter(nullptr) - , m_webContents(nullptr) + , m_webContents(std::move(webContents)) #if QT_CONFIG(webengine_webchannel) , m_webChannel(nullptr) , m_webChannelWorld(0) #endif , m_adapterClient(nullptr) - , m_nextRequestId(CallbackDirectory::ReservedCallbackIdsEnd) - , m_currentDropAction(blink::kWebDragOperationNone) + , m_nextRequestId(1) + , m_currentDropAction(blink::kDragOperationNone) , m_devToolsFrontend(nullptr) { // This has to be the first thing we create, and the last we destroy. WebEngineContext::current(); } -WebContentsAdapter::WebContentsAdapter(std::unique_ptr<content::WebContents> webContents) - : m_profileAdapter(nullptr) - , m_webContents(std::move(webContents)) -#if QT_CONFIG(webengine_webchannel) - , m_webChannel(nullptr) - , m_webChannelWorld(0) -#endif - , m_adapterClient(nullptr) - , m_nextRequestId(CallbackDirectory::ReservedCallbackIdsEnd) - , m_currentDropAction(blink::kWebDragOperationNone) - , m_devToolsFrontend(nullptr) +WebContentsAdapter::WebContentsAdapter() + : WebContentsAdapter(nullptr) { - // This has to be the first thing we create, and the last we destroy. - WebEngineContext::current(); } WebContentsAdapter::~WebContentsAdapter() @@ -486,7 +446,7 @@ void WebContentsAdapter::setClient(WebContentsAdapterClient *adapterClient) Q_ASSERT(m_profileAdapter); // This might replace any adapter that has been initialized with this WebEngineSettings. - adapterClient->webEngineSettings()->setWebContentsAdapter(this); + WebEngineSettings::get(adapterClient->webEngineSettings())->setWebContentsAdapter(this); } bool WebContentsAdapter::isInitialized() const @@ -494,6 +454,10 @@ bool WebContentsAdapter::isInitialized() const return (bool)m_webContentsDelegate; } +ui::NativeTheme::PreferredColorScheme toWeb(Qt::ColorScheme colorScheme) { + return colorScheme == Qt::ColorScheme::Dark ? ui::NativeTheme::PreferredColorScheme::kDark : ui::NativeTheme::PreferredColorScheme::kLight; +} + void WebContentsAdapter::initialize(content::SiteInstance *site) { Q_ASSERT(m_adapterClient); @@ -510,7 +474,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()); @@ -526,6 +490,12 @@ void WebContentsAdapter::initialize(content::SiteInstance *site) extensions::ExtensionWebContentsObserverQt::CreateForWebContents(webContents()); #endif + content::BrowserContext *context = webContents()->GetBrowserContext(); + FaviconDriverQt::CreateForWebContents( + webContents(), FaviconServiceFactoryQt::GetForBrowserContext(context), m_adapterClient); + + AutofillClientQt::CreateForWebContents(webContents()); + // Create an instance of WebEngineVisitedLinksManager to catch the first // content::NOTIFICATION_RENDERER_PROCESS_CREATED event. This event will // force to initialize visited links in VisitedLinkSlave. @@ -535,24 +505,32 @@ void WebContentsAdapter::initialize(content::SiteInstance *site) // Create a RenderView with the initial empty document content::RenderViewHost *rvh = m_webContents->GetRenderViewHost(); Q_ASSERT(rvh); - if (!rvh->IsRenderViewLive()) - static_cast<content::WebContentsImpl*>(m_webContents.get())->CreateRenderViewForRenderManager(rvh, MSG_ROUTING_NONE, MSG_ROUTING_NONE, base::UnguessableToken::Create(), content::FrameReplicationState()); + if (!m_webContents->GetPrimaryMainFrame()->IsRenderFrameLive()) + static_cast<content::WebContentsImpl*>(m_webContents.get())->CreateRenderViewForRenderManager( + rvh, absl::nullopt, nullptr); m_webContentsDelegate->RenderViewHostChanged(nullptr, rvh); + // Make sure the system theme's light/dark mode is propagated to webpages + QObject::connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged, [](Qt::ColorScheme colorScheme){ + ui::NativeTheme::GetInstanceForWeb()->set_preferred_color_scheme(toWeb(colorScheme)); + }); + ui::NativeTheme::GetInstanceForWeb()->set_preferred_color_scheme(toWeb(QGuiApplication::styleHints()->colorScheme())); + m_adapterClient->initializationFinished(); } void WebContentsAdapter::initializeRenderPrefs() { - blink::mojom::RendererPreferences *rendererPrefs = m_webContents->GetMutableRendererPrefs(); + blink::RendererPreferences *rendererPrefs = m_webContents->GetMutableRendererPrefs(); rendererPrefs->use_custom_colors = true; // Qt returns a flash time (the whole cycle) in ms, chromium expects just the interval in // seconds const int qtCursorFlashTime = QGuiApplication::styleHints()->cursorFlashTime(); rendererPrefs->caret_blink_interval = - base::TimeDelta::FromMillisecondsD(0.5 * static_cast<double>(qtCursorFlashTime)); - rendererPrefs->user_agent_override = m_profileAdapter->httpUserAgent().toStdString(); + base::Milliseconds(0.5 * static_cast<double>(qtCursorFlashTime)); + rendererPrefs->user_agent_override = blink::UserAgentOverride::UserAgentOnly(m_profileAdapter->httpUserAgent().toStdString()); + rendererPrefs->user_agent_override.ua_metadata_override = profile()->userAgentMetadata(); rendererPrefs->accept_languages = m_profileAdapter->httpAcceptLanguageWithoutQualities().toStdString(); #if QT_CONFIG(webengine_webrtc) base::CommandLine* commandLine = base::CommandLine::ForCurrentProcess(); @@ -561,10 +539,13 @@ void WebContentsAdapter::initializeRenderPrefs() commandLine->GetSwitchValueASCII(switches::kForceWebRtcIPHandlingPolicy); else rendererPrefs->webrtc_ip_handling_policy = - m_adapterClient->webEngineSettings()->testAttribute(WebEngineSettings::WebRTCPublicInterfacesOnly) + m_adapterClient->webEngineSettings()->testAttribute( + QWebEngineSettings::WebRTCPublicInterfacesOnly) ? blink::kWebRTCIPHandlingDefaultPublicInterfaceOnly : blink::kWebRTCIPHandlingDefault; #endif + rendererPrefs->can_accept_load_drops = m_adapterClient->webEngineSettings()->testAttribute(QWebEngineSettings::NavigateOnDropEnabled); + // Set web-contents font settings to the default font settings as Chromium constantly overrides // the global font defaults with the font settings of the latest web-contents created. static const gfx::FontRenderParams params = gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr); @@ -598,8 +579,9 @@ bool WebContentsAdapter::canGoToOffset(int offset) const void WebContentsAdapter::stop() { CHECK_INITIALIZED(); - content::NavigationController& controller = m_webContents->GetController(); + base::RecordAction(base::UserMetricsAction("Stop")); + content::NavigationController& controller = m_webContents->GetController(); int index = controller.GetPendingEntryIndex(); if (index != -1) controller.RemoveEntryAtIndex(index); @@ -611,10 +593,12 @@ void WebContentsAdapter::stop() void WebContentsAdapter::reload() { CHECK_INITIALIZED(); + base::RecordAction(base::UserMetricsAction("Reload")); + bool wasDiscarded = (m_lifecycleState == LifecycleState::Discarded); setLifecycleState(LifecycleState::Active); - CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost()); - WebEngineSettings *settings = m_adapterClient->webEngineSettings(); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame()); + WebEngineSettings *settings = WebEngineSettings::get(m_adapterClient->webEngineSettings()); settings->doApply(); if (!wasDiscarded) // undiscard() already triggers a reload m_webContents->GetController().Reload(content::ReloadType::NORMAL, /*checkRepost = */false); @@ -624,10 +608,12 @@ void WebContentsAdapter::reload() void WebContentsAdapter::reloadAndBypassCache() { CHECK_INITIALIZED(); + base::RecordAction(base::UserMetricsAction("ReloadBypassingCache")); + bool wasDiscarded = (m_lifecycleState == LifecycleState::Discarded); setLifecycleState(LifecycleState::Active); - CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost()); - WebEngineSettings *settings = m_adapterClient->webEngineSettings(); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame()); + WebEngineSettings *settings = WebEngineSettings::get(m_adapterClient->webEngineSettings()); settings->doApply(); if (!wasDiscarded) // undiscard() already triggers a reload m_webContents->GetController().Reload(content::ReloadType::BYPASSING_CACHE, /*checkRepost = */false); @@ -648,6 +634,7 @@ void WebContentsAdapter::load(const QUrl &url) void WebContentsAdapter::load(const QWebEngineHttpRequest &request) { + base::RecordAction(base::UserMetricsAction("LoadURL")); GURL gurl = toGurl(request.url()); if (!isInitialized()) { scoped_refptr<content::SiteInstance> site = @@ -657,10 +644,9 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request) setLifecycleState(LifecycleState::Active); } - CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost()); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame()); - WebEngineSettings *settings = m_adapterClient->webEngineSettings(); - settings->doApply(); + WebEngineSettings::get(m_adapterClient->webEngineSettings())->doApply(); // The situation can occur when relying on the editingFinished signal in QML to set the url // of the WebView. @@ -701,10 +687,11 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request) params.load_type = content::NavigationController::LOAD_TYPE_HTTP_POST; // chromium accepts LOAD_TYPE_HTTP_POST only for the HTTP and HTTPS protocols if (!params.url.SchemeIsHTTPOrHTTPS()) { - m_adapterClient->loadFinished(false, request.url(), false, - net::ERR_DISALLOWED_URL_SCHEME, - QCoreApplication::translate("WebContentsAdapter", - "HTTP-POST data can only be sent over HTTP(S) protocol")); + m_adapterClient->loadFinished(QWebEngineLoadingInfo( + request.url(), QWebEngineLoadingInfo::LoadFailedStatus, false, + QCoreApplication::translate("WebContentsAdapter", + "HTTP-POST data can only be sent over HTTP(S) protocol"), + net::ERR_DISALLOWED_URL_SCHEME)); return; } params.post_data = network::ResourceRequestBody::CreateFromBytes( @@ -714,8 +701,8 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request) } // convert the custom headers into the format that chromium expects - QVector<QByteArray> headers = request.headers(); - for (QVector<QByteArray>::const_iterator it = headers.cbegin(); it != headers.cend(); ++it) { + QList<QByteArray> headers = request.headers(); + for (QList<QByteArray>::const_iterator it = headers.cbegin(); it != headers.cend(); ++it) { if (params.extra_headers.length() > 0) params.extra_headers += '\n'; params.extra_headers += (*it).toStdString() + ": " + request.header(*it).toStdString(); @@ -731,7 +718,7 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request) if (resizeNeeded) { // Schedule navigation on the event loop. - base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(&NavigateTask, sharedFromThis().toWeakRef(), std::move(params))); } else { Navigate(this, params); @@ -745,10 +732,9 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT else setLifecycleState(LifecycleState::Active); - CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost()); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame()); - WebEngineSettings *settings = m_adapterClient->webEngineSettings(); - settings->doApply(); + WebEngineSettings::get(m_adapterClient->webEngineSettings())->doApply(); QByteArray encodedData = data.toPercentEncoding(); std::string urlString; @@ -760,7 +746,8 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT GURL dataUrlToLoad(urlString); if (dataUrlToLoad.spec().size() > url::kMaxURLChars) { - m_adapterClient->loadFinished(false, baseUrl, false, net::ERR_ABORTED); + m_adapterClient->loadFinished(QWebEngineLoadingInfo(baseUrl, QWebEngineLoadingInfo::LoadFailedStatus, + false, QString(), net::ERR_ABORTED)); return; } content::NavigationController::LoadURLParams params((dataUrlToLoad)); @@ -776,7 +763,8 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT void WebContentsAdapter::save(const QString &filePath, int savePageFormat) { CHECK_INITIALIZED(); - m_webContentsDelegate->setSavePageInfo(SavePageInfo(filePath, savePageFormat)); + base::RecordAction(base::UserMetricsAction("SavePage")); + m_webContentsDelegate->setSavePageInfo(new SavePageInfo(filePath, savePageFormat)); m_webContents->OnSavePage(); } @@ -805,12 +793,15 @@ QUrl WebContentsAdapter::requestedUrl() const QUrl WebContentsAdapter::iconUrl() const { CHECK_INITIALIZED(QUrl()); - if (content::NavigationEntry* entry = m_webContents->GetController().GetVisibleEntry()) { - content::FaviconStatus &favicon = entry->GetFavicon(); - if (favicon.valid) - return toQt(favicon.url); - } - return QUrl(); + FaviconDriverQt *driver = FaviconDriverQt::FromWebContents(webContents()); + return toQt(driver->GetFaviconURL()); +} + +QIcon WebContentsAdapter::icon() const +{ + CHECK_INITIALIZED(QIcon()); + FaviconDriverQt *driver = FaviconDriverQt::FromWebContents(webContents()); + return toQIcon(driver->GetFavicon()); } QString WebContentsAdapter::pageTitle() const @@ -830,42 +821,49 @@ QString WebContentsAdapter::selectedText() const void WebContentsAdapter::undo() { CHECK_INITIALIZED(); + base::RecordAction(base::UserMetricsAction("Undo")); m_webContents->Undo(); } void WebContentsAdapter::redo() { CHECK_INITIALIZED(); + base::RecordAction(base::UserMetricsAction("Redo")); m_webContents->Redo(); } void WebContentsAdapter::cut() { CHECK_INITIALIZED(); + base::RecordAction(base::UserMetricsAction("Cut")); m_webContents->Cut(); } void WebContentsAdapter::copy() { CHECK_INITIALIZED(); + base::RecordAction(base::UserMetricsAction("Copy")); m_webContents->Copy(); } void WebContentsAdapter::paste() { CHECK_INITIALIZED(); + base::RecordAction(base::UserMetricsAction("Paste")); m_webContents->Paste(); } void WebContentsAdapter::pasteAndMatchStyle() { CHECK_INITIALIZED(); + base::RecordAction(base::UserMetricsAction("PasteAndMatchStyle")); m_webContents->PasteAndMatchStyle(); } void WebContentsAdapter::selectAll() { CHECK_INITIALIZED(); + base::RecordAction(base::UserMetricsAction("SelectAll")); m_webContents->SelectAll(); } @@ -884,7 +882,8 @@ void WebContentsAdapter::unselect() void WebContentsAdapter::navigateBack() { CHECK_INITIALIZED(); - CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost()); + base::RecordAction(base::UserMetricsAction("Back")); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame()); if (!m_webContents->GetController().CanGoBack()) return; m_webContents->GetController().GoBack(); @@ -894,7 +893,8 @@ void WebContentsAdapter::navigateBack() void WebContentsAdapter::navigateForward() { CHECK_INITIALIZED(); - CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost()); + base::RecordAction(base::UserMetricsAction("Forward")); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame()); if (!m_webContents->GetController().CanGoForward()) return; m_webContents->GetController().GoForward(); @@ -904,7 +904,7 @@ void WebContentsAdapter::navigateForward() void WebContentsAdapter::navigateToIndex(int offset) { CHECK_INITIALIZED(); - CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost()); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame()); m_webContents->GetController().GoToIndex(offset); focusIfNecessary(); } @@ -912,7 +912,7 @@ void WebContentsAdapter::navigateToIndex(int offset) void WebContentsAdapter::navigateToOffset(int offset) { CHECK_INITIALIZED(); - CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetRenderViewHost()); + CHECK_VALID_RENDER_WIDGET_HOST_VIEW(m_webContents->GetPrimaryMainFrame()); m_webContents->GetController().GoToOffset(offset); focusIfNecessary(); } @@ -920,13 +920,13 @@ void WebContentsAdapter::navigateToOffset(int offset) int WebContentsAdapter::navigationEntryCount() { CHECK_INITIALIZED(0); - return m_webContents->GetController().GetEntryCount(); + return navigationListSize(m_webContents->GetController()); } int WebContentsAdapter::currentNavigationEntryIndex() { CHECK_INITIALIZED(0); - return m_webContents->GetController().GetCurrentEntryIndex(); + return navigationListCurrentIndex(m_webContents->GetController()); } QUrl WebContentsAdapter::getNavigationEntryOriginalUrl(int index) @@ -990,9 +990,8 @@ void WebContentsAdapter::setZoomFactor(qreal factor) content::HostZoomMap *zoomMap = content::HostZoomMap::GetForWebContents(m_webContents.get()); if (zoomMap) { - int render_process_id = m_webContents->GetMainFrame()->GetProcess()->GetID(); - int render_view_id = m_webContents->GetRenderViewHost()->GetRoutingID(); - zoomMap->SetTemporaryZoomLevel(render_process_id, render_view_id, zoomLevel); + const content::GlobalRenderFrameHostId global_id = m_webContents->GetPrimaryMainFrame()->GetGlobalId(); + zoomMap->SetTemporaryZoomLevel(global_id, zoomLevel); } } @@ -1028,15 +1027,13 @@ QWebEngineUrlRequestInterceptor* WebContentsAdapter::requestInterceptor() const QAccessibleInterface *WebContentsAdapter::browserAccessible() { CHECK_INITIALIZED(nullptr); - content::RenderViewHost *rvh = m_webContents->GetRenderViewHost(); - Q_ASSERT(rvh); - content::RenderFrameHostImpl *rfh = static_cast<content::RenderFrameHostImpl *>(rvh->GetMainFrame()); + content::RenderFrameHostImpl *rfh = static_cast<content::RenderFrameHostImpl *>(m_webContents->GetPrimaryMainFrame()); if (!rfh) return nullptr; content::BrowserAccessibilityManager *manager = rfh->GetOrCreateBrowserAccessibilityManager(); if (!manager) // FIXME! return nullptr; - content::BrowserAccessibility *acc = manager->GetRoot(); + content::BrowserAccessibility *acc = manager->GetFromAXNode(manager->GetRoot()); return content::toQAccessibleInterface(acc); } @@ -1045,58 +1042,63 @@ QAccessibleInterface *WebContentsAdapter::browserAccessible() void WebContentsAdapter::runJavaScript(const QString &javaScript, quint32 worldId) { CHECK_INITIALIZED(); - content::RenderViewHost *rvh = m_webContents->GetRenderViewHost(); - Q_ASSERT(rvh); -// static_cast<content::RenderFrameHostImpl *>(rvh->GetMainFrame())->NotifyUserActivation(); - if (worldId == 0) { - rvh->GetMainFrame()->ExecuteJavaScript(toString16(javaScript), base::NullCallback()); + content::RenderFrameHost *rfh = m_webContents->GetPrimaryMainFrame(); + Q_ASSERT(rfh); + if (!static_cast<content::RenderFrameHostImpl*>(rfh)->GetAssociatedLocalFrame()) { + qWarning() << "Local frame is gone, not running script"; return; } - - content::RenderFrameHost::JavaScriptResultCallback callback = base::BindOnce(&callbackOnEvaluateJS, m_adapterClient, CallbackDirectory::NoCallbackId); - rvh->GetMainFrame()->ExecuteJavaScriptInIsolatedWorld(toString16(javaScript), std::move(callback), worldId); + if (worldId == 0) + rfh->ExecuteJavaScript(toString16(javaScript), base::NullCallback()); + else + rfh->ExecuteJavaScriptInIsolatedWorld(toString16(javaScript), base::NullCallback(), worldId); } quint64 WebContentsAdapter::runJavaScriptCallbackResult(const QString &javaScript, quint32 worldId) { CHECK_INITIALIZED(0); - content::RenderViewHost *rvh = m_webContents->GetRenderViewHost(); - Q_ASSERT(rvh); -// static_cast<content::RenderFrameHostImpl *>(rvh->GetMainFrame())->NotifyUserActivation(); + content::RenderFrameHost *rfh = m_webContents->GetPrimaryMainFrame(); + Q_ASSERT(rfh); + if (!static_cast<content::RenderFrameHostImpl*>(rfh)->GetAssociatedLocalFrame()) { + qWarning() << "Local frame is gone, not running script"; + return 0; + } content::RenderFrameHost::JavaScriptResultCallback callback = base::BindOnce(&callbackOnEvaluateJS, m_adapterClient, m_nextRequestId); if (worldId == 0) - rvh->GetMainFrame()->ExecuteJavaScript(toString16(javaScript), std::move(callback)); + rfh->ExecuteJavaScript(toString16(javaScript), std::move(callback)); else - rvh->GetMainFrame()->ExecuteJavaScriptInIsolatedWorld(toString16(javaScript), std::move(callback), worldId); + rfh->ExecuteJavaScriptInIsolatedWorld(toString16(javaScript), std::move(callback), worldId); return m_nextRequestId++; } 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++; } -void WebContentsAdapter::updateWebPreferences(const content::WebPreferences & webPreferences) +void WebContentsAdapter::updateWebPreferences(const blink::web_pref::WebPreferences &webPreferences) { CHECK_INITIALIZED(); - m_webContents->GetRenderViewHost()->UpdateWebkitPreferences(webPreferences); + m_webContents->SetWebPreferences(webPreferences); // In case of updating preferences during navigation, there might be a pending RVH what will // be active on successful navigation. - content::RenderFrameHost *pendingRFH = (static_cast<content::WebContentsImpl*>(m_webContents.get()))->GetPendingMainFrame(); + content::RenderFrameHost *pendingRFH = + (static_cast<content::WebContentsImpl*>(m_webContents.get())) + ->GetPrimaryFrameTree().root()->render_manager()->speculative_frame_host(); if (pendingRFH) { content::RenderViewHost *pendingRVH = pendingRFH->GetRenderViewHost(); Q_ASSERT(pendingRVH); - pendingRVH->UpdateWebkitPreferences(webPreferences); + static_cast<content::RenderViewHostImpl*>(pendingRVH)->SendWebPreferencesToRenderer(); } } @@ -1106,13 +1108,12 @@ void WebContentsAdapter::download(const QUrl &url, const QString &suggestedFileN { CHECK_INITIALIZED(); content::BrowserContext *bctx = m_webContents->GetBrowserContext(); - content::DownloadManager *dlm = content::BrowserContext::GetDownloadManager(bctx); + content::DownloadManager *dlm = bctx->GetDownloadManager(); DownloadManagerDelegateQt *dlmd = m_profileAdapter->downloadManagerDelegate(); if (!dlm) return; - dlmd->markNextDownloadAsUserRequested(); dlm->SetDelegate(dlmd); net::NetworkTrafficAnnotationTag traffic_annotation = @@ -1172,7 +1173,7 @@ qint64 WebContentsAdapter::renderProcessPid() const { CHECK_INITIALIZED(0); - content::RenderProcessHost *renderProcessHost = m_webContents->GetMainFrame()->GetProcess(); + content::RenderProcessHost *renderProcessHost = m_webContents->GetPrimaryMainFrame()->GetProcess(); const base::Process &process = renderProcessHost->GetProcess(); if (!process.IsValid()) return 0; @@ -1182,25 +1183,25 @@ qint64 WebContentsAdapter::renderProcessPid() const void WebContentsAdapter::copyImageAt(const QPoint &location) { CHECK_INITIALIZED(); - m_webContents->GetRenderViewHost()->GetMainFrame()->CopyImageAt(location.x(), location.y()); + m_webContents->GetPrimaryMainFrame()->CopyImageAt(location.x(), location.y()); } -static blink::MediaPlayerAction::Type toBlinkMediaPlayerActionType(WebContentsAdapter::MediaPlayerAction action) +static blink::mojom::MediaPlayerActionType toBlinkMediaPlayerActionType(WebContentsAdapter::MediaPlayerAction action) { switch (action) { case WebContentsAdapter::MediaPlayerPlay: - return blink::MediaPlayerAction::Type::kPlay; + return blink::mojom::MediaPlayerActionType::kPlay; case WebContentsAdapter::MediaPlayerMute: - return blink::MediaPlayerAction::Type::kMute; + return blink::mojom::MediaPlayerActionType::kMute; case WebContentsAdapter::MediaPlayerLoop: - return blink::MediaPlayerAction::Type::kLoop; + return blink::mojom::MediaPlayerActionType::kLoop; case WebContentsAdapter::MediaPlayerControls: - return blink::MediaPlayerAction::Type::kControls; + return blink::mojom::MediaPlayerActionType::kControls; case WebContentsAdapter::MediaPlayerNoAction: break; } NOTREACHED(); - return (blink::MediaPlayerAction::Type)-1; + return (blink::mojom::MediaPlayerActionType)-1; } void WebContentsAdapter::executeMediaPlayerActionAt(const QPoint &location, MediaPlayerAction action, bool enable) @@ -1208,8 +1209,8 @@ void WebContentsAdapter::executeMediaPlayerActionAt(const QPoint &location, Medi CHECK_INITIALIZED(); if (action == MediaPlayerNoAction) return; - blink::MediaPlayerAction blinkAction(toBlinkMediaPlayerActionType(action), enable); - m_webContents->GetRenderViewHost()->GetMainFrame()->ExecuteMediaPlayerActionAtLocation(toGfx(location), blinkAction); + blink::mojom::MediaPlayerAction blinkAction(toBlinkMediaPlayerActionType(action), enable); + m_webContents->GetPrimaryMainFrame()->ExecuteMediaPlayerActionAtLocation(toGfx(location), blinkAction); } void WebContentsAdapter::inspectElementAt(const QPoint &location) @@ -1260,7 +1261,10 @@ void WebContentsAdapter::openDevToolsFrontend(QSharedPointer<WebContentsAdapter> setLifecycleState(LifecycleState::Active); - m_devToolsFrontend = DevToolsFrontendQt::Show(frontendAdapter, m_webContents.get()); + content::WebContents *webContents = m_webContents.get(); + if (content::WebContents *guest = guestWebContents()) + webContents = guest; + m_devToolsFrontend = DevToolsFrontendQt::Show(frontendAdapter, webContents); updateRecommendedState(); } @@ -1280,15 +1284,22 @@ void WebContentsAdapter::devToolsFrontendDestroyed(DevToolsFrontendQt *frontend) updateRecommendedState(); } +QString WebContentsAdapter::devToolsId() +{ + return QString::fromStdString(DevToolsFrontendQt::GetId(m_webContents.get())); +} + void WebContentsAdapter::exitFullScreen() { CHECK_INITIALIZED(); + base::RecordAction(base::UserMetricsAction("ToggleFullscreen")); m_webContents->ExitFullscreen(false); } void WebContentsAdapter::changedFullScreen() { CHECK_INITIALIZED(); + base::RecordAction(base::UserMetricsAction("ToggleFullscreen")); m_webContents->NotifyFullscreenChanged(false); } @@ -1304,33 +1315,42 @@ void WebContentsAdapter::wasHidden() m_webContents->WasHidden(); } -void WebContentsAdapter::printToPDF(const QPageLayout &pageLayout, const QString &filePath) +void WebContentsAdapter::printToPDF(const QPageLayout &pageLayout, const QPageRanges &pageRanges, const QString &filePath) { #if QT_CONFIG(webengine_printing_and_pdf) CHECK_INITIALIZED(); - PrintViewManagerQt::PrintToPDFFileCallback callback = base::Bind(&callbackOnPdfSavingFinished, - m_adapterClient, - filePath); - PrintViewManagerQt::FromWebContents(m_webContents.get())->PrintToPDFFileWithCallback(pageLayout, - true, - filePath, - callback); + PrintViewManagerQt::PrintToPDFFileCallback callback = base::BindOnce(&callbackOnPdfSavingFinished, + m_adapterClient, + filePath); + content::WebContents *webContents = m_webContents.get(); + if (content::WebContents *guest = guestWebContents()) + webContents = guest; + PrintViewManagerQt::FromWebContents(webContents)->PrintToPDFFileWithCallback(pageLayout, + pageRanges, + true, + filePath, + std::move(callback)); #endif // QT_CONFIG(webengine_printing_and_pdf) } quint64 WebContentsAdapter::printToPDFCallbackResult(const QPageLayout &pageLayout, + const QPageRanges &pageRanges, bool colorMode, bool useCustomMargins) { #if QT_CONFIG(webengine_printing_and_pdf) CHECK_INITIALIZED(0); - PrintViewManagerQt::PrintToPDFCallback callback = base::Bind(&callbackOnPrintingFinished, - m_adapterClient, - m_nextRequestId); - PrintViewManagerQt::FromWebContents(m_webContents.get())->PrintToPDFWithCallback(pageLayout, - colorMode, - useCustomMargins, - callback); + PrintViewManagerQt::PrintToPDFCallback callback = base::BindOnce(&callbackOnPrintingFinished, + m_adapterClient, + m_nextRequestId); + content::WebContents *webContents = m_webContents.get(); + if (content::WebContents *guest = guestWebContents()) + webContents = guest; + PrintViewManagerQt::FromWebContents(webContents)->PrintToPDFWithCallback(pageLayout, + pageRanges, + colorMode, + useCustomMargins, + std::move(callback)); return m_nextRequestId++; #else Q_UNUSED(pageLayout); @@ -1375,7 +1395,7 @@ void WebContentsAdapter::grantFeaturePermission(const QUrl &securityOrigin, Prof void WebContentsAdapter::grantMouseLockPermission(const QUrl &securityOrigin, bool granted) { CHECK_INITIALIZED(); - if (securityOrigin != toQt(m_webContents->GetLastCommittedURL().GetOrigin())) + if (securityOrigin != toQt(m_webContents->GetLastCommittedURL().DeprecatedGetOriginAsURL())) return; if (granted) { @@ -1393,15 +1413,17 @@ void WebContentsAdapter::grantMouseLockPermission(const QUrl &securityOrigin, bo granted = false; } - m_webContents->GotResponseToLockMouseRequest(granted); + m_webContents->GotResponseToLockMouseRequest(granted ? blink::mojom::PointerLockResult::kSuccess + : blink::mojom::PointerLockResult::kPermissionDenied); } void WebContentsAdapter::handlePendingMouseLockPermission() { CHECK_INITIALIZED(); - auto it = m_pendingMouseLockPermissions.find(toQt(m_webContents->GetLastCommittedURL().GetOrigin())); + auto it = m_pendingMouseLockPermissions.find(toQt(m_webContents->GetLastCommittedURL().DeprecatedGetOriginAsURL())); if (it != m_pendingMouseLockPermissions.end()) { - m_webContents->GotResponseToLockMouseRequest(it.value()); + m_webContents->GotResponseToLockMouseRequest(it.value() ? blink::mojom::PointerLockResult::kSuccess + : blink::mojom::PointerLockResult::kPermissionDenied); m_pendingMouseLockPermissions.erase(it); } } @@ -1409,8 +1431,13 @@ void WebContentsAdapter::handlePendingMouseLockPermission() void WebContentsAdapter::setBackgroundColor(const QColor &color) { CHECK_INITIALIZED(); - if (content::RenderWidgetHostView *rwhv = m_webContents->GetRenderWidgetHostView()) - rwhv->SetBackgroundColor(toSk(color)); + SkColor c = toSk(color); + if (content::RenderWidgetHostView *rwhv = m_webContents->GetRenderWidgetHostView()) { + rwhv->SetBackgroundColor(c); + ((content::RenderWidgetHostViewBase *)rwhv)->SetContentBackgroundColor(c); + } + if (color != Qt::transparent) + m_pageHost->SetBackgroundColor(c); } content::WebContents *WebContentsAdapter::webContents() const @@ -1418,6 +1445,12 @@ content::WebContents *WebContentsAdapter::webContents() const return m_webContents.get(); } +content::WebContents *WebContentsAdapter::guestWebContents() const +{ + std::vector<content::WebContents *> innerWebContents = m_webContents->GetInnerWebContents(); + return !innerWebContents.empty() ? innerWebContents[0] : nullptr; +} + #if QT_CONFIG(webengine_webchannel) QWebChannel *WebContentsAdapter::webChannel() const { @@ -1454,12 +1487,14 @@ void WebContentsAdapter::setWebChannel(QWebChannel *channel, uint worldId) static QMimeData *mimeDataFromDropData(const content::DropData &dropData) { QMimeData *mimeData = new QMimeData(); - if (!dropData.text.is_null()) - mimeData->setText(toQt(dropData.text.string())); - if (!dropData.html.is_null()) - mimeData->setHtml(toQt(dropData.html.string())); - if (dropData.url.is_valid()) + if (dropData.text.has_value()) + mimeData->setText(toQt(*dropData.text)); + if (dropData.html.has_value()) + mimeData->setHtml(toQt(*dropData.html)); + if (dropData.url.is_valid()) { mimeData->setUrls(QList<QUrl>() << toQt(dropData.url)); + mimeData->setText(toQt(dropData.url_title)); + } if (!dropData.custom_data.empty()) { base::Pickle pickle; ui::WriteCustomDataToPickle(dropData.custom_data, &pickle); @@ -1468,16 +1503,16 @@ static QMimeData *mimeDataFromDropData(const content::DropData &dropData) return mimeData; } -static blink::WebDragOperationsMask toWeb(const Qt::DropActions action) +static blink::DragOperationsMask toWeb(const Qt::DropActions action) { - int result = blink::kWebDragOperationNone; + int result = blink::kDragOperationNone; if (action & Qt::CopyAction) - result |= blink::kWebDragOperationCopy; + result |= blink::kDragOperationCopy; if (action & Qt::LinkAction) - result |= blink::kWebDragOperationLink; + result |= blink::kDragOperationLink; if (action & Qt::MoveAction) - result |= blink::kWebDragOperationMove; - return static_cast<blink::WebDragOperationsMask>(result); + result |= blink::kDragOperationMove; + return static_cast<blink::DragOperationsMask>(result); } void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropData &dropData, @@ -1496,7 +1531,7 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD m_currentDropData->file_contents.clear(); m_currentDropData->file_contents_content_disposition.clear(); - m_currentDropAction = blink::kWebDragOperationNone; + m_currentDropAction = blink::kDragOperationNone; QDrag *drag = new QDrag(dragSource); // will be deleted by Qt's DnD implementation bool dValid = true; QMetaObject::Connection onDestroyed = QObject::connect(dragSource, &QObject::destroyed, [&dValid](){ @@ -1514,18 +1549,26 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD } { - base::MessageLoopCurrent::ScopedNestableTaskAllower allow; + base::CurrentThread::ScopedAllowApplicationTasksInNativeNestedLoop allow; drag->exec(allowedActions); } QObject::disconnect(onDestroyed); if (dValid) { if (m_webContents) { - content::RenderViewHost *rvh = m_webContents->GetRenderViewHost(); + // This is the quickest and (at the moment) the most safe solution to not break guest views when + // dropping data into them. We don't even try to support dropping into PDF input fields, + // since it's not working in Chrome right now. + content::WebContents *targetWebContents = m_webContents.get(); + if (content::WebContents *guest = guestWebContents()) + targetWebContents = guest; + + content::RenderViewHost *rvh = targetWebContents->GetRenderViewHost(); if (rvh) { rvh->GetWidget()->DragSourceEndedAt(gfx::PointF(m_lastDragClientPos.x(), m_lastDragClientPos.y()), gfx::PointF(m_lastDragScreenPos.x(), m_lastDragScreenPos.y()), - blink::WebDragOperation(m_currentDropAction)); + ui::mojom::DragOperation(m_currentDropAction), + base::DoNothing()); rvh->GetWidget()->DragSourceSystemDragEnded(); } } @@ -1576,23 +1619,28 @@ static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeDat } if (!dropData->filenames.empty()) return; + if (!urls.empty()) { + dropData->url = toGurl(urls.first()); + if (mimeData->hasText()) + dropData->url_title = toString16(mimeData->text()); + } if (mimeData->hasHtml()) - dropData->html = toNullableString16(mimeData->html()); + dropData->html = toOptionalString16(mimeData->html()); if (mimeData->hasText()) - dropData->text = toNullableString16(mimeData->text()); + dropData->text = toOptionalString16(mimeData->text()); if (mimeData->hasFormat(QLatin1String(ui::kMimeTypeWebCustomData))) { QByteArray customData = mimeData->data(QLatin1String(ui::kMimeTypeWebCustomData)); ui::ReadCustomDataIntoMap(customData.constData(), customData.length(), &dropData->custom_data); } } -Qt::DropAction toQt(blink::WebDragOperation op) +Qt::DropAction toQt(ui::mojom::DragOperation op) { - if (op & blink::kWebDragOperationCopy) + if (int(op) & int(ui::mojom::DragOperation::kCopy)) return Qt::CopyAction; - if (op & blink::kWebDragOperationLink) + if (int(op) & int(ui::mojom::DragOperation::kLink)) return Qt::LinkAction; - if (op & blink::kWebDragOperationMove || op & blink::kWebDragOperationDelete) + if (int(op) & int(ui::mojom::DragOperation::kMove)) return Qt::MoveAction; return Qt::IgnoreAction; } @@ -1635,21 +1683,22 @@ void WebContentsAdapter::enterDrag(QDragEnterEvent *e, const QPointF &screenPos) content::RenderViewHost *rvh = m_webContents->GetRenderViewHost(); rvh->GetWidget()->FilterDropData(m_currentDropData.get()); - rvh->GetWidget()->DragTargetDragEnter(*m_currentDropData, toGfx(e->posF()), toGfx(screenPos), + rvh->GetWidget()->DragTargetDragEnter(*m_currentDropData, toGfx(e->position()), toGfx(screenPos), toWeb(e->possibleActions()), - toWeb(e->mouseButtons()) | toWeb(e->keyboardModifiers())); + toWeb(e->buttons()) | toWeb(e->modifiers()), + base::DoNothing()); } Qt::DropAction WebContentsAdapter::updateDragPosition(QDragMoveEvent *e, const QPointF &screenPos) { CHECK_INITIALIZED(Qt::DropAction()); content::RenderViewHost *rvh = m_webContents->GetRenderViewHost(); - m_lastDragClientPos = e->posF(); + m_lastDragClientPos = e->position(); m_lastDragScreenPos = screenPos; rvh->GetWidget()->DragTargetDragOver(toGfx(m_lastDragClientPos), toGfx(m_lastDragScreenPos), toWeb(e->possibleActions()), - toWeb(e->mouseButtons()) | toWeb(e->keyboardModifiers())); + toWeb(e->buttons()) | toWeb(e->modifiers()), base::DoNothing()); waitForUpdateDragActionCalled(); - return toQt(blink::WebDragOperation(m_currentDropAction)); + return toQt(ui::mojom::DragOperation(m_currentDropAction)); } void WebContentsAdapter::waitForUpdateDragActionCalled() @@ -1658,7 +1707,7 @@ void WebContentsAdapter::waitForUpdateDragActionCalled() const qint64 timeout = 3000; QElapsedTimer t; t.start(); - auto seqMan = base::MessageLoopCurrent::GetCurrentSequenceManagerImpl(); + auto seqMan = base::CurrentThread::GetCurrentSequenceManagerImpl(); base::MessagePump::Delegate *delegate = static_cast<base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl *>( seqMan->controller_.get()); @@ -1666,7 +1715,7 @@ void WebContentsAdapter::waitForUpdateDragActionCalled() DCHECK(delegate); m_updateDragActionCalled = false; for (;;) { - while (delegate->DoWork() && !m_updateDragActionCalled) {} + while (delegate->DoWork().is_immediate() && !m_updateDragActionCalled) {} if (m_updateDragActionCalled) break; if (t.hasExpired(timeout)) { @@ -1674,7 +1723,7 @@ void WebContentsAdapter::waitForUpdateDragActionCalled() static_cast<int>(timeout)); return; } - base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); + base::PlatformThread::Sleep(base::Milliseconds(1)); } } @@ -1682,7 +1731,7 @@ void WebContentsAdapter::updateDragAction(int action) { CHECK_INITIALIZED(); m_updateDragActionCalled = true; - m_currentDropAction = static_cast<blink::WebDragOperation>(action); + m_currentDropAction = action; } void WebContentsAdapter::endDragging(QDropEvent *e, const QPointF &screenPos) @@ -1690,10 +1739,10 @@ void WebContentsAdapter::endDragging(QDropEvent *e, const QPointF &screenPos) CHECK_INITIALIZED(); content::RenderViewHost *rvh = m_webContents->GetRenderViewHost(); rvh->GetWidget()->FilterDropData(m_currentDropData.get()); - m_lastDragClientPos = e->posF(); + m_lastDragClientPos = e->position(); m_lastDragScreenPos = screenPos; rvh->GetWidget()->DragTargetDrop(*m_currentDropData, toGfx(m_lastDragClientPos), toGfx(m_lastDragScreenPos), - toWeb(e->mouseButtons()) | toWeb(e->keyboardModifiers())); + toWeb(e->buttons()) | toWeb(e->modifiers()), base::DoNothing()); m_currentDropData.reset(); } @@ -1718,8 +1767,8 @@ void WebContentsAdapter::replaceMisspelling(const QString &word) void WebContentsAdapter::focusIfNecessary() { CHECK_INITIALIZED(); - const WebEngineSettings *settings = m_adapterClient->webEngineSettings(); - bool focusOnNavigation = settings->testAttribute(WebEngineSettings::FocusOnNavigationEnabled); + const QWebEngineSettings *settings = m_adapterClient->webEngineSettings(); + bool focusOnNavigation = settings->testAttribute(QWebEngineSettings::FocusOnNavigationEnabled); if (focusOnNavigation) m_webContents->Focus(); } @@ -1737,7 +1786,29 @@ void WebContentsAdapter::resetSelection() if (auto rwhv = static_cast<RenderWidgetHostViewQt *>(m_webContents->GetRenderWidgetHostView())) { if (auto mgr = rwhv->GetTextInputManager()) if (auto selection = const_cast<content::TextInputManager::TextSelection *>(mgr->GetTextSelection(rwhv))) - selection->SetSelection(base::string16(), 0, gfx::Range(), false); + selection->SetSelection(std::u16string(), 0, gfx::Range(), false); + } +} + +void WebContentsAdapter::resetTouchSelectionController() +{ + CHECK_INITIALIZED(); + unselect(); + if (auto rwhv = static_cast<RenderWidgetHostViewQt *>(m_webContents->GetRenderWidgetHostView())) + rwhv->resetTouchSelectionController(); +} + +void WebContentsAdapter::changeTextDirection(bool leftToRight) +{ + CHECK_INITIALIZED(); + if (auto rwhv = static_cast<RenderWidgetHostViewQt *>(m_webContents->GetRenderWidgetHostView())) { + auto textInputManager = rwhv->GetTextInputManager(); + if (!textInputManager) + return; + if (auto activeWidget = textInputManager->GetActiveWidget()) { + activeWidget->UpdateTextDirection(leftToRight ? base::i18n::TextDirection::LEFT_TO_RIGHT : base::i18n::TextDirection::RIGHT_TO_LEFT); + activeWidget->NotifyTextDirection(); + } } } @@ -1749,18 +1820,20 @@ WebContentsAdapterClient::renderProcessExitStatus(int terminationStatus) { status = WebContentsAdapterClient::NormalTerminationStatus; break; case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: + case base::TERMINATION_STATUS_LAUNCH_FAILED: status = WebContentsAdapterClient::AbnormalTerminationStatus; break; case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: -#if defined(OS_CHROMEOS) - case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM: -#endif + case base::TERMINATION_STATUS_OOM: status = WebContentsAdapterClient::KilledTerminationStatus; break; case base::TERMINATION_STATUS_PROCESS_CRASHED: -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) case base::TERMINATION_STATUS_OOM_PROTECTED: #endif +#if BUILDFLAG(IS_WIN) + case base::TERMINATION_STATUS_INTEGRITY_FAILURE: +#endif status = WebContentsAdapterClient::CrashedTerminationStatus; break; case base::TERMINATION_STATUS_STILL_RUNNING: @@ -1772,12 +1845,6 @@ WebContentsAdapterClient::renderProcessExitStatus(int terminationStatus) { return status; } -FaviconManager *WebContentsAdapter::faviconManager() -{ - CHECK_INITIALIZED(nullptr); - return m_webContentsDelegate->faviconManager(); -} - FindTextHelper *WebContentsAdapter::findTextHelper() { CHECK_INITIALIZED(nullptr); @@ -1787,7 +1854,8 @@ FindTextHelper *WebContentsAdapter::findTextHelper() void WebContentsAdapter::viewSource() { CHECK_INITIALIZED(); - m_webContents->GetMainFrame()->ViewSource(); + base::RecordAction(base::UserMetricsAction("ViewSource")); + m_webContents->GetPrimaryMainFrame()->ViewSource(); } bool WebContentsAdapter::canViewSource() @@ -1893,13 +1961,13 @@ WebContentsAdapter::LifecycleState WebContentsAdapter::determineRecommendedState return LifecycleState::Frozen; // Form input is not saved. - if (m_webContents->GetPageImportanceSignals().had_form_interaction) + if (FormInteractionTabHelper::FromWebContents(m_webContents.get())->had_form_interaction()) return LifecycleState::Frozen; // Do not discard PDFs as they might contain entry that is not saved and they // don't remember their scrolling positions. See crbug.com/547286 and // crbug.com/65244. - if (m_webContents->GetContentsMimeType() == "application/pdf") + if (m_webContents->GetContentsMimeType() == kPDFMimeType) return LifecycleState::Frozen; return LifecycleState::Discarded; @@ -1959,6 +2027,7 @@ void WebContentsAdapter::discard() if (m_webContents->IsLoading()) { m_webContentsDelegate->didFailLoad(m_webContentsDelegate->url(webContents()), net::Error::ERR_ABORTED, QStringLiteral("Discarded")); + m_webContentsDelegate->DidStopLoading(); } content::WebContents::CreateParams createParams(m_profileAdapter->profile()); @@ -1973,7 +2042,7 @@ void WebContentsAdapter::discard() nullContents->SetWasDiscarded(true); // Kill render process if this is the only page it's got. - content::RenderProcessHost *renderProcessHost = m_webContents->GetMainFrame()->GetProcess(); + content::RenderProcessHost *renderProcessHost = m_webContents->GetPrimaryMainFrame()->GetProcess(); renderProcessHost->FastShutdownIfPossible(/* page_count */ 1u, /* skip_unload_handlers */ false); @@ -1984,14 +2053,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); @@ -2010,11 +2079,9 @@ void WebContentsAdapter::undiscard() // Create a RenderView with the initial empty document content::RenderViewHost *rvh = m_webContents->GetRenderViewHost(); Q_ASSERT(rvh); - if (!rvh->IsRenderViewLive()) + if (!m_webContents->GetPrimaryMainFrame()->IsRenderFrameLive()) static_cast<content::WebContentsImpl *>(m_webContents.get()) - ->CreateRenderViewForRenderManager(rvh, MSG_ROUTING_NONE, MSG_ROUTING_NONE, - base::UnguessableToken::Create(), - content::FrameReplicationState()); + ->CreateRenderViewForRenderManager(rvh, absl::nullopt, nullptr); m_webContentsDelegate->RenderViewHostChanged(nullptr, rvh); m_adapterClient->initializationFinished(); m_adapterClient->selectionChanged(); @@ -2037,9 +2104,9 @@ ASSERT_ENUMS_MATCH(ReferrerPolicy::NoReferrerWhenDowngrade, network::mojom::Refe ASSERT_ENUMS_MATCH(ReferrerPolicy::Never, network::mojom::ReferrerPolicy::kNever) ASSERT_ENUMS_MATCH(ReferrerPolicy::Origin, network::mojom::ReferrerPolicy::kOrigin) ASSERT_ENUMS_MATCH(ReferrerPolicy::OriginWhenCrossOrigin, network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin) -ASSERT_ENUMS_MATCH(ReferrerPolicy::NoReferrerWhenDowngradeOriginWhenCrossOrigin, network::mojom::ReferrerPolicy::kNoReferrerWhenDowngradeOriginWhenCrossOrigin) +//ASSERT_ENUMS_MATCH(ReferrerPolicy::NoReferrerWhenDowngradeOriginWhenCrossOrigin, network::mojom::ReferrerPolicy::kNoReferrerWhenDowngradeOriginWhenCrossOrigin) ASSERT_ENUMS_MATCH(ReferrerPolicy::SameOrigin, network::mojom::ReferrerPolicy::kSameOrigin) ASSERT_ENUMS_MATCH(ReferrerPolicy::StrictOrigin, network::mojom::ReferrerPolicy::kStrictOrigin) -ASSERT_ENUMS_MATCH(ReferrerPolicy::Last, network::mojom::ReferrerPolicy::kLast) +ASSERT_ENUMS_MATCH(ReferrerPolicy::Last, network::mojom::ReferrerPolicy::kMaxValue) } // namespace QtWebEngineCore |