summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2021-03-12 12:41:40 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2021-03-16 12:03:57 +0100
commit3c544a5d0d59b0533f507a6131fbbc093ed223ea (patch)
treec64d3ae8e17280350037ff1d6687ec797ca4715c /src/core
parente7c869c225075d898cb5d20b194af4b939d2dbc1 (diff)
parentfdec85eba16d6321597e93b447bc13a611cfdd23 (diff)
Merge remote-tracking branch 'origin/5.15' into dev
Diffstat (limited to 'src/core')
-rw-r--r--src/core/api/qwebenginecontextmenurequest.h5
-rw-r--r--src/core/browser_main_parts_qt.cpp5
-rw-r--r--src/core/chromium_overrides.cpp48
-rw-r--r--src/core/content_browser_client_qt.cpp61
-rw-r--r--src/core/content_browser_client_qt.h6
-rw-r--r--src/core/content_client_qt.cpp2
-rw-r--r--src/core/core_chromium.pri2
-rw-r--r--src/core/desktop_screen_qt.cpp87
-rw-r--r--src/core/desktop_screen_qt.h7
-rw-r--r--src/core/devtools_frontend_qt.cpp30
-rw-r--r--src/core/devtools_frontend_qt.h4
-rw-r--r--src/core/extensions/extension_system_qt.cpp5
-rw-r--r--src/core/extensions/extension_web_contents_observer_qt.cpp16
-rw-r--r--src/core/extensions/extension_web_contents_observer_qt.h1
-rw-r--r--src/core/extensions/extensions_api_client_qt.cpp7
-rw-r--r--src/core/extensions/extensions_browser_client_qt.cpp2
-rw-r--r--src/core/extensions/mime_handler_view_guest_delegate_qt.cpp29
-rw-r--r--src/core/extensions/mime_handler_view_guest_delegate_qt.h8
-rw-r--r--src/core/extensions/plugin_service_filter_qt.cpp99
-rw-r--r--src/core/extensions/plugin_service_filter_qt.h71
-rw-r--r--src/core/net/plugin_response_interceptor_url_loader_throttle.cpp152
-rw-r--r--src/core/net/plugin_response_interceptor_url_loader_throttle.h12
-rw-r--r--src/core/profile_adapter.cpp3
-rw-r--r--src/core/profile_qt.cpp1
-rw-r--r--src/core/qtwebengine_resources.gni2
-rw-r--r--src/core/qtwebengine_sources.gni7
-rw-r--r--src/core/render_widget_host_view_qt.cpp238
-rw-r--r--src/core/render_widget_host_view_qt.h18
-rw-r--r--src/core/render_widget_host_view_qt_delegate_client.cpp33
-rw-r--r--src/core/renderer/content_renderer_client_qt.cpp56
-rw-r--r--src/core/renderer/content_renderer_client_qt.h11
-rw-r--r--src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp9
-rw-r--r--src/core/renderer/render_frame_observer_qt.cpp6
-rw-r--r--src/core/renderer/render_frame_observer_qt.h8
-rw-r--r--src/core/web_contents_adapter.cpp10
-rw-r--r--src/core/web_contents_view_qt.cpp3
-rw-r--r--src/core/web_contents_view_qt.h7
-rw-r--r--src/core/web_engine_context.cpp108
-rw-r--r--src/core/web_engine_context.h1
-rw-r--r--src/core/web_engine_library_info.cpp18
40 files changed, 905 insertions, 293 deletions
diff --git a/src/core/api/qwebenginecontextmenurequest.h b/src/core/api/qwebenginecontextmenurequest.h
index bc8095dc9..d9041d797 100644
--- a/src/core/api/qwebenginecontextmenurequest.h
+++ b/src/core/api/qwebenginecontextmenurequest.h
@@ -46,6 +46,10 @@
#include <QtCore/QPoint>
#include <QScopedPointer>
+namespace extensions {
+class MimeHandlerViewGuestDelegateQt;
+}
+
namespace QtWebEngineCore {
class RenderViewContextMenuQt;
class WebContentsViewQt;
@@ -156,6 +160,7 @@ private:
QScopedPointer<QWebEngineContextMenuRequestPrivate> d;
friend class QtWebEngineCore::WebContentsViewQt;
friend class QtWebEngineCore::RenderViewContextMenuQt;
+ friend class extensions::MimeHandlerViewGuestDelegateQt;
friend class QQuickWebEngineViewPrivate;
friend class QQuickWebEngineView;
friend class ContextMenuRequestJSWrapper;
diff --git a/src/core/browser_main_parts_qt.cpp b/src/core/browser_main_parts_qt.cpp
index 1add722a5..bc0499bca 100644
--- a/src/core/browser_main_parts_qt.cpp
+++ b/src/core/browser_main_parts_qt.cpp
@@ -59,10 +59,12 @@
#include "content/public/common/service_manager_connection.h"
#include "extensions/buildflags/buildflags.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
+#include "content/public/browser/plugin_service.h"
#include "extensions/common/constants.h"
#include "extensions/common/extensions_client.h"
#include "extensions/extensions_browser_client_qt.h"
#include "extensions/extension_system_factory_qt.h"
+#include "extensions/plugin_service_filter_qt.h"
#include "common/extensions/extensions_client_qt.h"
#endif //BUILDFLAG(ENABLE_EXTENSIONS)
#include "services/service_manager/public/cpp/connector.h"
@@ -250,6 +252,9 @@ void BrowserMainPartsQt::PreMainMessageLoopRun()
extensions::ExtensionsClient::Set(new extensions::ExtensionsClientQt());
extensions::ExtensionsBrowserClient::Set(new extensions::ExtensionsBrowserClientQt());
extensions::ExtensionSystemFactoryQt::GetInstance();
+
+ content::PluginService *plugin_service = content::PluginService::GetInstance();
+ plugin_service->SetFilter(extensions::PluginServiceFilterQt::GetInstance());
#endif //ENABLE_EXTENSIONS
}
diff --git a/src/core/chromium_overrides.cpp b/src/core/chromium_overrides.cpp
index 4dd3cadbb..6783175fe 100644
--- a/src/core/chromium_overrides.cpp
+++ b/src/core/chromium_overrides.cpp
@@ -50,7 +50,6 @@
#include "ui/base/dragdrop/os_exchange_data_provider_factory.h"
#include "ui/events/devices/device_data_manager.h"
#include "ui/events/platform/platform_event_source.h"
-#include "ui/snapshot/snapshot.h"
#include "ppapi/buildflags/buildflags.h"
#include <QGuiApplication>
@@ -149,53 +148,6 @@ std::vector<AccessibilityTreeFormatter::TestPass> AccessibilityTreeFormatter::Ge
}
} // namespace content
-#if defined(USE_AURA)
-namespace ui {
-
-bool GrabWindowSnapshot(gfx::NativeWindow window,
- const gfx::Rect& snapshot_bounds,
- gfx::Image* image)
-{
- NOTIMPLEMENTED();
- return false;
-}
-
-bool GrabViewSnapshot(gfx::NativeView view,
- const gfx::Rect& snapshot_bounds,
- gfx::Image* image)
-{
- NOTIMPLEMENTED();
- return false;
-}
-
-void GrabWindowSnapshotAndScaleAsync(gfx::NativeWindow window,
- const gfx::Rect& source_rect,
- const gfx::Size& target_size,
- GrabWindowSnapshotAsyncCallback callback)
-{
- NOTIMPLEMENTED();
- std::move(callback).Run(gfx::Image());
-}
-
-void GrabWindowSnapshotAsync(gfx::NativeWindow window,
- const gfx::Rect& source_rect,
- GrabWindowSnapshotAsyncCallback callback)
-{
- NOTIMPLEMENTED();
- std::move(callback).Run(gfx::Image());
-}
-
-void GrabViewSnapshotAsync(gfx::NativeView view,
- const gfx::Rect& source_rect,
- GrabWindowSnapshotAsyncCallback callback)
-{
- NOTIMPLEMENTED();
- std::move(callback).Run(gfx::Image());
-}
-
-} // namespace ui
-#endif // defined(USE_AURA)
-
std::unique_ptr<ui::OSExchangeDataProvider> ui::OSExchangeDataProviderFactory::CreateProvider()
{
return nullptr;
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index b70f8a290..fa960c58c 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -68,6 +68,7 @@
#include "content/public/common/service_names.mojom.h"
#include "content/public/common/user_agent.h"
#include "extensions/buildflags/buildflags.h"
+#include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
#include "net/ssl/client_cert_identity.h"
#include "net/ssl/client_cert_store.h"
#include "services/network/network_service.h"
@@ -152,12 +153,14 @@
#include "extensions/browser/extension_message_filter.h"
#include "extensions/browser/extension_protocols.h"
#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extension_util.h"
#include "extensions/browser/guest_view/extensions_guest_view_message_filter.h"
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
#include "extensions/browser/guest_view/web_view/web_view_guest.h"
#include "extensions/browser/process_map.h"
#include "extensions/browser/url_loader_factory_manager.h"
#include "extensions/common/constants.h"
+#include "extensions/common/manifest_handlers/mime_types_handler.h"
#include "extensions/extension_web_contents_observer_qt.h"
#include "extensions/extensions_browser_client_qt.h"
#include "net/plugin_response_interceptor_url_loader_throttle.h"
@@ -340,7 +343,12 @@ std::unique_ptr<net::ClientCertStore> ContentBrowserClientQt::CreateClientCertSt
std::string ContentBrowserClientQt::GetApplicationLocale()
{
- return WebEngineLibraryInfo::getApplicationLocale();
+ std::string bcp47Name = QLocale().bcp47Name().toStdString();
+ if (m_cachedQtLocale != bcp47Name) {
+ m_cachedQtLocale = bcp47Name;
+ m_appLocale = WebEngineLibraryInfo::getApplicationLocale();
+ }
+ return m_appLocale;
}
std::string ContentBrowserClientQt::GetAcceptLangs(content::BrowserContext *context)
@@ -652,6 +660,8 @@ bool ContentBrowserClientQt::AllowAppCache(const GURL &manifest_url,
content::BrowserContext *context)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ if (!context || context->ShutdownStarted())
+ return false;
return static_cast<ProfileQt *>(context)->profileAdapter()->cookieStore()->d_func()->canAccessCookies(toQt(first_party), toQt(manifest_url));
}
@@ -678,6 +688,8 @@ ContentBrowserClientQt::AllowServiceWorkerOnUI(const GURL &scope,
content::BrowserContext *context)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ if (!context || context->ShutdownStarted())
+ return content::AllowServiceWorkerResult::No();
// FIXME: Chrome also checks if javascript is enabled here to check if has been disabled since the service worker
// was started.
return static_cast<ProfileQt *>(context)->profileAdapter()->cookieStore()->d_func()->canAccessCookies(toQt(site_for_cookies), toQt(scope))
@@ -692,6 +704,8 @@ void ContentBrowserClientQt::AllowWorkerFileSystem(const GURL &url,
base::OnceCallback<void(bool)> callback)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ if (!context || context->ShutdownStarted())
+ return std::move(callback).Run(false);
std::move(callback).Run(
static_cast<ProfileQt *>(context)->profileAdapter()->cookieStore()->d_func()->canAccessCookies(toQt(url), toQt(url)));
}
@@ -702,6 +716,8 @@ bool ContentBrowserClientQt::AllowWorkerIndexedDB(const GURL &url,
const std::vector<content::GlobalFrameRoutingId> &/*render_frames*/)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ if (!context || context->ShutdownStarted())
+ return false;
return static_cast<ProfileQt *>(context)->profileAdapter()->cookieStore()->d_func()->canAccessCookies(toQt(url), toQt(url));
}
@@ -848,8 +864,11 @@ static bool navigationThrottleCallback(content::WebContents *source,
return false;
int navigationRequestAction = WebContentsAdapterClient::AcceptRequest;
- WebContentsDelegateQt *delegate = static_cast<WebContentsDelegateQt *>(source->GetDelegate());
- WebContentsAdapterClient *client = delegate->adapterClient();
+
+ WebContentsAdapterClient *client =
+ WebContentsViewQt::from(static_cast<content::WebContentsImpl *>(source)->GetView())->client();
+ if (!client)
+ return false;
client->navigationRequested(pageTransitionToNavigationType(params.transition_type()),
toQt(params.url()),
navigationRequestAction,
@@ -1137,6 +1156,33 @@ void ContentBrowserClientQt::RegisterNonNetworkSubresourceURLLoaderFactories(int
#endif
}
+base::flat_set<std::string> ContentBrowserClientQt::GetPluginMimeTypesWithExternalHandlers(
+ content::BrowserContext *browser_context)
+{
+ base::flat_set<std::string> mime_types;
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+ ProfileQt *profile = static_cast<ProfileQt *>(browser_context);
+ for (const std::string &extension_id : MimeTypesHandler::GetMIMETypeAllowlist()) {
+ const extensions::Extension *extension =
+ extensions::ExtensionRegistry::Get(browser_context)
+ ->enabled_extensions()
+ .GetByID(extension_id);
+ // The allowed extension may not be installed, so we have to nullptr
+ // check |extension|.
+ if (!extension ||
+ (profile->IsOffTheRecord() && !extensions::util::IsIncognitoEnabled(
+ extension_id, browser_context))) {
+ continue;
+ }
+ if (MimeTypesHandler *handler = MimeTypesHandler::GetHandler(extension)) {
+ for (const auto &supported_mime_type : handler->mime_type_set())
+ mime_types.insert(supported_mime_type);
+ }
+ }
+#endif
+ return mime_types;
+}
+
bool ContentBrowserClientQt::WillCreateURLLoaderFactory(
content::BrowserContext *browser_context,
content::RenderFrameHost *frame,
@@ -1202,4 +1248,13 @@ content::WebContentsViewDelegate *ContentBrowserClientQt::GetWebContentsViewDele
return nullptr;
}
+content::ContentBrowserClient::AllowWebBluetoothResult
+ContentBrowserClientQt::AllowWebBluetooth(content::BrowserContext *browser_context,
+ const url::Origin &requesting_origin,
+ const url::Origin &embedding_origin)
+{
+ DCHECK(browser_context);
+ return content::ContentBrowserClient::AllowWebBluetoothResult::BLOCK_GLOBALLY_DISABLED;
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h
index 75007989d..8b891131f 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -166,6 +166,9 @@ public:
bool AllowWorkerIndexedDB(const GURL &url,
content::BrowserContext *context,
const std::vector<content::GlobalFrameRoutingId> &render_frames) override;
+ AllowWebBluetoothResult AllowWebBluetooth(content::BrowserContext *browser_context,
+ const url::Origin &requesting_origin,
+ const url::Origin &embedding_origin) override;
#if QT_CONFIG(webengine_geolocation)
std::unique_ptr<device::LocationProvider> OverrideSystemLocationProvider() override;
@@ -255,6 +258,7 @@ public:
NonNetworkURLLoaderFactoryMap* factories) override;
void SiteInstanceGotProcess(content::SiteInstance *site_instance) override;
void SiteInstanceDeleting(content::SiteInstance *site_instance) override;
+ base::flat_set<std::string> GetPluginMimeTypesWithExternalHandlers(content::BrowserContext *browser_context) override;
content::WebContentsViewDelegate* GetWebContentsViewDelegate(content::WebContents* web_contents) override;
@@ -265,6 +269,8 @@ public:
private:
scoped_refptr<ShareGroupQt> m_shareGroupQt;
+ std::string m_appLocale;
+ std::string m_cachedQtLocale;
};
} // namespace QtWebEngineCore
diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index 83c367de0..560cdbf54 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -86,7 +86,7 @@ const char kWidevineCdmFileName[] =
#include "pdf/pdf.h"
#include "pdf/pdf_ppapi.h"
const char kPdfPluginMimeType[] = "application/x-google-chrome-pdf";
-const char kPdfPluginPath[] = "internal-pdf-viewer/";
+const char kPdfPluginPath[] = "internal-pdf-viewer";
const char kPdfPluginSrc[] = "src";
#endif // QT_CONFIG(webengine_printing_and_pdf)
diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri
index c22d5901f..a42ee4aff 100644
--- a/src/core/core_chromium.pri
+++ b/src/core/core_chromium.pri
@@ -331,6 +331,7 @@ qtConfig(webengine-extensions) {
extensions/extensions_browser_client_qt.cpp \
extensions/messaging_delegate_qt.cpp \
extensions/mime_handler_view_guest_delegate_qt.cpp \
+ extensions/plugin_service_filter_qt.cpp \
net/plugin_response_interceptor_url_loader_throttle.cpp \
renderer/extensions/extensions_dispatcher_delegate_qt.cpp \
renderer/extensions/extensions_renderer_client_qt.cpp \
@@ -349,6 +350,7 @@ qtConfig(webengine-extensions) {
extensions/extensions_browser_client_qt.h \
extensions/messaging_delegate_qt.h \
extensions/mime_handler_view_guest_delegate_qt.h \
+ extensions/plugin_service_filter_qt.h \
net/plugin_response_interceptor_url_loader_throttle.h \
renderer/extensions/extensions_dispatcher_delegate_qt.h \
renderer/extensions/extensions_renderer_client_qt.h \
diff --git a/src/core/desktop_screen_qt.cpp b/src/core/desktop_screen_qt.cpp
index 1f715444b..fd7a2c54f 100644
--- a/src/core/desktop_screen_qt.cpp
+++ b/src/core/desktop_screen_qt.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2020 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -41,15 +41,96 @@
#include "ui/display/display.h"
+#include "type_conversion.h"
+
+#include <QGuiApplication>
+#include <QScreen>
+
+#include <cmath>
+
namespace QtWebEngineCore {
+static display::Display::Rotation toDisplayRotation(Qt::ScreenOrientation orientation)
+{
+ switch (orientation) {
+ case Qt::PrimaryOrientation:
+ case Qt::LandscapeOrientation:
+ return display::Display::ROTATE_0;
+ case Qt::PortraitOrientation:
+ return display::Display::ROTATE_90;
+ case Qt::InvertedLandscapeOrientation:
+ return display::Display::ROTATE_180;
+ case Qt::InvertedPortraitOrientation:
+ return display::Display::ROTATE_270;
+ }
+}
+
+display::Display toDisplayDisplay(int id, const QScreen *screen)
+{
+ auto display = display::Display(id, toGfx(screen->geometry()));
+ display.set_work_area(toGfx(screen->availableGeometry()));
+ display.set_device_scale_factor(screen->devicePixelRatio());
+ display.set_is_monochrome(screen->depth() == 1);
+ display.set_color_depth(screen->depth());
+ display.set_depth_per_component(8); // FIXME: find the real value
+ display.set_display_frequency(std::ceil(screen->refreshRate()));
+ display.set_rotation(toDisplayRotation(screen->orientation()));
+ if (screen->nativeOrientation() != Qt::PrimaryOrientation)
+ display.set_panel_rotation(toDisplayRotation(screen->nativeOrientation()));
+ return display;
+}
+
DesktopScreenQt::DesktopScreenQt()
{
- ProcessDisplayChanged(display::Display::GetDefaultDisplay(), true /* is_primary */);
+ initializeScreens();
}
DesktopScreenQt::~DesktopScreenQt()
-{}
+{
+ for (auto conn : qAsConst(m_connections))
+ QObject::disconnect(conn);
+}
+
+void DesktopScreenQt::initializeScreens()
+{
+ if (updateAllScreens()) {
+ m_connections[0] =
+ QObject::connect(qApp, &QGuiApplication::primaryScreenChanged, [this] (QScreen *screen) {
+ ProcessDisplayChanged(toDisplayDisplay(0, screen), true /* is_primary */);
+ });
+ // no guarantees how these will affect ids:
+ m_connections[1] =
+ QObject::connect(qApp, &QGuiApplication::screenAdded, [this] (QScreen *) {
+ updateAllScreens();
+ });
+ m_connections[2] =
+ QObject::connect(qApp, &QGuiApplication::screenRemoved, [this] (QScreen *) {
+ updateAllScreens();
+ });
+ } else {
+ // Running headless
+ ProcessDisplayChanged(display::Display::GetDefaultDisplay(), true /* is_primary */);
+ m_connections[0] =
+ QObject::connect(qApp, &QGuiApplication::screenAdded, [this] (QScreen *) {
+ display_list().RemoveDisplay(display::kDefaultDisplayId);
+ QObject::disconnect(m_connections[0]);
+ initializeScreens();
+ });
+ }
+}
+
+bool DesktopScreenQt::updateAllScreens()
+{
+ Q_ASSERT(qApp->primaryScreen() == qApp->screens().first());
+ const auto screens = qApp->screens();
+ const int oldLen = GetNumDisplays();
+ for (int i = screens.length(); i < oldLen; ++i)
+ display_list().RemoveDisplay(i);
+ for (int i = 0; i < screens.length(); ++i)
+ ProcessDisplayChanged(toDisplayDisplay(i, screens.at(i)), i == 0 /* is_primary */);
+
+ return screens.length() > 0;
+}
display::Display DesktopScreenQt::GetDisplayNearestWindow(gfx::NativeWindow /*window*/) const
{
diff --git a/src/core/desktop_screen_qt.h b/src/core/desktop_screen_qt.h
index f47cfabbc..1b2e095a4 100644
--- a/src/core/desktop_screen_qt.h
+++ b/src/core/desktop_screen_qt.h
@@ -42,6 +42,8 @@
#include "ui/display/screen_base.h"
+#include <qmetaobject.h>
+
namespace QtWebEngineCore {
class DesktopScreenQt : public display::ScreenBase
@@ -51,6 +53,11 @@ public:
~DesktopScreenQt() override;
display::Display GetDisplayNearestWindow(gfx::NativeWindow /*window*/) const override;
+
+private:
+ void initializeScreens();
+ bool updateAllScreens();
+ QMetaObject::Connection m_connections[3];
};
} // namespace QtWebEngineCore
diff --git a/src/core/devtools_frontend_qt.cpp b/src/core/devtools_frontend_qt.cpp
index 71d51190a..553757fbb 100644
--- a/src/core/devtools_frontend_qt.cpp
+++ b/src/core/devtools_frontend_qt.cpp
@@ -59,6 +59,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/values.h"
+#include "chrome/browser/devtools/devtools_eye_dropper.h"
#include "chrome/common/url_constants.h"
#include "components/prefs/in_memory_pref_store.h"
#include "components/prefs/json_pref_store.h"
@@ -531,6 +532,11 @@ void DevToolsFrontendQt::HandleMessageFromDevToolsFrontend(const std::string &me
Activate();
} else if (method == "closeWindow") {
web_contents()->Close();
+ } else if (method == "setEyeDropperActive" && params->GetSize() == 1) {
+ bool active;
+ if (!params->GetBoolean(0, &active))
+ return;
+ SetEyeDropperActive(active);
} else {
VLOG(1) << "Unimplemented devtools method: " << message;
return;
@@ -540,6 +546,30 @@ void DevToolsFrontendQt::HandleMessageFromDevToolsFrontend(const std::string &me
SendMessageAck(request_id, nullptr);
}
+void DevToolsFrontendQt::SetEyeDropperActive(bool active)
+{
+ if (!m_inspectedContents)
+ return;
+ if (active) {
+ m_eyeDropper.reset(new DevToolsEyeDropper(
+ m_inspectedContents,
+ base::Bind(&DevToolsFrontendQt::ColorPickedInEyeDropper,
+ base::Unretained(this))));
+ } else {
+ m_eyeDropper.reset();
+ }
+}
+
+void DevToolsFrontendQt::ColorPickedInEyeDropper(int r, int g, int b, int a)
+{
+ base::DictionaryValue color;
+ color.SetInteger("r", r);
+ color.SetInteger("g", g);
+ color.SetInteger("b", b);
+ color.SetInteger("a", a);
+ CallClientFunction("DevToolsAPI.eyeDropperPickedColor", &color, nullptr, nullptr);
+}
+
void DevToolsFrontendQt::DispatchProtocolMessage(content::DevToolsAgentHost *agentHost, base::span<const uint8_t> message)
{
Q_UNUSED(agentHost);
diff --git a/src/core/devtools_frontend_qt.h b/src/core/devtools_frontend_qt.h
index 423131c4e..aac5909dc 100644
--- a/src/core/devtools_frontend_qt.h
+++ b/src/core/devtools_frontend_qt.h
@@ -65,6 +65,7 @@ class RenderViewHost;
class WebContents;
} // namespace content
+class DevToolsEyeDropper;
class PersistentPrefStore;
namespace QtWebEngineCore {
@@ -113,6 +114,8 @@ private:
void RemovePreference(const std::string &name);
void ClearPreferences();
void CreateJsonPreferences(bool clear);
+ void SetEyeDropperActive(bool active);
+ void ColorPickedInEyeDropper(int r, int g, int b, int a);
// We shouldn't be keeping it alive
QWeakPointer<WebContentsAdapter> m_frontendAdapter;
@@ -123,6 +126,7 @@ private:
int m_inspect_element_at_x;
int m_inspect_element_at_y;
std::unique_ptr<content::DevToolsFrontendHost> m_frontendHost;
+ std::unique_ptr<DevToolsEyeDropper> m_eyeDropper;
class NetworkResourceLoader;
std::set<std::unique_ptr<NetworkResourceLoader>, base::UniquePtrComparator> m_loaders;
diff --git a/src/core/extensions/extension_system_qt.cpp b/src/core/extensions/extension_system_qt.cpp
index 9c080e9aa..285b27729 100644
--- a/src/core/extensions/extension_system_qt.cpp
+++ b/src/core/extensions/extension_system_qt.cpp
@@ -223,11 +223,12 @@ void ExtensionSystemQt::NotifyExtensionLoaded(const Extension *extension)
// Register plugins included with the extension.
// Implementation based on PluginManager::OnExtensionLoaded.
const MimeTypesHandler *handler = MimeTypesHandler::GetHandler(extension);
- if (handler && !handler->handler_url().empty()) {
+ if (handler && handler->HasPlugin()) {
content::WebPluginInfo info;
info.type = content::WebPluginInfo::PLUGIN_TYPE_BROWSER_PLUGIN;
info.name = base::UTF8ToUTF16(extension->name());
- info.path = base::FilePath::FromUTF8Unsafe(extension->url().spec());
+ info.path = handler->GetPluginPath();
+ info.background_color = handler->GetBackgroundColor();
for (std::set<std::string>::const_iterator mime_type = handler->mime_type_set().begin();
mime_type != handler->mime_type_set().end(); ++mime_type) {
content::WebPluginMimeType mime_type_info;
diff --git a/src/core/extensions/extension_web_contents_observer_qt.cpp b/src/core/extensions/extension_web_contents_observer_qt.cpp
index 5b1514bb4..e336f70b4 100644
--- a/src/core/extensions/extension_web_contents_observer_qt.cpp
+++ b/src/core/extensions/extension_web_contents_observer_qt.cpp
@@ -43,13 +43,17 @@
#include "extension_web_contents_observer_qt.h"
+#include "components/guest_view/browser/guest_view_base.h"
#include "content/public/browser/child_process_security_policy.h"
-#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
#include "content/public/common/url_constants.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/manifest.h"
+#include "render_widget_host_view_qt.h"
+
namespace extensions {
ExtensionWebContentsObserverQt::ExtensionWebContentsObserverQt(content::WebContents *web_contents)
@@ -85,6 +89,16 @@ void ExtensionWebContentsObserverQt::RenderFrameCreated(content::RenderFrameHost
policy->GrantRequestOrigin(process_id, url::Origin::Create(GURL(content::kChromeUIResourcesURL)));
}
+void ExtensionWebContentsObserverQt::RenderViewCreated(content::RenderViewHost *render_view_host)
+{
+ if (web_contents()->IsInnerWebContentsForGuest()) {
+ content::RenderWidgetHost *render_widget_host = render_view_host->GetWidget();
+ content::WebContents *parent_web_contents = guest_view::GuestViewBase::GetTopLevelWebContents(web_contents());
+ QtWebEngineCore::RenderWidgetHostViewQt *parent_rwhv = static_cast<QtWebEngineCore::RenderWidgetHostViewQt *>(parent_web_contents->GetRenderWidgetHostView());
+ parent_rwhv->setGuest(static_cast<content::RenderWidgetHostImpl *>(render_widget_host));
+ }
+}
+
WEB_CONTENTS_USER_DATA_KEY_IMPL(ExtensionWebContentsObserverQt)
} // namespace extensions
diff --git a/src/core/extensions/extension_web_contents_observer_qt.h b/src/core/extensions/extension_web_contents_observer_qt.h
index 658966b31..c0269e4f5 100644
--- a/src/core/extensions/extension_web_contents_observer_qt.h
+++ b/src/core/extensions/extension_web_contents_observer_qt.h
@@ -61,6 +61,7 @@ public:
// content::WebContentsObserver overrides.
void RenderFrameCreated(content::RenderFrameHost *render_frame_host) override;
+ void RenderViewCreated(content::RenderViewHost *render_view_host) override;
private:
friend class content::WebContentsUserData<ExtensionWebContentsObserverQt>;
diff --git a/src/core/extensions/extensions_api_client_qt.cpp b/src/core/extensions/extensions_api_client_qt.cpp
index 81d9efde2..925fd10da 100644
--- a/src/core/extensions/extensions_api_client_qt.cpp
+++ b/src/core/extensions/extensions_api_client_qt.cpp
@@ -47,9 +47,10 @@
#include <memory>
#include "components/pdf/browser/pdf_web_contents_helper.h"
+#include "extension_web_contents_observer_qt.h"
#include "extensions/browser/guest_view/extensions_guest_view_manager_delegate.h"
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h"
-#include "extension_web_contents_observer_qt.h"
+#include "mime_handler_view_guest_delegate_qt.h"
#include "printing/print_view_manager_qt.h"
namespace extensions {
@@ -67,12 +68,12 @@ AppViewGuestDelegate *ExtensionsAPIClientQt::CreateAppViewGuestDelegate() const
std::unique_ptr<guest_view::GuestViewManagerDelegate> ExtensionsAPIClientQt::CreateGuestViewManagerDelegate(content::BrowserContext *context) const
{
- return std::make_unique<guest_view::GuestViewManagerDelegate>();
+ return std::make_unique<extensions::ExtensionsGuestViewManagerDelegate>(context);
}
std::unique_ptr<MimeHandlerViewGuestDelegate> ExtensionsAPIClientQt::CreateMimeHandlerViewGuestDelegate(MimeHandlerViewGuest *guest) const
{
- return std::make_unique<MimeHandlerViewGuestDelegate>();
+ return std::make_unique<MimeHandlerViewGuestDelegateQt>(guest);
}
void ExtensionsAPIClientQt::AttachWebContentsHelpers(content::WebContents *web_contents) const
diff --git a/src/core/extensions/extensions_browser_client_qt.cpp b/src/core/extensions/extensions_browser_client_qt.cpp
index 6bcf37d85..501252823 100644
--- a/src/core/extensions/extensions_browser_client_qt.cpp
+++ b/src/core/extensions/extensions_browser_client_qt.cpp
@@ -335,7 +335,7 @@ BrowserContext *ExtensionsBrowserClientQt::GetOriginalContext(BrowserContext *co
bool ExtensionsBrowserClientQt::IsGuestSession(BrowserContext *context) const
{
- return false;
+ return context->IsOffTheRecord();
}
bool ExtensionsBrowserClientQt::IsExtensionIncognitoEnabled(const std::string &extension_id,
diff --git a/src/core/extensions/mime_handler_view_guest_delegate_qt.cpp b/src/core/extensions/mime_handler_view_guest_delegate_qt.cpp
index 58f4f209a..16a747929 100644
--- a/src/core/extensions/mime_handler_view_guest_delegate_qt.cpp
+++ b/src/core/extensions/mime_handler_view_guest_delegate_qt.cpp
@@ -44,33 +44,44 @@
#include "mime_handler_view_guest_delegate_qt.h"
-#include "content/browser/browser_plugin/browser_plugin_guest.h"
-#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/context_menu_params.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
+#include "profile_adapter.h"
+#include "qwebenginecontextmenurequest.h"
+#include "qwebenginecontextmenurequest_p.h"
+#include "render_widget_host_view_qt.h"
+#include "touch_selection_controller_client_qt.h"
+#include "web_contents_adapter.h"
+#include "web_contents_adapter_client.h"
+#include "web_contents_view_qt.h"
+
namespace extensions {
MimeHandlerViewGuestDelegateQt::MimeHandlerViewGuestDelegateQt(MimeHandlerViewGuest *)
: MimeHandlerViewGuestDelegate()
+ , m_contextMenuRequest(new QWebEngineContextMenuRequest(new QWebEngineContextMenuRequestPrivate))
{
}
MimeHandlerViewGuestDelegateQt::~MimeHandlerViewGuestDelegateQt()
{
+ delete m_contextMenuRequest;
}
bool MimeHandlerViewGuestDelegateQt::HandleContextMenu(content::WebContents *web_contents, const content::ContextMenuParams &params)
{
- content::ContextMenuParams new_params = params;
-
- gfx::Point guest_coordinates =
- static_cast<content::WebContentsImpl *>(web_contents)->GetBrowserPluginGuest()->GetScreenCoordinates(gfx::Point());
+ content::WebContents *parent_web_contents = guest_view::GuestViewBase::GetTopLevelWebContents(web_contents);
+ if (auto rwhv = static_cast<QtWebEngineCore::RenderWidgetHostViewQt *>(parent_web_contents->GetRenderWidgetHostView())) {
+ if (rwhv->getTouchSelectionControllerClient()->handleContextMenu(params))
+ return true;
- // Adjust (x,y) position for offset from guest to embedder.
- new_params.x += guest_coordinates.x();
- new_params.y += guest_coordinates.y();
+ QtWebEngineCore::WebContentsAdapterClient *adapterClient = rwhv->adapterClient();
+ QtWebEngineCore::WebContentsViewQt::update(m_contextMenuRequest, params, adapterClient->profileAdapter()->isSpellCheckEnabled());
+ adapterClient->contextMenuRequested(m_contextMenuRequest);
+ return true;
+ }
return false;
}
diff --git a/src/core/extensions/mime_handler_view_guest_delegate_qt.h b/src/core/extensions/mime_handler_view_guest_delegate_qt.h
index 6cd80689c..c9b822aa1 100644
--- a/src/core/extensions/mime_handler_view_guest_delegate_qt.h
+++ b/src/core/extensions/mime_handler_view_guest_delegate_qt.h
@@ -46,8 +46,11 @@
#define MIME_HANDLER_VIEW_GUEST_DELEGATE_QT_H_
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h"
-#include "content/browser/web_contents/web_contents_view.h"
-#include "content/public/browser/web_contents.h"
+#include "api/qtwebenginecoreglobal_p.h"
+
+QT_BEGIN_NAMESPACE
+class QWebEngineContextMenuRequest;
+QT_END_NAMESPACE
namespace content {
struct ContextMenuParams;
@@ -66,6 +69,7 @@ public:
const content::ContextMenuParams &params) override;
private:
+ QWebEngineContextMenuRequest *m_contextMenuRequest;
DISALLOW_COPY_AND_ASSIGN(MimeHandlerViewGuestDelegateQt);
};
diff --git a/src/core/extensions/plugin_service_filter_qt.cpp b/src/core/extensions/plugin_service_filter_qt.cpp
new file mode 100644
index 000000000..94cf5cb27
--- /dev/null
+++ b/src/core/extensions/plugin_service_filter_qt.cpp
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 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 "extensions/plugin_service_filter_qt.h"
+
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/web_contents.h"
+
+#include "web_contents_delegate_qt.h"
+
+using namespace QtWebEngineCore;
+
+namespace extensions {
+
+// static
+PluginServiceFilterQt *PluginServiceFilterQt::GetInstance() {
+ return base::Singleton<PluginServiceFilterQt>::get();
+}
+
+bool PluginServiceFilterQt::IsPluginAvailable(int render_process_id,
+ int render_frame_id,
+ const GURL &url,
+ const url::Origin &main_frame_origin,
+ content::WebPluginInfo *plugin)
+{
+ content::RenderFrameHost *frame_host = content::RenderFrameHost::FromID(render_process_id, render_frame_id);
+ content::WebContents *web_contents = content::WebContents::FromRenderFrameHost(frame_host);
+ if (!web_contents) {
+ // Availability checked somewhere before/during WebContents initialization. Let it load and enable
+ // all the plugins at this phase. This information will be queried again when receiving the response
+ // for the requested content. Postponing our decision and enabling/blocking there makes WebEngineSettings
+ // modifiable in runtime without reconstructing WebContents.
+ return true;
+ }
+
+ if (web_contents->IsInnerWebContentsForGuest())
+ web_contents = web_contents->GetOuterWebContents();
+
+ if (auto *delegate = static_cast<WebContentsDelegateQt *>(web_contents->GetDelegate())) {
+ const WebEngineSettings *settings = delegate->webEngineSettings();
+ if (!settings->testAttribute(QWebEngineSettings::PdfViewerEnabled)
+ || !settings->testAttribute(QWebEngineSettings::PluginsEnabled))
+ return false;
+ }
+
+ return true;
+}
+
+bool PluginServiceFilterQt::CanLoadPlugin(int render_process_id,
+ const base::FilePath &path)
+{
+ return true;
+}
+
+PluginServiceFilterQt::PluginServiceFilterQt()
+{
+}
+
+PluginServiceFilterQt::~PluginServiceFilterQt()
+{
+}
+
+} // namespace extensions
diff --git a/src/core/extensions/plugin_service_filter_qt.h b/src/core/extensions/plugin_service_filter_qt.h
new file mode 100644
index 000000000..ea5f082f2
--- /dev/null
+++ b/src/core/extensions/plugin_service_filter_qt.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 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 PLUGIN_SERVICE_FILTER_QT
+#define PLUGIN_SERVICE_FILTER_QT
+
+#include "content/public/browser/plugin_service_filter.h"
+
+#include "base/memory/singleton.h"
+
+namespace extensions {
+
+class PluginServiceFilterQt : public content::PluginServiceFilter {
+public:
+ static PluginServiceFilterQt* GetInstance();
+
+ bool IsPluginAvailable(int render_process_id,
+ int render_frame_id,
+ const GURL &url,
+ const url::Origin &main_frame_origin,
+ content::WebPluginInfo *plugin) override;
+
+ bool CanLoadPlugin(int render_process_id,
+ const base::FilePath &path) override;
+
+private:
+ friend struct base::DefaultSingletonTraits<PluginServiceFilterQt>;
+
+ PluginServiceFilterQt();
+ ~PluginServiceFilterQt();
+};
+
+} // namespace extensions
+
+#endif // PLUGIN_SERVICE_FILTER_QT
diff --git a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
index 334b147a5..bca059ae6 100644
--- a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
+++ b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
@@ -40,59 +40,27 @@
#include "plugin_response_interceptor_url_loader_throttle.h"
#include "base/bind.h"
+#include "base/guid.h"
#include "base/task/post_task.h"
+#include "chrome/browser/extensions/api/streams_private/streams_private_api.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/download_request_utils.h"
#include "content/public/browser/download_utils.h"
+#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_attach_helper.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
+#include "extensions/common/manifest_handlers/mime_types_handler.h"
+#include "third_party/blink/public/mojom/loader/transferrable_url_loader.mojom.h"
+#include "extensions/extension_system_qt.h"
#include "web_contents_delegate_qt.h"
#include <string>
namespace QtWebEngineCore {
-void onPdfStreamIntercepted(const GURL &original_url, std::string extension_id, int frame_tree_node_id)
-{
- content::WebContents *web_contents = content::WebContents::FromFrameTreeNodeId(frame_tree_node_id);
- if (!web_contents)
- return;
-
- WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt *>(web_contents->GetDelegate());
- if (!contentsDelegate)
- return;
-
- WebEngineSettings *settings = contentsDelegate->webEngineSettings();
- if (!settings->testAttribute(QWebEngineSettings::PdfViewerEnabled)
- || !settings->testAttribute(QWebEngineSettings::PluginsEnabled)) {
- // If the applications has been set up to always download PDF files to open them in an
- // external viewer, trigger the download.
- std::unique_ptr<download::DownloadUrlParameters> params(
- content::DownloadRequestUtils::CreateDownloadForWebContentsMainFrame(web_contents, original_url,
- MISSING_TRAFFIC_ANNOTATION));
- content::BrowserContext::GetDownloadManager(web_contents->GetBrowserContext())->DownloadUrl(std::move(params));
- return;
- }
-
- // The URL passes the original pdf resource url, that will be requested
- // by the pdf viewer extension page.
- content::NavigationController::LoadURLParams params(
- GURL(base::StringPrintf("%s://%s/index.html?%s", extensions::kExtensionScheme,
- extension_id.c_str(), original_url.spec().c_str())));
-
- params.frame_tree_node_id = frame_tree_node_id;
- web_contents->GetController().LoadURLWithParams(params);
-}
-
-
-PluginResponseInterceptorURLLoaderThrottle::PluginResponseInterceptorURLLoaderThrottle(
- content::ResourceContext *resource_context, int resource_type, int frame_tree_node_id)
- : m_resource_context(resource_context), m_resource_type(resource_type), m_frame_tree_node_id(frame_tree_node_id)
-{}
-
PluginResponseInterceptorURLLoaderThrottle::PluginResponseInterceptorURLLoaderThrottle(
content::BrowserContext *browser_context, int resource_type, int frame_tree_node_id)
: m_browser_context(browser_context), m_resource_type(resource_type), m_frame_tree_node_id(frame_tree_node_id)
@@ -102,31 +70,111 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL
network::mojom::URLResponseHead *response_head,
bool *defer)
{
- Q_UNUSED(defer);
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (content::download_utils::MustDownload(response_url, response_head->headers.get(), response_head->mime_type))
return;
- if (m_resource_context) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- } else {
- DCHECK(m_browser_context);
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- }
+ content::WebContents *web_contents = content::WebContents::FromFrameTreeNodeId(m_frame_tree_node_id);
+ if (!web_contents)
+ return;
std::string extension_id;
- // FIXME: We should use extensions::InfoMap in the future:
if (response_head->mime_type == "application/pdf")
extension_id = extension_misc::kPdfExtensionId;
if (extension_id.empty())
return;
- *defer = true;
+ WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt *>(web_contents->GetDelegate());
+ if (!contentsDelegate)
+ return;
+
+ WebEngineSettings *settings = contentsDelegate->webEngineSettings();
+ if (!settings->testAttribute(QWebEngineSettings::PdfViewerEnabled)
+ || !settings->testAttribute(QWebEngineSettings::PluginsEnabled)) {
+ // PluginServiceFilterQt will inform the URLLoader about the disabled state of plugins
+ // and we can expect the download to be triggered automatically. It's unnecessary to
+ // go further and start the guest view embedding process.
+ return;
+ }
+
+ // Chrome's PDF Extension does not work properly in the face of a restrictive
+ // Content-Security-Policy, and does not currently respect the policy anyway.
+ // Ignore CSP served on a PDF response. https://crbug.com/271452
+ if (extension_id == extension_misc::kPdfExtensionId && response_head->headers)
+ response_head->headers->RemoveHeader("Content-Security-Policy");
+
+ MimeTypesHandler::ReportUsedHandler(extension_id);
+
+ std::string view_id = base::GenerateGUID();
+ // The string passed down to the original client with the response body.
+ std::string payload = view_id;
+
+ mojo::PendingRemote<network::mojom::URLLoader> dummy_new_loader;
+ ignore_result(dummy_new_loader.InitWithNewPipeAndPassReceiver());
+ mojo::Remote<network::mojom::URLLoaderClient> new_client;
+ mojo::PendingReceiver<network::mojom::URLLoaderClient> new_client_receiver =
+ new_client.BindNewPipeAndPassReceiver();
+
+
+ uint32_t data_pipe_size = 64U;
+ // Provide the MimeHandlerView code a chance to override the payload. This is
+ // the case where the resource is handled by frame-based MimeHandlerView.
+ *defer = extensions::MimeHandlerViewAttachHelper::OverrideBodyForInterceptedResponse(
+ m_frame_tree_node_id, response_url, response_head->mime_type, view_id,
+ &payload, &data_pipe_size,
+ base::BindOnce(
+ &PluginResponseInterceptorURLLoaderThrottle::ResumeLoad,
+ weak_factory_.GetWeakPtr()));
+
+ mojo::DataPipe data_pipe(data_pipe_size);
+ uint32_t len = static_cast<uint32_t>(payload.size());
+ CHECK_EQ(MOJO_RESULT_OK,
+ data_pipe.producer_handle->WriteData(
+ payload.c_str(), &len, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
+
+
+ new_client->OnStartLoadingResponseBody(std::move(data_pipe.consumer_handle));
+
+ network::URLLoaderCompletionStatus status(net::OK);
+ status.decoded_body_length = len;
+ new_client->OnComplete(status);
+
+ mojo::PendingRemote<network::mojom::URLLoader> original_loader;
+ mojo::PendingReceiver<network::mojom::URLLoaderClient> original_client;
+ delegate_->InterceptResponse(std::move(dummy_new_loader),
+ std::move(new_client_receiver), &original_loader,
+ &original_client);
+
+ // Make a deep copy of URLResponseHead before passing it cross-thread.
+ auto deep_copied_response = response_head->Clone();
+ if (response_head->headers) {
+ deep_copied_response->headers =
+ base::MakeRefCounted<net::HttpResponseHeaders>(
+ response_head->headers->raw_headers());
+ }
+
+ auto transferrable_loader = blink::mojom::TransferrableURLLoader::New();
+ transferrable_loader->url = GURL(
+ extensions::Extension::GetBaseURLFromExtensionId(extension_id).spec() +
+ base::GenerateGUID());
+ transferrable_loader->url_loader = std::move(original_loader);
+ transferrable_loader->url_loader_client = std::move(original_client);
+ transferrable_loader->head = std::move(deep_copied_response);
+ transferrable_loader->head->intercepted_by_plugin = true;
+
+ bool embedded = m_resource_type !=
+ static_cast<int>(blink::mojom::ResourceType::kMainFrame);
+ content::GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &extensions::StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent,
+ extension_id, view_id, embedded, m_frame_tree_node_id,
+ -1 /* render_process_id */, -1 /* render_frame_id */,
+ std::move(transferrable_loader), response_url));
+}
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(&onPdfStreamIntercepted,
- response_url,
- extension_id,
- m_frame_tree_node_id));
+void PluginResponseInterceptorURLLoaderThrottle::ResumeLoad() {
+ delegate_->Resume();
}
} // namespace QtWebEngineCore
diff --git a/src/core/net/plugin_response_interceptor_url_loader_throttle.h b/src/core/net/plugin_response_interceptor_url_loader_throttle.h
index 7b9db6490..205ab25e6 100644
--- a/src/core/net/plugin_response_interceptor_url_loader_throttle.h
+++ b/src/core/net/plugin_response_interceptor_url_loader_throttle.h
@@ -41,11 +41,11 @@
#define PLUGIN_RESPONSE_INTERCEPTOR_URL_LOADER_THROTTLE_H_
#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
namespace content {
class BrowserContext;
-class ResourceContext;
}
namespace QtWebEngineCore {
@@ -53,8 +53,6 @@ namespace QtWebEngineCore {
class PluginResponseInterceptorURLLoaderThrottle : public blink::URLLoaderThrottle
{
public:
- PluginResponseInterceptorURLLoaderThrottle(content::ResourceContext *resource_context,
- int resource_type, int frame_tree_node_id);
PluginResponseInterceptorURLLoaderThrottle(content::BrowserContext *browser_context,
int resource_type, int frame_tree_node_id);
~PluginResponseInterceptorURLLoaderThrottle() override = default;
@@ -63,11 +61,17 @@ private:
// content::URLLoaderThrottle overrides;
void WillProcessResponse(const GURL &response_url, network::mojom::URLResponseHead *response_head, bool *defer) override;
- content::ResourceContext *m_resource_context = nullptr;
+ // Resumes loading for an intercepted response. This would give the extension
+ // layer chance to initialize its browser side state.
+ void ResumeLoad();
+
content::BrowserContext *m_browser_context = nullptr;
const int m_resource_type;
const int m_frame_tree_node_id;
+ base::WeakPtrFactory<PluginResponseInterceptorURLLoaderThrottle>
+ weak_factory_{this};
+
DISALLOW_COPY_AND_ASSIGN(PluginResponseInterceptorURLLoaderThrottle);
};
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index 577d0f6c8..de28aee6c 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -121,6 +121,7 @@ ProfileAdapter::ProfileAdapter(const QString &storageName):
ProfileAdapter::~ProfileAdapter()
{
+ content::BrowserContext::NotifyWillBeDestroyed(m_profile.data());
while (!m_webContentsAdapterClients.isEmpty()) {
m_webContentsAdapterClients.first()->releaseProfile();
}
@@ -131,7 +132,9 @@ ProfileAdapter::~ProfileAdapter()
}
#if QT_CONFIG(ssl)
delete m_clientCertificateStore;
+ m_clientCertificateStore = nullptr;
#endif
+ WebEngineContext::flushMessages();
}
void ProfileAdapter::setStorageName(const QString &storageName)
diff --git a/src/core/profile_qt.cpp b/src/core/profile_qt.cpp
index 748104312..36303605f 100644
--- a/src/core/profile_qt.cpp
+++ b/src/core/profile_qt.cpp
@@ -111,7 +111,6 @@ ProfileQt::~ProfileQt()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
m_prefServiceAdapter.commit();
- content::BrowserContext::NotifyWillBeDestroyed(this);
BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(this);
ShutdownStoragePartitions();
m_profileIOData->shutdownOnUIThread();
diff --git a/src/core/qtwebengine_resources.gni b/src/core/qtwebengine_resources.gni
index 73ec8bda9..8eee4ada0 100644
--- a/src/core/qtwebengine_resources.gni
+++ b/src/core/qtwebengine_resources.gni
@@ -138,10 +138,12 @@ repack("qtwebengine_repack_resources_200") {
repack("qtwebengine_repack_resources_devtools") {
sources = [
"$root_gen_dir/content/browser/devtools/devtools_resources.pak",
+ "$root_gen_dir/third_party/blink/public/resources/inspector_overlay_resources.pak",
]
output = "$root_out_dir/qtwebengine_devtools_resources.pak"
deps = [
"//content/browser/devtools:devtools_resources_grit",
+ "//third_party/blink/public:devtools_inspector_resources",
]
}
diff --git a/src/core/qtwebengine_sources.gni b/src/core/qtwebengine_sources.gni
index 0f3e8b946..b14fc1049 100644
--- a/src/core/qtwebengine_sources.gni
+++ b/src/core/qtwebengine_sources.gni
@@ -75,6 +75,8 @@ source_set("qtwebengine_sources") {
"//chrome/browser/custom_handlers/protocol_handler_registry.h",
"//chrome/browser/custom_handlers/protocol_handler_registry_factory.cc",
"//chrome/browser/custom_handlers/protocol_handler_registry_factory.h",
+ "//chrome/browser/devtools/devtools_eye_dropper.cc",
+ "//chrome/browser/devtools/devtools_eye_dropper.h",
"//chrome/browser/media/webrtc/desktop_media_list.h",
"//chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc",
"//chrome/browser/net/chrome_mojo_proxy_resolver_factory.h",
@@ -208,7 +210,10 @@ source_set("qtwebengine_sources") {
"//components/pdf/browser:browser",
"//components/pdf/renderer:renderer",
"//components/printing/browser",
- "//components/printing/renderer",
+ "//components/printing/renderer"
+ ]
+ sources += [
+ "//chrome/browser/extensions/api/streams_private/streams_private_api.cc",
]
}
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 43ee36ed2..14622142c 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -57,8 +57,10 @@
#include "components/viz/common/surfaces/frame_sink_id_allocator.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "content/browser/compositor/image_transport_factory.h"
+#include "content/browser/renderer_host/display_util.h"
#include "content/browser/renderer_host/frame_tree.h"
#include "content/browser/renderer_host/frame_tree_node.h"
+#include "content/browser/renderer_host/cursor_manager.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
@@ -70,6 +72,7 @@
#include "content/common/input_messages.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/cursor/cursor.h"
+#include "ui/base/resource/resource_bundle.h"
#include "ui/events/blink/blink_event_util.h"
#include "ui/events/event.h"
#include "ui/events/gesture_detection/gesture_configuration.h"
@@ -83,7 +86,10 @@
#if defined(USE_AURA)
#include "ui/base/cursor/cursor_size.h"
#include "ui/base/cursor/cursors_aura.h"
-#include "ui/base/resource/resource_bundle.h"
+#endif
+
+#if defined(Q_OS_MACOS)
+#include "content/app/resources/grit/content_resources.h"
#endif
#include <QGuiApplication>
@@ -122,6 +128,20 @@ static inline ui::GestureProvider::Config QtGestureProviderConfig() {
return config;
}
+extern display::Display toDisplayDisplay(int id, const QScreen *screen);
+
+static blink::ScreenInfo screenInfoFromQScreen(QScreen *screen)
+{
+ blink::ScreenInfo r;
+ if (!screen)
+ screen = qApp->primaryScreen();
+ if (screen)
+ content::DisplayUtil::DisplayToScreenInfo(&r, toDisplayDisplay(0, screen));
+ else
+ r.device_scale_factor = qGuiApp->devicePixelRatio();
+ return r;
+}
+
// An minimal override to support progressing flings
class FlingingCompositor : public ui::Compositor
{
@@ -149,10 +169,33 @@ public:
}
};
+class GuestInputEventObserverQt : public content::RenderWidgetHost::InputEventObserver
+{
+public:
+ GuestInputEventObserverQt(RenderWidgetHostViewQt *rwhv)
+ : m_rwhv(rwhv)
+ {
+ }
+ ~GuestInputEventObserverQt() {}
+
+ void OnInputEvent(const blink::WebInputEvent&) override {}
+ void OnInputEventAck(blink::mojom::InputEventResultSource,
+ blink::mojom::InputEventResultState state,
+ const blink::WebInputEvent &event) override
+ {
+ if (event.GetType() == blink::WebInputEvent::Type::kMouseWheel)
+ m_rwhv->WheelEventAck(static_cast<const blink::WebMouseWheelEvent &>(event), state);
+ }
+
+private:
+ RenderWidgetHostViewQt *m_rwhv;
+};
+
RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget)
: content::RenderWidgetHostViewBase::RenderWidgetHostViewBase(widget)
, m_taskRunner(base::ThreadTaskRunnerHandle::Get())
, m_gestureProvider(QtGestureProviderConfig(), this)
+ , m_guestInputEventObserver(new GuestInputEventObserverQt(this))
, m_frameSinkId(host()->GetFrameSinkId())
, m_delegateClient(new RenderWidgetHostViewQtDelegateClient(this))
{
@@ -181,6 +224,8 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget
if (host()->delegate() && host()->delegate()->GetInputEventRouter())
host()->delegate()->GetInputEventRouter()->AddFrameSinkIdOwner(GetFrameSinkId(), this);
+ m_cursorManager.reset(new content::CursorManager(this));
+
m_touchSelectionControllerClient.reset(new TouchSelectionControllerClientQt(this));
ui::TouchSelectionController::Config config;
config.max_tap_duration = base::TimeDelta::FromMilliseconds(ui::GestureConfiguration::GetInstance()->long_press_time_in_ms());
@@ -207,6 +252,7 @@ RenderWidgetHostViewQt::~RenderWidgetHostViewQt()
m_touchSelectionControllerClient.reset();
host()->render_frame_metadata_provider()->RemoveObserver(this);
+ host()->ViewDestroyed();
}
void RenderWidgetHostViewQt::setDelegate(RenderWidgetHostViewQtDelegate* delegate)
@@ -230,6 +276,11 @@ void RenderWidgetHostViewQt::setAdapterClient(WebContentsAdapterClient *adapterC
m_adapterClient = nullptr; });
}
+void RenderWidgetHostViewQt::setGuest(content::RenderWidgetHostImpl *rwh)
+{
+ rwh->AddInputEventObserver(m_guestInputEventObserver.get());
+}
+
void RenderWidgetHostViewQt::InitAsChild(gfx::NativeView)
{
}
@@ -305,6 +356,11 @@ bool RenderWidgetHostViewQt::IsMouseLocked()
return m_isMouseLocked;
}
+viz::FrameSinkId RenderWidgetHostViewQt::GetRootFrameSinkId()
+{
+ return m_uiCompositor->frame_sink_id();
+}
+
bool RenderWidgetHostViewQt::IsSurfaceAvailableForCopy()
{
return m_delegatedFrameHost->CanCopyFromCompositingSurface();
@@ -388,6 +444,74 @@ void RenderWidgetHostViewQt::UnlockMouse()
host()->LostMouseLock();
}
+bool RenderWidgetHostViewQt::updateCursorFromResource(ui::mojom::CursorType type)
+{
+ int resourceId;
+ // GetCursorDataFor only knows hotspots for 1x and 2x cursor images, in physical pixels.
+ qreal hotspotDpr = m_screenInfo.device_scale_factor <= 1.0f ? 1.0f : 2.0f;
+ qreal hotX;
+ qreal hotY;
+
+#if defined(USE_AURA)
+ gfx::Point hotspot;
+ if (!ui::GetCursorDataFor(ui::CursorSize::kNormal, type, hotspotDpr, &resourceId, &hotspot))
+ return false;
+ hotX = hotspot.x();
+ hotY = hotspot.y();
+#elif defined(Q_OS_MACOS)
+ // See chromium/content/common/cursors/webcursor_mac.mm
+ switch (type) {
+ case ui::mojom::CursorType::kVerticalText:
+ // TODO: [NSCursor IBeamCursorForVerticalLayout]
+ return false;
+ case ui::mojom::CursorType::kCell:
+ resourceId = IDR_CELL_CURSOR;
+ hotX = 7;
+ hotY = 7;
+ break;
+ case ui::mojom::CursorType::kContextMenu:
+ // TODO: [NSCursor contextualMenuCursor]
+ return false;
+ case ui::mojom::CursorType::kZoomIn:
+ resourceId = IDR_ZOOMIN_CURSOR;
+ hotX = 7;
+ hotY = 7;
+ break;
+ case ui::mojom::CursorType::kZoomOut:
+ resourceId = IDR_ZOOMOUT_CURSOR;
+ hotX = 7;
+ hotY = 7;
+ break;
+ default:
+ Q_UNREACHABLE();
+ return false;
+ }
+#else
+ Q_UNREACHABLE();
+ return false;
+#endif
+
+ const gfx::ImageSkia *imageSkia = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resourceId);
+ if (!imageSkia)
+ return false;
+
+ QImage imageQt = toQImage(imageSkia->GetRepresentation(m_screenInfo.device_scale_factor));
+
+ // Convert hotspot coordinates into device-independent pixels.
+ hotX /= hotspotDpr;
+ hotY /= hotspotDpr;
+
+#if defined(Q_OS_LINUX)
+ // QTBUG-68571: On Linux (xcb, wayland, eglfs), hotspot coordinates must be in physical pixels.
+ qreal imageDpr = imageQt.devicePixelRatio();
+ hotX *= imageDpr;
+ hotY *= imageDpr;
+#endif
+
+ m_delegate->updateCursor(QCursor(QPixmap::fromImage(std::move(imageQt)), qRound(hotX), qRound(hotY)));
+ return true;
+}
+
void RenderWidgetHostViewQt::UpdateCursor(const content::WebCursor &webCursor)
{
DisplayCursor(webCursor);
@@ -397,9 +521,6 @@ void RenderWidgetHostViewQt::DisplayCursor(const content::WebCursor &webCursor)
{
const ui::Cursor &cursorInfo = webCursor.cursor();
Qt::CursorShape shape = Qt::ArrowCursor;
-#if defined(USE_AURA)
- ui::mojom::CursorType auraType = ui::mojom::CursorType::kNull;
-#endif
switch (cursorInfo.type()) {
case ui::mojom::CursorType::kNull:
case ui::mojom::CursorType::kPointer:
@@ -475,31 +596,14 @@ void RenderWidgetHostViewQt::DisplayCursor(const content::WebCursor &webCursor)
case ui::mojom::CursorType::kAlias:
shape = Qt::DragLinkCursor;
break;
-#if defined(USE_AURA)
- case ui::mojom::CursorType::kVerticalText:
- auraType = ui::mojom::CursorType::kVerticalText;
- break;
- case ui::mojom::CursorType::kCell:
- auraType = ui::mojom::CursorType::kCell;
- break;
- case ui::mojom::CursorType::kContextMenu:
- auraType = ui::mojom::CursorType::kContextMenu;
- break;
- case ui::mojom::CursorType::kZoomIn:
- auraType = ui::mojom::CursorType::kZoomIn;
- break;
- case ui::mojom::CursorType::kZoomOut:
- auraType = ui::mojom::CursorType::kZoomOut;
- break;
-#else
case ui::mojom::CursorType::kVerticalText:
case ui::mojom::CursorType::kCell:
case ui::mojom::CursorType::kContextMenu:
case ui::mojom::CursorType::kZoomIn:
case ui::mojom::CursorType::kZoomOut:
- // FIXME: Support on OS X
+ if (updateCursorFromResource(cursorInfo.type()))
+ return;
break;
-#endif
case ui::mojom::CursorType::kNoDrop:
case ui::mojom::CursorType::kNotAllowed:
shape = Qt::ForbiddenCursor;
@@ -521,36 +625,14 @@ void RenderWidgetHostViewQt::DisplayCursor(const content::WebCursor &webCursor)
}
break;
}
-#if defined(USE_AURA)
- if (auraType != ui::mojom::CursorType::kNull) {
- int resourceId;
- gfx::Point hotspot;
- // GetCursorDataFor only knows hotspots for 1x and 2x cursor images, in physical pixels.
- qreal hotspotDpr = m_screenInfo.device_scale_factor <= 1.0f ? 1.0f : 2.0f;
- if (ui::GetCursorDataFor(ui::CursorSize::kNormal, auraType, hotspotDpr, &resourceId, &hotspot)) {
- if (const gfx::ImageSkia *imageSkia = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resourceId)) {
- QImage imageQt = toQImage(imageSkia->GetRepresentation(m_screenInfo.device_scale_factor));
-
- // Convert hotspot coordinates into device-independent pixels.
- qreal hotX = hotspot.x() / hotspotDpr;
- qreal hotY = hotspot.y() / hotspotDpr;
-
-#if defined(Q_OS_LINUX)
- // QTBUG-68571: On Linux (xcb, wayland, eglfs), hotspot coordinates must be in physical pixels.
- qreal imageDpr = imageQt.devicePixelRatio();
- hotX *= imageDpr;
- hotY *= imageDpr;
-#endif
-
- m_delegate->updateCursor(QCursor(QPixmap::fromImage(std::move(imageQt)), qRound(hotX), qRound(hotY)));
- return;
- }
- }
- }
-#endif
m_delegate->updateCursor(QCursor(shape));
}
+content::CursorManager *RenderWidgetHostViewQt::GetCursorManager()
+{
+ return m_cursorManager.get();
+}
+
void RenderWidgetHostViewQt::SetIsLoading(bool)
{
// We use WebContentsDelegateQt::LoadingStateChanged to notify about loading state.
@@ -572,6 +654,18 @@ void RenderWidgetHostViewQt::RenderProcessGone()
Destroy();
}
+bool RenderWidgetHostViewQt::TransformPointToCoordSpaceForView(const gfx::PointF &point,
+ content::RenderWidgetHostViewBase *target_view,
+ gfx::PointF *transformed_point)
+{
+ if (target_view == this) {
+ *transformed_point = point;
+ return true;
+ }
+
+ return target_view->TransformPointToLocalCoordSpace(point, GetCurrentSurfaceId(), transformed_point);
+}
+
void RenderWidgetHostViewQt::Destroy()
{
delete this;
@@ -584,7 +678,7 @@ void RenderWidgetHostViewQt::SetTooltipText(const base::string16 &tooltip_text)
void RenderWidgetHostViewQt::DisplayTooltipText(const base::string16 &tooltip_text)
{
- if (m_adapterClient)
+ if (host()->delegate() && m_adapterClient)
m_adapterClient->setToolTip(toQt(tooltip_text));
}
@@ -606,8 +700,8 @@ void RenderWidgetHostViewQt::OnUpdateTextInputStateCalled(content::TextInputMana
const ui::mojom::TextInputState *state = text_input_manager_->GetTextInputState();
if (!state) {
- m_delegate->inputMethodStateChanged(false /*editorVisible*/, false /*passwordInput*/);
- m_delegate->setInputMethodHints(Qt::ImhNone);
+ // Do not reset input method state here because an editable node might be still focused and
+ // this would hide the virtual keyboard if a child of the focused node is removed.
return;
}
@@ -714,7 +808,8 @@ void RenderWidgetHostViewQt::OnGestureEvent(const ui::GestureEventData& gesture)
}
}
- host()->ForwardGestureEvent(event);
+ if (host()->delegate() && host()->delegate()->GetInputEventRouter())
+ host()->delegate()->GetInputEventRouter()->RouteGestureEvent(this, &event, ui::LatencyInfo());
}
void RenderWidgetHostViewQt::DidStopFlinging()
@@ -784,11 +879,11 @@ void RenderWidgetHostViewQt::processMotionEvent(const ui::MotionEvent &motionEve
auto result = m_gestureProvider.OnTouchEvent(motionEvent);
if (!result.succeeded)
return;
-
blink::WebTouchEvent touchEvent = ui::CreateWebTouchEventFromMotionEvent(motionEvent,
result.moved_beyond_slop_region,
false /*hovering, FIXME ?*/);
- host()->ForwardTouchEventWithLatencyInfo(touchEvent, CreateLatencyInfo(touchEvent));
+ if (host()->delegate() && host()->delegate()->GetInputEventRouter())
+ host()->delegate()->GetInputEventRouter()->RouteTouchEvent(this, &touchEvent, CreateLatencyInfo(touchEvent));
}
bool RenderWidgetHostViewQt::isPopup() const
@@ -800,17 +895,7 @@ bool RenderWidgetHostViewQt::updateScreenInfo()
{
blink::ScreenInfo oldScreenInfo = m_screenInfo;
QScreen *screen = m_delegate->window() ? m_delegate->window()->screen() : nullptr;
-
- if (screen) {
- m_screenInfo.device_scale_factor = screen->devicePixelRatio();
- m_screenInfo.depth_per_component = 8;
- m_screenInfo.depth = screen->depth();
- m_screenInfo.is_monochrome = (m_screenInfo.depth == 1);
- m_screenInfo.rect = toGfx(screen->geometry());
- m_screenInfo.available_rect = toGfx(screen->availableGeometry());
- } else {
- m_screenInfo.device_scale_factor = qGuiApp->devicePixelRatio();
- }
+ m_screenInfo = screenInfoFromQScreen(screen);
return (m_screenInfo != oldScreenInfo);
}
@@ -821,8 +906,9 @@ void RenderWidgetHostViewQt::handleWheelEvent(QWheelEvent *event)
Q_ASSERT(m_pendingWheelEvents.isEmpty());
blink::WebMouseWheelEvent webEvent = WebEventFactory::toWebWheelEvent(event);
m_wheelAckPending = (webEvent.phase != blink::WebMouseWheelEvent::kPhaseEnded);
- GetMouseWheelPhaseHandler()->AddPhaseIfNeededAndScheduleEndEvent(webEvent, false);
- host()->ForwardWheelEvent(webEvent);
+ GetMouseWheelPhaseHandler()->AddPhaseIfNeededAndScheduleEndEvent(webEvent, true);
+ if (host()->delegate() && host()->delegate()->GetInputEventRouter())
+ host()->delegate()->GetInputEventRouter()->RouteMouseWheelEvent(this, &webEvent, ui::LatencyInfo());
return;
}
if (!m_pendingWheelEvents.isEmpty()) {
@@ -842,8 +928,9 @@ void RenderWidgetHostViewQt::WheelEventAck(const blink::WebMouseWheelEvent &even
while (!m_pendingWheelEvents.isEmpty() && !m_wheelAckPending) {
blink::WebMouseWheelEvent webEvent = m_pendingWheelEvents.takeFirst();
m_wheelAckPending = (webEvent.phase != blink::WebMouseWheelEvent::kPhaseEnded);
- m_mouseWheelPhaseHandler.AddPhaseIfNeededAndScheduleEndEvent(webEvent, false);
- host()->ForwardWheelEvent(webEvent);
+ m_mouseWheelPhaseHandler.AddPhaseIfNeededAndScheduleEndEvent(webEvent, true);
+ if (host()->delegate() && host()->delegate()->GetInputEventRouter())
+ host()->delegate()->GetInputEventRouter()->RouteMouseWheelEvent(this, &webEvent, ui::LatencyInfo());
}
}
@@ -899,6 +986,15 @@ const viz::LocalSurfaceId &RenderWidgetHostViewQt::GetLocalSurfaceId() const
return m_dfhLocalSurfaceIdAllocator.GetCurrentLocalSurfaceId();
}
+void RenderWidgetHostViewQt::FocusedNodeChanged(bool is_editable_node, const gfx::Rect& node_bounds_in_screen)
+{
+ Q_UNUSED(node_bounds_in_screen);
+ if (!is_editable_node) {
+ m_delegate->inputMethodStateChanged(false /*editorVisible*/, false /*passwordInput*/);
+ m_delegate->setInputMethodHints(Qt::ImhNone);
+ }
+}
+
void RenderWidgetHostViewQt::TakeFallbackContentFrom(content::RenderWidgetHostView *view)
{
DCHECK(!static_cast<RenderWidgetHostViewBase*>(view)->IsRenderWidgetHostViewChildFrame());
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index fed831551..e01d91c84 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -68,6 +68,7 @@ class TouchSelectionController;
namespace QtWebEngineCore {
class RenderWidgetHostViewQtDelegateClient;
+class GuestInputEventObserverQt;
class TouchSelectionControllerClientQt;
class WebContentsAdapterClient;
@@ -87,6 +88,7 @@ public:
WebContentsAdapterClient *adapterClient() { return m_adapterClient; }
void setAdapterClient(WebContentsAdapterClient *adapterClient);
RenderWidgetHostViewQtDelegateClient *delegateClient() const { return m_delegateClient.get(); }
+ void setGuest(content::RenderWidgetHostImpl *);
void InitAsChild(gfx::NativeView) override;
void InitAsPopup(content::RenderWidgetHostView*, const gfx::Rect&) override;
@@ -98,6 +100,7 @@ public:
void Focus() override;
bool HasFocus() override;
bool IsMouseLocked() override;
+ viz::FrameSinkId GetRootFrameSinkId() override;
bool IsSurfaceAvailableForCopy() override;
void CopyFromSurface(const gfx::Rect &src_rect,
const gfx::Size &output_size,
@@ -112,10 +115,14 @@ public:
void UnlockMouse() override;
void UpdateCursor(const content::WebCursor&) override;
void DisplayCursor(const content::WebCursor&) override;
+ content::CursorManager *GetCursorManager() override;
void SetIsLoading(bool) override;
void ImeCancelComposition() override;
void ImeCompositionRangeChanged(const gfx::Range&, const std::vector<gfx::Rect>&) override;
void RenderProcessGone() override;
+ bool TransformPointToCoordSpaceForView(const gfx::PointF &point,
+ content::RenderWidgetHostViewBase *target_view,
+ gfx::PointF *transformed_point) override;
void Destroy() override;
void SetTooltipText(const base::string16 &tooltip_text) override;
void DisplayTooltipText(const base::string16& tooltip_text) override;
@@ -127,13 +134,15 @@ public:
viz::ScopedSurfaceIdAllocator DidUpdateVisualProperties(const cc::RenderFrameMetadata &metadata) override;
void OnDidUpdateVisualPropertiesComplete(const cc::RenderFrameMetadata &metadata);
+ // Overridden from RenderWidgetHostViewBase:
void GetScreenInfo(blink::ScreenInfo *results) override;
gfx::Rect GetBoundsInRootWindow() override;
void ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch,
blink::mojom::InputEventResultState ack_result) override;
viz::SurfaceId GetCurrentSurfaceId() const override;
const viz::FrameSinkId &GetFrameSinkId() const override;
- const viz::LocalSurfaceId &GetLocalSurfaceId() const;
+ const viz::LocalSurfaceId &GetLocalSurfaceId() const override;
+ void FocusedNodeChanged(bool is_editable_node, const gfx::Rect& node_bounds_in_screen) override;
void TakeFallbackContentFrom(content::RenderWidgetHostView *view) override;
void EnsureSurfaceSynchronizedForWebTest() override;
@@ -195,8 +204,15 @@ private:
bool isPopup() const;
+ bool updateCursorFromResource(ui::mojom::CursorType type);
+
scoped_refptr<base::SingleThreadTaskRunner> m_taskRunner;
+
+ std::unique_ptr<content::CursorManager> m_cursorManager;
+
ui::FilteredGestureProvider m_gestureProvider;
+ std::unique_ptr<GuestInputEventObserverQt> m_guestInputEventObserver;
+
viz::FrameSinkId m_frameSinkId;
std::unique_ptr<RenderWidgetHostViewQtDelegateClient> m_delegateClient;
std::unique_ptr<RenderWidgetHostViewQtDelegate> m_delegate;
diff --git a/src/core/render_widget_host_view_qt_delegate_client.cpp b/src/core/render_widget_host_view_qt_delegate_client.cpp
index ef2d8ba25..305f4c1e9 100644
--- a/src/core/render_widget_host_view_qt_delegate_client.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_client.cpp
@@ -47,6 +47,7 @@
#include "web_event_factory.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
#include "ui/touch_selection/touch_selection_controller.h"
#include <QEvent>
@@ -94,7 +95,7 @@ QList<TouchPoint> RenderWidgetHostViewQtDelegateClient::mapTouchPointIds(const Q
[] (QSet<int> s, const TouchPoint &p) { s.insert(p.second.id()); return s; }).size());
for (auto &&point : qAsConst(input))
- if (point.state() == Qt::TouchPointReleased)
+ if (point.state() == QEventPoint::Released)
m_touchIdMapping.remove(point.id());
return output;
@@ -117,8 +118,8 @@ public:
// index is only valid for ACTION_DOWN and ACTION_UP and should correspond to the point causing it
// see blink_event_util.cc:ToWebTouchPointState for details
Q_ASSERT_X((action != Action::POINTER_DOWN && action != Action::POINTER_UP && index == -1)
- || (action == Action::POINTER_DOWN && index >= 0 && touchPoint(index).state() == Qt::TouchPointPressed)
- || (action == Action::POINTER_UP && index >= 0 && touchPoint(index).state() == Qt::TouchPointReleased),
+ || (action == Action::POINTER_DOWN && index >= 0 && touchPoint(index).state() == QEventPoint::Pressed)
+ || (action == Action::POINTER_UP && index >= 0 && touchPoint(index).state() == QEventPoint::Released),
"MotionEventQt", qPrintable(QString("action: %1, index: %2, state: %3").arg(int(action)).arg(index).arg(touchPoint(index).state())));
}
@@ -350,7 +351,10 @@ bool RenderWidgetHostViewQtDelegateClient::forwardEvent(QEvent *event)
return false;
#endif
case QEvent::HoverLeave:
- m_rwhv->host()->ForwardMouseEvent(WebEventFactory::toWebMouseEvent(event));
+ if (m_rwhv->host()->delegate() && m_rwhv->host()->delegate()->GetInputEventRouter()) {
+ auto webEvent = WebEventFactory::toWebMouseEvent(event);
+ m_rwhv->host()->delegate()->GetInputEventRouter()->RouteMouseEvent(m_rwhv, &webEvent, ui::LatencyInfo());
+ }
break;
default:
return false;
@@ -476,7 +480,8 @@ void RenderWidgetHostViewQtDelegateClient::handlePointerEvent(T *event)
#endif
}
- m_rwhv->host()->ForwardMouseEvent(webEvent);
+ if (m_rwhv->host()->delegate() && m_rwhv->host()->delegate()->GetInputEventRouter())
+ m_rwhv->host()->delegate()->GetInputEventRouter()->RouteMouseEvent(m_rwhv, &webEvent, ui::LatencyInfo());
}
void RenderWidgetHostViewQtDelegateClient::handleMouseEvent(QMouseEvent *event)
@@ -535,14 +540,14 @@ void RenderWidgetHostViewQtDelegateClient::handleKeyEvent(QKeyEvent *event)
std::vector<blink::mojom::EditCommandPtr> commands;
commands.emplace_back(blink::mojom::EditCommand::New(m_editCommand, ""));
m_editCommand.clear();
- m_rwhv->host()->ForwardKeyboardEventWithCommands(webEvent, latency, std::move(commands), nullptr);
+ m_rwhv->GetFocusedWidget()->ForwardKeyboardEventWithCommands(webEvent, latency, std::move(commands), nullptr);
return;
}
bool keyDownTextInsertion =
webEvent.GetType() == blink::WebInputEvent::Type::kRawKeyDown && webEvent.text[0];
webEvent.skip_in_browser = keyDownTextInsertion;
- m_rwhv->host()->ForwardKeyboardEvent(webEvent);
+ m_rwhv->GetFocusedWidget()->ForwardKeyboardEvent(webEvent);
if (keyDownTextInsertion) {
// Blink won't consume the RawKeyDown, but rather the Char event in this case.
@@ -550,7 +555,7 @@ void RenderWidgetHostViewQtDelegateClient::handleKeyEvent(QKeyEvent *event)
// The same os_event will be set on both NativeWebKeyboardEvents.
webEvent.skip_in_browser = false;
webEvent.SetType(blink::WebInputEvent::Type::kChar);
- m_rwhv->host()->ForwardKeyboardEvent(webEvent);
+ m_rwhv->GetFocusedWidget()->ForwardKeyboardEvent(webEvent);
}
}
@@ -733,14 +738,22 @@ void RenderWidgetHostViewQtDelegateClient::handleGestureEvent(QNativeGestureEven
const Qt::NativeGestureType type = event->gestureType();
// These are the only supported gestures by Chromium so far.
if (type == Qt::ZoomNativeGesture || type == Qt::SmartZoomNativeGesture) {
- m_rwhv->host()->ForwardGestureEvent(WebEventFactory::toWebGestureEvent(event));
+ auto *hostDelegate = m_rwhv->host()->delegate();
+ if (hostDelegate && hostDelegate->GetInputEventRouter()) {
+ auto webEvent = WebEventFactory::toWebGestureEvent(event);
+ hostDelegate->GetInputEventRouter()->RouteGestureEvent(m_rwhv, &webEvent, ui::LatencyInfo());
+ }
}
}
#endif
void RenderWidgetHostViewQtDelegateClient::handleHoverEvent(QHoverEvent *event)
{
- m_rwhv->host()->ForwardMouseEvent(WebEventFactory::toWebMouseEvent(event));
+ auto *hostDelegate = m_rwhv->host()->delegate();
+ if (hostDelegate && hostDelegate->GetInputEventRouter()) {
+ auto webEvent = WebEventFactory::toWebMouseEvent(event);
+ hostDelegate->GetInputEventRouter()->RouteMouseEvent(m_rwhv, &webEvent, ui::LatencyInfo());
+ }
}
void RenderWidgetHostViewQtDelegateClient::handleFocusEvent(QFocusEvent *event)
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp
index 86cc5d52a..ed7f98f23 100644
--- a/src/core/renderer/content_renderer_client_qt.cpp
+++ b/src/core/renderer/content_renderer_client_qt.cpp
@@ -90,6 +90,8 @@
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "common/extensions/extensions_client_qt.h"
#include "extensions/extensions_renderer_client_qt.h"
+#include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.h"
+#include "mojo/public/cpp/bindings/associated_remote.h"
#endif //ENABLE_EXTENSIONS
#if BUILDFLAG(ENABLE_PLUGINS)
@@ -219,6 +221,11 @@ void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame *render_fr
new printing::PrintRenderFrameHelper(render_frame, base::WrapUnique(new PrintWebViewHelperDelegateQt()));
#endif // QT_CONFIG(webengine_printing_and_pdf)
#if BUILDFLAG(ENABLE_EXTENSIONS)
+ blink::AssociatedInterfaceRegistry *associated_interfaces = render_frame_observer->associatedInterfaces();
+ associated_interfaces->AddInterface(base::BindRepeating(
+ &extensions::MimeHandlerViewContainerManager::BindReceiver,
+ render_frame->GetRoutingID()));
+
auto registry = std::make_unique<service_manager::BinderRegistry>();
ExtensionsRendererClientQt::GetInstance()->RenderFrameCreated(render_frame, render_frame_observer->registry());
#endif
@@ -336,6 +343,30 @@ std::unique_ptr<blink::WebPrescientNetworking> ContentRendererClientQt::CreatePr
return std::make_unique<network_hints::WebPrescientNetworkingImpl>(render_frame);
}
+bool ContentRendererClientQt::IsPluginHandledExternally(content::RenderFrame *render_frame,
+ const blink::WebElement &plugin_element,
+ const GURL &original_url,
+ const std::string &original_mime_type)
+{
+#if BUILDFLAG(ENABLE_EXTENSIONS) && BUILDFLAG(ENABLE_PLUGINS)
+ bool found = false;
+ content::WebPluginInfo plugin_info;
+ std::string mime_type;
+
+ render_frame->Send(new FrameHostMsg_GetPluginInfo(render_frame->GetRoutingID(), original_url,
+ render_frame->GetWebFrame()->Top()->GetSecurityOrigin(),
+ original_mime_type, &found, &plugin_info, &mime_type));
+
+ return extensions::MimeHandlerViewContainerManager::Get(
+ content::RenderFrame::FromWebFrame(
+ plugin_element.GetDocument().GetFrame()),
+ true /* create_if_does_not_exist */)
+ ->CreateFrameContainer(plugin_element, original_url, mime_type, plugin_info);
+#else
+ return false;
+#endif
+}
+
bool ContentRendererClientQt::OverrideCreatePlugin(content::RenderFrame *render_frame,
const blink::WebPluginParams &params,
blink::WebPlugin **plugin)
@@ -346,7 +377,6 @@ bool ContentRendererClientQt::OverrideCreatePlugin(content::RenderFrame *render_
#endif //ENABLE_EXTENSIONS
#if BUILDFLAG(ENABLE_PLUGINS)
- chrome::mojom::PluginInfoPtr plugin_info = chrome::mojom::PluginInfo::New();
content::WebPluginInfo info;
std::string mime_type;
bool found = false;
@@ -354,30 +384,18 @@ bool ContentRendererClientQt::OverrideCreatePlugin(content::RenderFrame *render_
render_frame->Send(new FrameHostMsg_GetPluginInfo(render_frame->GetRoutingID(), params.url,
render_frame->GetWebFrame()->Top()->GetSecurityOrigin(),
params.mime_type.Utf8(), &found, &info, &mime_type));
- if (!found) {
- *plugin = CreatePlugin(render_frame, params, *plugin_info);
- return true;
- }
+ if (!found)
+ *plugin = LoadablePluginPlaceholderQt::CreateLoadableMissingPlugin(render_frame, params)->plugin();
+ else
+ *plugin = render_frame->CreatePlugin(info, params, nullptr);
#endif // BUILDFLAG(ENABLE_PLUGINS)
- return content::ContentRendererClient::OverrideCreatePlugin(render_frame, params, plugin);
+ return true;
}
bool ContentRendererClientQt::IsOriginIsolatedPepperPlugin(const base::FilePath& plugin_path)
{
- return plugin_path.value() == FILE_PATH_LITERAL("internal-pdf-viewer/");
-}
-
-#if BUILDFLAG(ENABLE_PLUGINS)
-// static
-blink::WebPlugin* ContentRendererClientQt::CreatePlugin(content::RenderFrame* render_frame,
- const blink::WebPluginParams& original_params,
- const chrome::mojom::PluginInfo& plugin_info)
-{
- // If the browser plugin is to be enabled, this should be handled by the
- // renderer, so the code won't reach here due to the early exit in OverrideCreatePlugin.
- return LoadablePluginPlaceholderQt::CreateLoadableMissingPlugin(render_frame, original_params)->plugin();
+ return plugin_path.value() == FILE_PATH_LITERAL("internal-pdf-viewer");
}
-#endif //BUILDFLAG(ENABLE_PLUGINS)
#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
chrome::WebRtcLoggingAgentImpl *ContentRendererClientQt::GetWebRtcLoggingAgent()
diff --git a/src/core/renderer/content_renderer_client_qt.h b/src/core/renderer/content_renderer_client_qt.h
index 0b0a7b68c..a0faec531 100644
--- a/src/core/renderer/content_renderer_client_qt.h
+++ b/src/core/renderer/content_renderer_client_qt.h
@@ -47,7 +47,6 @@
#include "ppapi/buildflags/buildflags.h"
#if BUILDFLAG(ENABLE_PLUGINS)
-#include "qtwebengine/browser/plugin.mojom.h"
#include "third_party/blink/public/web/web_plugin_params.h"
#endif
@@ -113,6 +112,10 @@ public:
void RunScriptsAtDocumentStart(content::RenderFrame *render_frame) override;
void RunScriptsAtDocumentEnd(content::RenderFrame *render_frame) override;
void RunScriptsAtDocumentIdle(content::RenderFrame *render_frame) override;
+ bool IsPluginHandledExternally(content::RenderFrame *embedder_frame,
+ const blink::WebElement &plugin_element,
+ const GURL &original_url,
+ const std::string &original_mime_type);
bool OverrideCreatePlugin(content::RenderFrame *render_frame,
const blink::WebPluginParams &params,
blink::WebPlugin **plugin) override;
@@ -128,12 +131,6 @@ public:
bool RequiresWebComponentsV0(const GURL &url) override;
-#if BUILDFLAG(ENABLE_PLUGINS)
- static blink::WebPlugin* CreatePlugin(content::RenderFrame* render_frame,
- const blink::WebPluginParams& params,
- const chrome::mojom::PluginInfo& plugin_info);
-#endif
-
#if QT_CONFIG(webengine_webrtc) && QT_CONFIG(webengine_extensions)
chrome::WebRtcLoggingAgentImpl *GetWebRtcLoggingAgent();
#endif
diff --git a/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp b/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp
index 33c744f13..1b9de4d4d 100644
--- a/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp
+++ b/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp
@@ -48,6 +48,7 @@
#include "base/memory/ptr_util.h"
#include "chrome/renderer/pepper/pepper_flash_font_file_host.h"
+#include "chrome/renderer/pepper/pepper_uma_host.h"
#if QT_CONFIG(webengine_printing_and_pdf)
#include "components/pdf/renderer/pepper_pdf_host.h"
#endif // QT_CONFIG(webengine_printing_and_pdf)
@@ -127,6 +128,14 @@ std::unique_ptr<ppapi::host::ResourceHost> PepperRendererHostFactoryQt::CreateRe
}
}
#endif // QT_CONFIG(webengine_printing_and_pdf)
+
+ // Create a default ResourceHost for this message type to suppress
+ // "Failed to create PPAPI resource host" console error message.
+ switch (message.type()) {
+ case PpapiHostMsg_UMA_Create::ID:
+ return std::make_unique<ppapi::host::ResourceHost>(host_->GetPpapiHost(), instance, resource);
+ }
+
return nullptr;
}
diff --git a/src/core/renderer/render_frame_observer_qt.cpp b/src/core/renderer/render_frame_observer_qt.cpp
index fd900c292..77d325f3c 100644
--- a/src/core/renderer/render_frame_observer_qt.cpp
+++ b/src/core/renderer/render_frame_observer_qt.cpp
@@ -77,6 +77,12 @@ void RenderFrameObserverQt::DidCreatePepperPlugin(content::RendererPpapiHost *ho
}
#endif
+bool RenderFrameObserverQt::OnAssociatedInterfaceRequestForFrame(const std::string &interface_name,
+ mojo::ScopedInterfaceEndpointHandle *handle)
+{
+ return m_associated_interfaces.TryBindInterface(interface_name, handle);
+}
+
void RenderFrameObserverQt::WillDetach()
{
m_isFrameDetached = true;
diff --git a/src/core/renderer/render_frame_observer_qt.h b/src/core/renderer/render_frame_observer_qt.h
index 237185f8c..8803dde89 100644
--- a/src/core/renderer/render_frame_observer_qt.h
+++ b/src/core/renderer/render_frame_observer_qt.h
@@ -46,6 +46,7 @@
#include "content/public/renderer/render_frame_observer_tracker.h"
#include "ppapi/buildflags/buildflags.h"
#include "services/service_manager/public/cpp/binder_registry.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
namespace content {
class RenderFrame;
@@ -67,12 +68,18 @@ public:
#if QT_CONFIG(webengine_pepper_plugins)
void DidCreatePepperPlugin(content::RendererPpapiHost *host) override;
#endif
+ bool OnAssociatedInterfaceRequestForFrame(
+ const std::string &interface_name,
+ mojo::ScopedInterfaceEndpointHandle *handle) override;
void OnDestruct() override;
void WillDetach() override;
bool isFrameDetached() const;
service_manager::BinderRegistry *registry() { return &registry_; }
+ blink::AssociatedInterfaceRegistry *associatedInterfaces() {
+ return &m_associated_interfaces;
+ }
private:
DISALLOW_COPY_AND_ASSIGN(RenderFrameObserverQt);
@@ -81,6 +88,7 @@ private:
bool m_isFrameDetached;
service_manager::BinderRegistry registry_;
+ blink::AssociatedInterfaceRegistry m_associated_interfaces;
web_cache::WebCacheImpl *m_web_cache_impl;
};
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 014fb6482..0f41a53cb 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -1546,7 +1546,15 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD
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();
+ std::vector<content::WebContents *> innerWebContents = m_webContents->GetInnerWebContents();
+ if (!innerWebContents.empty())
+ targetWebContents = innerWebContents[0];
+
+ 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()),
diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp
index 93c48f268..9041f1489 100644
--- a/src/core/web_contents_view_qt.cpp
+++ b/src/core/web_contents_view_qt.cpp
@@ -46,7 +46,6 @@
#include "render_widget_host_view_qt.h"
#include "touch_selection_controller_client_qt.h"
#include "type_conversion.h"
-#include "web_contents_adapter_client.h"
#include "web_contents_adapter.h"
#include "web_engine_context.h"
#include "web_contents_delegate_qt.h"
@@ -209,7 +208,7 @@ ASSERT_ENUMS_MATCH(QWebEngineContextMenuRequest::CanSelectAll, blink::kCanSelect
ASSERT_ENUMS_MATCH(QWebEngineContextMenuRequest::CanTranslate, blink::kCanTranslate)
ASSERT_ENUMS_MATCH(QWebEngineContextMenuRequest::CanEditRichly, blink::kCanEditRichly)
-
+// static
void WebContentsViewQt::update(QWebEngineContextMenuRequest *request,
const content::ContextMenuParams &params, bool spellcheckEnabled)
{
diff --git a/src/core/web_contents_view_qt.h b/src/core/web_contents_view_qt.h
index 07a78016d..ff3b9d632 100644
--- a/src/core/web_contents_view_qt.h
+++ b/src/core/web_contents_view_qt.h
@@ -44,9 +44,14 @@
#include "content/browser/web_contents/web_contents_view.h"
#include "api/qtwebenginecoreglobal_p.h"
+#include "web_contents_adapter_client.h"
QT_FORWARD_DECLARE_CLASS(QWebEngineContextMenuRequest)
+namespace extensions {
+class MimeHandlerViewGuestDelegateQt;
+}
+
namespace content {
class WebContents;
}
@@ -131,6 +136,8 @@ private:
WebContentsAdapterClient *m_client;
WebContentsAdapterClient *m_factoryClient;
std::unique_ptr<QWebEngineContextMenuRequest> m_contextMenuRequest;
+
+ friend class extensions::MimeHandlerViewGuestDelegateQt;
};
} // namespace QtWebEngineCore
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 7f338efe8..94f214a07 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -431,6 +431,15 @@ void WebEngineContext::removeProfileAdapter(ProfileAdapter *profileAdapter)
m_profileAdapters.removeAll(profileAdapter);
}
+void WebEngineContext::flushMessages()
+{
+ if (!m_destroyed) {
+ base::MessagePump::Delegate *delegate = static_cast<
+ base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl *>(
+ WebEngineContext::current()->m_runLoop->delegate_);
+ while (delegate->DoWork().is_immediate()) { }
+ }
+}
void WebEngineContext::destroy()
{
if (m_devtoolsServer)
@@ -441,20 +450,17 @@ void WebEngineContext::destroy()
m_webrtcLogUploader->Shutdown();
#endif
- base::MessagePump::Delegate *delegate =
- static_cast<base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl *>(
- m_runLoop->delegate_);
// Normally the GPU thread is shut down when the GpuProcessHost is destroyed
// on IO thread (triggered by ~BrowserMainRunner). But by that time the UI
// task runner is not working anymore so we need to do this earlier.
cleanupVizProcess();
while (waitForViz) {
- while (delegate->DoWork().is_immediate()) { }
+ flushMessages();
QThread::msleep(50);
}
destroyGpuProcess();
// Flush the UI message loop before quitting.
- while (delegate->DoWork().is_immediate()) { }
+ flushMessages();
#if QT_CONFIG(webengine_printing_and_pdf)
// Kill print job manager early as it has a content::NotificationRegistrar
@@ -476,7 +482,7 @@ void WebEngineContext::destroy()
// Handle any events posted by browser-context shutdown.
// This should deliver all nessesery calls of DeleteSoon from PostTask
- while (delegate->DoWork().is_immediate()) { }
+ flushMessages();
m_devtoolsServer.reset();
m_runLoop->AfterRun();
@@ -596,23 +602,47 @@ bool WebEngineContext::isGpuServiceOnUIThread()
return !threadedGpu;
}
-static void appendToFeatureList(std::string &featureList, const char *feature)
+static void initializeFeatureList(base::CommandLine *commandLine, std::vector<std::string> enableFeatures, std::vector<std::string> disableFeatures)
{
- if (featureList.empty())
- featureList = feature;
- else
- featureList = featureList + "," + feature;
-}
+ std::string enableFeaturesString = base::JoinString(enableFeatures, ",");
+ if (commandLine->HasSwitch(switches::kEnableFeatures)) {
+ std::string commandLineEnableFeatures = commandLine->GetSwitchValueASCII(switches::kEnableFeatures);
-static void appendToFeatureSwitch(base::CommandLine *commandLine, const char *featureSwitch, std::string feature)
-{
- if (!commandLine->HasSwitch(featureSwitch)) {
- commandLine->AppendSwitchASCII(featureSwitch, feature);
- } else {
- std::string featureList = commandLine->GetSwitchValueASCII(featureSwitch);
- featureList = featureList + "," + feature;
- commandLine->AppendSwitchASCII(featureSwitch, featureList);
+ for (const std::string &enableFeature : base::SplitString(commandLineEnableFeatures, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
+ auto it = std::find(disableFeatures.begin(), disableFeatures.end(), enableFeature);
+ if (it == disableFeatures.end())
+ continue;
+
+ qWarning("An unsupported feature has been enabled from command line: %s\n"
+ "The feature is enabled but there is no guarantee that it will work or not break QtWebEngine.", enableFeature.c_str());
+
+ // If a feature is disabled and enabled at the same time, then it will be disabled.
+ // Remove feature from the disable list to make it possible to override from command line.
+ disableFeatures.erase(it);
+ }
+
+ enableFeaturesString = enableFeaturesString + "," + commandLineEnableFeatures;
}
+
+ std::string disableFeaturesString = base::JoinString(disableFeatures, ",");
+ if (commandLine->HasSwitch(switches::kDisableFeatures)) {
+ std::string commandLineDisableFeatures = commandLine->GetSwitchValueASCII(switches::kDisableFeatures);
+
+ for (const std::string &disableFeature : base::SplitString(commandLineDisableFeatures, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
+ auto it = std::find(enableFeatures.begin(), enableFeatures.end(), disableFeature);
+ if (it == enableFeatures.end())
+ continue;
+
+ qWarning("An essential feature has been disabled from command line: %s\n"
+ "The feature is disabled but there is no guarantee that it will not break QtWebEngine.", disableFeature.c_str());
+ }
+
+ disableFeaturesString = disableFeaturesString + "," + commandLineDisableFeatures;
+ }
+
+ commandLine->AppendSwitchASCII(switches::kEnableFeatures, enableFeaturesString);
+ commandLine->AppendSwitchASCII(switches::kDisableFeatures, disableFeaturesString);
+ base::FeatureList::InitializeInstance(enableFeaturesString, disableFeaturesString);
}
WebEngineContext::WebEngineContext()
@@ -683,55 +713,51 @@ WebEngineContext::WebEngineContext()
// Do not advertise a feature we have removed at compile time
parsedCommandLine->AppendSwitch(switches::kDisableSpeechAPI);
- std::string disableFeatures;
- std::string enableFeatures;
+ std::vector<std::string> disableFeatures;
+ std::vector<std::string> enableFeatures;
// Needed to allow navigations within pages that were set using setHtml(). One example is
// tst_QWebEnginePage::acceptNavigationRequest.
// This is deprecated behavior, and will be removed in a future Chromium version, as per
// upstream Chromium commit ba52f56207a4b9d70b34880fbff2352e71a06422.
- appendToFeatureList(enableFeatures, features::kAllowContentInitiatedDataUrlNavigations.name);
+ enableFeatures.push_back(features::kAllowContentInitiatedDataUrlNavigations.name);
- appendToFeatureList(enableFeatures, features::kTracingServiceInProcess.name);
+ enableFeatures.push_back(features::kTracingServiceInProcess.name);
// The video-capture service is not functioning at this moment (since 69)
- appendToFeatureList(disableFeatures, features::kMojoVideoCapture.name);
+ disableFeatures.push_back(features::kMojoVideoCapture.name);
#if defined(Q_OS_LINUX)
// broken and crashy (even upstream):
- appendToFeatureList(disableFeatures, features::kFontSrcLocalMatching.name);
+ disableFeatures.push_back(features::kFontSrcLocalMatching.name);
#endif
// We don't support the skia renderer (enabled by default on Linux since 80)
- appendToFeatureList(disableFeatures, features::kUseSkiaRenderer.name);
+ disableFeatures.push_back(features::kUseSkiaRenderer.name);
- appendToFeatureList(disableFeatures, network::features::kDnsOverHttpsUpgrade.name);
+ disableFeatures.push_back(network::features::kDnsOverHttpsUpgrade.name);
// When enabled, event.movement is calculated in blink instead of in browser.
- appendToFeatureList(disableFeatures, features::kConsolidatedMovementXY.name);
+ disableFeatures.push_back(features::kConsolidatedMovementXY.name);
// Avoid crashing when websites tries using this feature (since 83)
- appendToFeatureList(disableFeatures, features::kInstalledApp.name);
+ disableFeatures.push_back(features::kInstalledApp.name);
// Explicitly tell Chromium about default-on features we do not support
- appendToFeatureList(disableFeatures, features::kBackgroundFetch.name);
- appendToFeatureList(disableFeatures, features::kSmsReceiver.name);
- appendToFeatureList(disableFeatures, features::kWebPayments.name);
- appendToFeatureList(disableFeatures, features::kWebUsb.name);
- appendToFeatureList(disableFeatures, media::kPictureInPicture.name);
+ disableFeatures.push_back(features::kBackgroundFetch.name);
+ disableFeatures.push_back(features::kSmsReceiver.name);
+ disableFeatures.push_back(features::kWebPayments.name);
+ disableFeatures.push_back(features::kWebUsb.name);
+ disableFeatures.push_back(media::kPictureInPicture.name);
if (useEmbeddedSwitches) {
// embedded switches are based on the switches for Android, see content/browser/android/content_startup_flags.cc
- appendToFeatureList(enableFeatures, features::kOverlayScrollbar.name);
+ enableFeatures.push_back(features::kOverlayScrollbar.name);
parsedCommandLine->AppendSwitch(switches::kEnableViewport);
parsedCommandLine->AppendSwitch(switches::kMainFrameResizesAreOrientationChanges);
parsedCommandLine->AppendSwitch(cc::switches::kDisableCompositedAntialiasing);
}
- appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, disableFeatures);
- appendToFeatureSwitch(parsedCommandLine, switches::kEnableFeatures, enableFeatures);
- base::FeatureList::InitializeInstance(
- parsedCommandLine->GetSwitchValueASCII(switches::kEnableFeatures),
- parsedCommandLine->GetSwitchValueASCII(switches::kDisableFeatures));
+ initializeFeatureList(parsedCommandLine, enableFeatures, disableFeatures);
GLContextHelper::initialize();
diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h
index 63872bdfe..9ac598c67 100644
--- a/src/core/web_engine_context.h
+++ b/src/core/web_engine_context.h
@@ -108,6 +108,7 @@ public:
static WebEngineContext *current();
static void destroyContextPostRoutine();
static ProxyAuthentication qProxyNetworkAuthentication(QString host, int port);
+ static void flushMessages();
ProfileAdapter *createDefaultProfileAdapter();
ProfileAdapter *defaultProfileAdapter();
diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp
index c5cede929..47c4634b3 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -46,6 +46,7 @@
#include "components/spellcheck/spellcheck_buildflags.h"
#include "content/public/common/content_paths.h"
#include "sandbox/policy/switches.h"
+#include "ui/base/l10n/l10n_util.h"
#include "ui/base/ui_base_paths.h"
#include "ui/base/ui_base_switches.h"
@@ -353,18 +354,15 @@ base::string16 WebEngineLibraryInfo::getApplicationName()
std::string WebEngineLibraryInfo::getApplicationLocale()
{
base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess();
- if (!parsedCommandLine->HasSwitch(switches::kLang)) {
+ if (parsedCommandLine->HasSwitch(switches::kLang)) {
+ return parsedCommandLine->GetSwitchValueASCII(switches::kLang);
+ } else {
const QString &locale = QLocale().bcp47Name();
-
- // QLocale::bcp47Name returns "en" for American English locale. Chromium requires the "US" suffix
- // to clarify the dialect and ignores the shorter version.
- if (locale == "en")
- return "en-US";
-
- return locale.toStdString();
+ std::string resolvedLocale;
+ if (l10n_util::CheckAndResolveLocale(locale.toStdString(), &resolvedLocale))
+ return resolvedLocale;
}
-
- return parsedCommandLine->GetSwitchValueASCII(switches::kLang);
+ return "en-US";
}
#if defined(OS_WIN)