From a12c2ab3e13181924f7990d0f40d58554670f890 Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Thu, 23 Jan 2020 16:58:01 -0500 Subject: [PATCH] Add support for MimeHandlerViewInCrossProcessFrame (fixes issue #2727) The PDF loading documentation in extension_system.cc has be updated to describe the new code paths. To support delivery of input events to the mime handler renderer process it is now necessary to route events via the correct RWHV interface. For Aura-based platforms (Windows/Linux) this means RWHVAura::On*Event and for macOS this means RWHVMac::RouteOrProcess*Event. Since Aura uses UI event types these have become the source of truth on Aura-based platforms with conversion to Web event types when needed (primarily for OSR). This change also adds a timeout for CefProcessHostMsg_GetNewBrowserInfo to avoid a hung renderer process if the guest WebContents route is not registered via CefMimeHandlerViewGuestDelegate::OnGuestDetached as expected prior to CefBrowserInfoManager::OnGetNewBrowserInfo being called. This timeout can be disabled for testing purposes by passing the `--disable-new-browser-info-timeout` command-line flag. The `--disable-features=MimeHandlerViewInCrossProcessFrame` command-line flag can be used for a limited time to restore the previous implementation based on BrowserPlugin. That implementation will be deleted starting with the 3897 branch update. Known issues: - ExecuteJavaScript calls on the frame hosting the PDF extension will not be routed to the mime handler renderer process. - The PDF extension will not load successfully if blocked by ChromePluginPlaceholder and then manually continued via the "Run this plugin" context menu option (see https://crbug.com/533069#c41). --- BUILD.gn | 7 + libcef/browser/browser_host_impl.cc | 19 +- libcef/browser/browser_info_manager.cc | 77 +++++- libcef/browser/browser_info_manager.h | 8 +- libcef/browser/browser_platform_delegate.cc | 33 +-- libcef/browser/browser_platform_delegate.h | 35 +-- .../browser_platform_delegate_background.cc | 50 ++-- .../browser_platform_delegate_background.h | 26 +- libcef/browser/extensions/extension_system.cc | 110 +++++--- .../mime_handler_view_guest_delegate.cc | 47 ++-- .../mime_handler_view_guest_delegate.h | 5 +- .../pdf_web_contents_helper_client.cc | 9 +- .../browser_platform_delegate_native.cc | 25 +- .../native/browser_platform_delegate_native.h | 35 ++- .../browser_platform_delegate_native_aura.cc | 232 +++++++++++++++++ .../browser_platform_delegate_native_aura.h | 81 ++++++ .../browser_platform_delegate_native_linux.cc | 190 ++++---------- .../browser_platform_delegate_native_linux.h | 25 +- .../browser_platform_delegate_native_mac.h | 49 ++-- .../browser_platform_delegate_native_mac.mm | 173 +++++++++---- .../browser_platform_delegate_native_win.cc | 237 +++++------------- .../browser_platform_delegate_native_win.h | 26 +- .../osr/browser_platform_delegate_osr.cc | 87 ++++--- .../osr/browser_platform_delegate_osr.h | 28 +-- .../views/browser_platform_delegate_views.cc | 73 ++---- .../views/browser_platform_delegate_views.h | 26 +- libcef/common/cef_switches.cc | 4 + libcef/common/cef_switches.h | 1 + libcef/common/main_delegate.cc | 7 - libcef/renderer/blink_glue.cc | 6 + libcef/renderer/blink_glue.h | 3 + libcef/renderer/content_renderer_client.cc | 16 +- libcef/renderer/frame_impl.cc | 5 + libcef/renderer/render_frame_observer.cc | 8 + libcef/renderer/render_frame_observer.h | 8 + patch/patch.cfg | 6 +- ...> mime_handler_view_guest_1565_2727.patch} | 93 ++----- tests/ceftests/plugin_unittest.cc | 77 +----- 38 files changed, 1030 insertions(+), 917 deletions(-) create mode 100644 libcef/browser/native/browser_platform_delegate_native_aura.cc create mode 100644 libcef/browser/native/browser_platform_delegate_native_aura.h rename patch/patches/{browser_plugin_guest_1565.patch => mime_handler_view_guest_1565_2727.patch} (82%) diff --git a/BUILD.gn b/BUILD.gn index 141f860ab..4f9dfd061 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1098,6 +1098,13 @@ static_library("libcef_static") { ] } } + + if (is_win || is_linux) { + sources += [ + "libcef/browser/native/browser_platform_delegate_native_aura.cc", + "libcef/browser/native/browser_platform_delegate_native_aura.h", + ] + } } else { sources += [ # Provides stub implementations for the views static methods. diff --git a/libcef/browser/browser_host_impl.cc b/libcef/browser/browser_host_impl.cc index e88e13412..81f0404ee 100644 --- a/libcef/browser/browser_host_impl.cc +++ b/libcef/browser/browser_host_impl.cc @@ -1163,11 +1163,7 @@ void CefBrowserHostImpl::SendKeyEvent(const CefKeyEvent& event) { if (!web_contents() || !platform_delegate_) return; - content::NativeWebKeyboardEvent web_event(blink::WebInputEvent::kUndefined, - blink::WebInputEvent::kNoModifiers, - ui::EventTimeForNow()); - platform_delegate_->TranslateKeyEvent(web_event, event); - platform_delegate_->SendKeyEvent(web_event); + platform_delegate_->SendKeyEvent(event); } void CefBrowserHostImpl::SendMouseClickEvent(const CefMouseEvent& event, @@ -1184,10 +1180,7 @@ void CefBrowserHostImpl::SendMouseClickEvent(const CefMouseEvent& event, if (!web_contents() || !platform_delegate_) return; - blink::WebMouseEvent web_event; - platform_delegate_->TranslateClickEvent(web_event, event, type, mouseUp, - clickCount); - platform_delegate_->SendMouseEvent(web_event); + platform_delegate_->SendMouseClickEvent(event, type, mouseUp, clickCount); } void CefBrowserHostImpl::SendMouseMoveEvent(const CefMouseEvent& event, @@ -1202,9 +1195,7 @@ void CefBrowserHostImpl::SendMouseMoveEvent(const CefMouseEvent& event, if (!web_contents() || !platform_delegate_) return; - blink::WebMouseEvent web_event; - platform_delegate_->TranslateMoveEvent(web_event, event, mouseLeave); - platform_delegate_->SendMouseEvent(web_event); + platform_delegate_->SendMouseMoveEvent(event, mouseLeave); } void CefBrowserHostImpl::SendMouseWheelEvent(const CefMouseEvent& event, @@ -1225,9 +1216,7 @@ void CefBrowserHostImpl::SendMouseWheelEvent(const CefMouseEvent& event, if (!web_contents() || !platform_delegate_) return; - blink::WebMouseWheelEvent web_event; - platform_delegate_->TranslateWheelEvent(web_event, event, deltaX, deltaY); - platform_delegate_->SendMouseWheelEvent(web_event); + platform_delegate_->SendMouseWheelEvent(event, deltaX, deltaY); } void CefBrowserHostImpl::SendFocusEvent(bool setFocus) { diff --git a/libcef/browser/browser_info_manager.cc b/libcef/browser/browser_info_manager.cc index d29a4629e..23622dc91 100644 --- a/libcef/browser/browser_info_manager.cc +++ b/libcef/browser/browser_info_manager.cc @@ -11,9 +11,11 @@ #include "libcef/browser/extensions/browser_extensions_util.h" #include "libcef/browser/thread_util.h" #include "libcef/common/cef_messages.h" +#include "libcef/common/cef_switches.h" #include "libcef/common/extensions/extensions_util.h" #include "libcef/common/values_impl.h" +#include "base/command_line.h" #include "base/logging.h" #include "content/common/view_messages.h" #include "content/public/browser/render_frame_host.h" @@ -23,6 +25,9 @@ namespace { +// Timeout delay for new browser info responses. +const int64_t kNewBrowserInfoResponseTimeoutMs = 2000; + void TranslatePopupFeatures(const blink::mojom::WindowFeatures& webKitFeatures, CefPopupFeatures& features) { features.x = static_cast(webKitFeatures.x); @@ -44,7 +49,7 @@ CefBrowserInfoManager* g_info_manager = nullptr; } // namespace -CefBrowserInfoManager::CefBrowserInfoManager() : next_browser_id_(0) { +CefBrowserInfoManager::CefBrowserInfoManager() { DCHECK(!g_info_manager); g_info_manager = this; } @@ -86,10 +91,11 @@ scoped_refptr CefBrowserInfoManager::CreatePopupBrowserInfo( new CefBrowserInfo(++next_browser_id_, true, is_windowless, extra_info); browser_info_list_.push_back(browser_info); - // Continue any pending NewBrowserInfo requests. + // Continue any pending NewBrowserInfo request. auto it = pending_new_browser_info_map_.find(frame_id); if (it != pending_new_browser_info_map_.end()) { - SendNewBrowserInfoResponse(render_process_id, browser_info, false, + SendNewBrowserInfoResponse(render_process_id, browser_info, + false /* is_guest_view */, it->second->reply_msg); pending_new_browser_info_map_.erase(it); } @@ -287,13 +293,27 @@ void CefBrowserInfoManager::OnGetNewBrowserInfo(int render_process_id, DCHECK(pending_new_browser_info_map_.find(frame_id) == pending_new_browser_info_map_.end()); + const int timeout_id = ++next_timeout_id_; + // Queue the request. std::unique_ptr pending(new PendingNewBrowserInfo()); pending->render_process_id = render_process_id; pending->render_routing_id = render_routing_id; + pending->timeout_id = timeout_id; pending->reply_msg = reply_msg; pending_new_browser_info_map_.insert( std::make_pair(frame_id, std::move(pending))); + + // Register a timeout for the pending response so that the renderer process + // doesn't hang forever. + if (!base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableNewBrowserInfoTimeout)) { + CEF_POST_DELAYED_TASK( + CEF_UIT, + base::BindOnce(&CefBrowserInfoManager::TimeoutNewBrowserInfoResponse, + frame_id, timeout_id), + kNewBrowserInfoResponseTimeoutMs); + } } void CefBrowserInfoManager::RemoveBrowserInfo( @@ -498,19 +518,52 @@ void CefBrowserInfoManager::SendNewBrowserInfoResponse( } CefProcessHostMsg_GetNewBrowserInfo_Params params; - params.browser_id = browser_info->browser_id(); - params.is_windowless = browser_info->is_windowless(); - params.is_popup = browser_info->is_popup(); params.is_guest_view = is_guest_view; - auto extra_info = browser_info->extra_info(); - if (extra_info) { - auto extra_info_impl = - static_cast(extra_info.get()); - auto extra_info_value = extra_info_impl->CopyValue(); - extra_info_value->Swap(¶ms.extra_info); + if (browser_info) { + params.browser_id = browser_info->browser_id(); + params.is_windowless = browser_info->is_windowless(); + params.is_popup = browser_info->is_popup(); + + auto extra_info = browser_info->extra_info(); + if (extra_info) { + auto extra_info_impl = + static_cast(extra_info.get()); + auto extra_info_value = extra_info_impl->CopyValue(); + extra_info_value->Swap(¶ms.extra_info); + } + } else { + // The new browser info response has timed out. + params.browser_id = -1; } CefProcessHostMsg_GetNewBrowserInfo::WriteReplyParams(reply_msg, params); host->Send(reply_msg); } + +// static +void CefBrowserInfoManager::TimeoutNewBrowserInfoResponse(int64_t frame_id, + int timeout_id) { + if (!g_info_manager) + return; + + base::AutoLock lock_scope(g_info_manager->browser_info_lock_); + + // Continue the NewBrowserInfo request if it's still pending. + auto it = g_info_manager->pending_new_browser_info_map_.find(frame_id); + if (it != g_info_manager->pending_new_browser_info_map_.end()) { + const auto& pending_info = it->second; + // Don't accidentally timeout a new request for the same frame. + if (pending_info->timeout_id != timeout_id) + return; + + LOG(ERROR) << "Timeout of new browser info response for frame process id " + << pending_info->render_process_id << " and routing id " + << pending_info->render_routing_id; + + SendNewBrowserInfoResponse(pending_info->render_process_id, nullptr, + false /* is_guest_view */, + pending_info->reply_msg); + g_info_manager->pending_new_browser_info_map_.erase(it); + } +} diff --git a/libcef/browser/browser_info_manager.h b/libcef/browser/browser_info_manager.h index 5983a4834..3bdc1c7bc 100644 --- a/libcef/browser/browser_info_manager.h +++ b/libcef/browser/browser_info_manager.h @@ -201,10 +201,14 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver { bool is_guest_view, IPC::Message* reply_msg); + // Time out a response if it's still pending. + static void TimeoutNewBrowserInfoResponse(int64_t frame_id, int timeout_id); + // Pending request for OnGetNewBrowserInfo. struct PendingNewBrowserInfo { int render_process_id; int render_routing_id; + int timeout_id; IPC::Message* reply_msg; }; @@ -213,7 +217,7 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver { // Access to the below members must be protected by |browser_info_lock_|. BrowserInfoList browser_info_list_; - int next_browser_id_; + int next_browser_id_ = 0; // Map of frame ID to info. using PendingNewBrowserInfoMap = @@ -224,6 +228,8 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver { using PendingPopupList = std::vector>; PendingPopupList pending_popup_list_; + int next_timeout_id_ = 0; + DISALLOW_COPY_AND_ASSIGN(CefBrowserInfoManager); }; diff --git a/libcef/browser/browser_platform_delegate.cc b/libcef/browser/browser_platform_delegate.cc index 3f7b4c490..5a7790628 100644 --- a/libcef/browser/browser_platform_delegate.cc +++ b/libcef/browser/browser_platform_delegate.cc @@ -14,7 +14,7 @@ #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h" -CefBrowserPlatformDelegate::CefBrowserPlatformDelegate() : browser_(nullptr) {} +CefBrowserPlatformDelegate::CefBrowserPlatformDelegate() {} CefBrowserPlatformDelegate::~CefBrowserPlatformDelegate() { DCHECK(!browser_); @@ -237,32 +237,33 @@ base::RepeatingClosure CefBrowserPlatformDelegate::GetBoundsChangedCallback() { } // static -int CefBrowserPlatformDelegate::TranslateModifiers(uint32 cef_modifiers) { - int webkit_modifiers = 0; +int CefBrowserPlatformDelegate::TranslateWebEventModifiers( + uint32 cef_modifiers) { + int result = 0; // Set modifiers based on key state. if (cef_modifiers & EVENTFLAG_SHIFT_DOWN) - webkit_modifiers |= blink::WebInputEvent::kShiftKey; + result |= blink::WebInputEvent::kShiftKey; if (cef_modifiers & EVENTFLAG_CONTROL_DOWN) - webkit_modifiers |= blink::WebInputEvent::kControlKey; + result |= blink::WebInputEvent::kControlKey; if (cef_modifiers & EVENTFLAG_ALT_DOWN) - webkit_modifiers |= blink::WebInputEvent::kAltKey; + result |= blink::WebInputEvent::kAltKey; if (cef_modifiers & EVENTFLAG_COMMAND_DOWN) - webkit_modifiers |= blink::WebInputEvent::kMetaKey; + result |= blink::WebInputEvent::kMetaKey; if (cef_modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON) - webkit_modifiers |= blink::WebInputEvent::kLeftButtonDown; + result |= blink::WebInputEvent::kLeftButtonDown; if (cef_modifiers & EVENTFLAG_MIDDLE_MOUSE_BUTTON) - webkit_modifiers |= blink::WebInputEvent::kMiddleButtonDown; + result |= blink::WebInputEvent::kMiddleButtonDown; if (cef_modifiers & EVENTFLAG_RIGHT_MOUSE_BUTTON) - webkit_modifiers |= blink::WebInputEvent::kRightButtonDown; + result |= blink::WebInputEvent::kRightButtonDown; if (cef_modifiers & EVENTFLAG_CAPS_LOCK_ON) - webkit_modifiers |= blink::WebInputEvent::kCapsLockOn; + result |= blink::WebInputEvent::kCapsLockOn; if (cef_modifiers & EVENTFLAG_NUM_LOCK_ON) - webkit_modifiers |= blink::WebInputEvent::kNumLockOn; + result |= blink::WebInputEvent::kNumLockOn; if (cef_modifiers & EVENTFLAG_IS_LEFT) - webkit_modifiers |= blink::WebInputEvent::kIsLeft; + result |= blink::WebInputEvent::kIsLeft; if (cef_modifiers & EVENTFLAG_IS_RIGHT) - webkit_modifiers |= blink::WebInputEvent::kIsRight; + result |= blink::WebInputEvent::kIsRight; if (cef_modifiers & EVENTFLAG_IS_KEY_PAD) - webkit_modifiers |= blink::WebInputEvent::kIsKeyPad; - return webkit_modifiers; + result |= blink::WebInputEvent::kIsKeyPad; + return result; } diff --git a/libcef/browser/browser_platform_delegate.h b/libcef/browser/browser_platform_delegate.h index 3cedf9f9b..2b7a110a7 100644 --- a/libcef/browser/browser_platform_delegate.h +++ b/libcef/browser/browser_platform_delegate.h @@ -148,11 +148,16 @@ class CefBrowserPlatformDelegate { virtual void SynchronizeVisualProperties() = 0; // Send input events. - virtual void SendKeyEvent(const content::NativeWebKeyboardEvent& event) = 0; - virtual void SendMouseEvent(const blink::WebMouseEvent& event) = 0; - virtual void SendMouseWheelEvent(const blink::WebMouseWheelEvent& event) = 0; - - // Send touch events. + virtual void SendKeyEvent(const CefKeyEvent& event) = 0; + virtual void SendMouseClickEvent(const CefMouseEvent& event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) = 0; + virtual void SendMouseMoveEvent(const CefMouseEvent& event, + bool mouseLeave) = 0; + virtual void SendMouseWheelEvent(const CefMouseEvent& event, + int deltaX, + int deltaY) = 0; virtual void SendTouchEvent(const CefTouchEvent& event) = 0; // Send focus event. The browser's WebContents may be NULL when this method is @@ -187,22 +192,6 @@ class CefBrowserPlatformDelegate { // Invoke platform specific handling for the external protocol. static void HandleExternalProtocol(const GURL& url); - // Translate CEF events to Chromium/Blink events. - virtual void TranslateKeyEvent(content::NativeWebKeyboardEvent& result, - const CefKeyEvent& key_event) const = 0; - virtual void TranslateClickEvent(blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - CefBrowserHost::MouseButtonType type, - bool mouseUp, - int clickCount) const = 0; - virtual void TranslateMoveEvent(blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - bool mouseLeave) const = 0; - virtual void TranslateWheelEvent(blink::WebMouseWheelEvent& result, - const CefMouseEvent& mouse_event, - int deltaX, - int deltaY) const = 0; - // Returns the OS event handle, if any, associated with |event|. virtual CefEventHandle GetEventHandle( const content::NativeWebKeyboardEvent& event) const = 0; @@ -287,9 +276,9 @@ class CefBrowserPlatformDelegate { base::RepeatingClosure GetBoundsChangedCallback(); - static int TranslateModifiers(uint32 cef_modifiers); + static int TranslateWebEventModifiers(uint32 cef_modifiers); - CefBrowserHostImpl* browser_; // Not owned by this object. + CefBrowserHostImpl* browser_ = nullptr; // Not owned by this object. private: // Used for the print preview dialog. diff --git a/libcef/browser/extensions/browser_platform_delegate_background.cc b/libcef/browser/extensions/browser_platform_delegate_background.cc index a9c4e3d85..ae2ac9525 100644 --- a/libcef/browser/extensions/browser_platform_delegate_background.cc +++ b/libcef/browser/extensions/browser_platform_delegate_background.cc @@ -52,17 +52,28 @@ void CefBrowserPlatformDelegateBackground::SynchronizeVisualProperties() { } void CefBrowserPlatformDelegateBackground::SendKeyEvent( - const content::NativeWebKeyboardEvent& event) { + const CefKeyEvent& event) { // Nothing to do here. } -void CefBrowserPlatformDelegateBackground::SendMouseEvent( - const blink::WebMouseEvent& event) { +void CefBrowserPlatformDelegateBackground::SendMouseClickEvent( + const CefMouseEvent& event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) { + // Nothing to do here. +} + +void CefBrowserPlatformDelegateBackground::SendMouseMoveEvent( + const CefMouseEvent& event, + bool mouseLeave) { // Nothing to do here. } void CefBrowserPlatformDelegateBackground::SendMouseWheelEvent( - const blink::WebMouseWheelEvent& event) { + const CefMouseEvent& event, + int deltaX, + int deltaY) { // Nothing to do here. } @@ -91,37 +102,6 @@ bool CefBrowserPlatformDelegateBackground::HandleKeyboardEvent( return false; } -void CefBrowserPlatformDelegateBackground::TranslateKeyEvent( - content::NativeWebKeyboardEvent& result, - const CefKeyEvent& key_event) const { - native_delegate_->TranslateKeyEvent(result, key_event); -} - -void CefBrowserPlatformDelegateBackground::TranslateClickEvent( - blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - CefBrowserHost::MouseButtonType type, - bool mouseUp, - int clickCount) const { - native_delegate_->TranslateClickEvent(result, mouse_event, type, mouseUp, - clickCount); -} - -void CefBrowserPlatformDelegateBackground::TranslateMoveEvent( - blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - bool mouseLeave) const { - native_delegate_->TranslateMoveEvent(result, mouse_event, mouseLeave); -} - -void CefBrowserPlatformDelegateBackground::TranslateWheelEvent( - blink::WebMouseWheelEvent& result, - const CefMouseEvent& mouse_event, - int deltaX, - int deltaY) const { - native_delegate_->TranslateWheelEvent(result, mouse_event, deltaX, deltaY); -} - CefEventHandle CefBrowserPlatformDelegateBackground::GetEventHandle( const content::NativeWebKeyboardEvent& event) const { return native_delegate_->GetEventHandle(event); diff --git a/libcef/browser/extensions/browser_platform_delegate_background.h b/libcef/browser/extensions/browser_platform_delegate_background.h index 48a9b4b07..a8df4f5e6 100644 --- a/libcef/browser/extensions/browser_platform_delegate_background.h +++ b/libcef/browser/extensions/browser_platform_delegate_background.h @@ -25,29 +25,21 @@ class CefBrowserPlatformDelegateBackground bool CanUseSharedTexture() const override; bool CanUseExternalBeginFrame() const override; void SynchronizeVisualProperties() override; - void SendKeyEvent(const content::NativeWebKeyboardEvent& event) override; - void SendMouseEvent(const blink::WebMouseEvent& event) override; - void SendMouseWheelEvent(const blink::WebMouseWheelEvent& event) override; + void SendKeyEvent(const CefKeyEvent& event) override; + void SendMouseClickEvent(const CefMouseEvent& event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) override; + void SendMouseMoveEvent(const CefMouseEvent& event, bool mouseLeave) override; + void SendMouseWheelEvent(const CefMouseEvent& event, + int deltaX, + int deltaY) override; void SendTouchEvent(const CefTouchEvent& event) override; void SendFocusEvent(bool setFocus) override; gfx::Point GetScreenPoint(const gfx::Point& view) const override; void ViewText(const std::string& text) override; bool HandleKeyboardEvent( const content::NativeWebKeyboardEvent& event) override; - void TranslateKeyEvent(content::NativeWebKeyboardEvent& result, - const CefKeyEvent& key_event) const override; - void TranslateClickEvent(blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - CefBrowserHost::MouseButtonType type, - bool mouseUp, - int clickCount) const override; - void TranslateMoveEvent(blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - bool mouseLeave) const override; - void TranslateWheelEvent(blink::WebMouseWheelEvent& result, - const CefMouseEvent& mouse_event, - int deltaX, - int deltaY) const override; CefEventHandle GetEventHandle( const content::NativeWebKeyboardEvent& event) const override; std::unique_ptr CreateFileDialogRunner() override; diff --git a/libcef/browser/extensions/extension_system.cc b/libcef/browser/extensions/extension_system.cc index 61f652e0b..a3dc98d60 100644 --- a/libcef/browser/extensions/extension_system.cc +++ b/libcef/browser/extensions/extension_system.cc @@ -185,48 +185,78 @@ void CefExtensionSystem::Init() { content::NotificationService::NoDetails()); // Add the internal PDF extension. PDF loading works as follows: - // 1. PDF PPAPI plugin is registered to handle kPDFPluginOutOfProcessMimeType - // in libcef/common/content_client.cc ComputeBuiltInPlugins. - // 2. PDF extension is registered and associated with the "application/pdf" - // mime type by the below call to AddExtension. - // 3. A page requests a resource with the "application/pdf" mime type. For - // example, by loading a PDF file. + // 1. The PDF PPAPI plugin is registered in libcef/common/content_client.cc + // ComputeBuiltInPlugins to handle the kPDFPluginOutOfProcessMimeType. + // 2. The PDF extension is registered by the below call to AddExtension and + // associated with the "application/pdf" mime type. + // 3. Web content running in the owner CefBrowser requests to load a PDF file + // resource with the "application/pdf" mime type. This can be via a frame + // (main frame/iframe) or object/embed tag. // 4. PluginResponseInterceptorURLLoaderThrottle intercepts the PDF resource - // load in the browser process, generates a - // unique View ID that is associated with the resource request for later - // retrieval via MimeHandlerStreamManager and the - // chrome.mimeHandlerPrivate JS API (extensions/common/api/ - // mime_handler_private.idl), and returns the unique View ID via the - // |payload| argument. - // 5. The unique View ID arrives in the renderer process via - // ResourceLoader::DidReceiveData and triggers creation of a new Document. - // DOMImplementation::createDocument indirectly calls - // RendererBlinkPlatformImpl::getPluginList to retrieve the list of - // supported plugins from the browser process. If a plugin supports the - // "application/pdf" mime type then a PluginDocument is created and - // CefContentRendererClient::OverrideCreatePlugin is called. This then - // indirectly calls CefContentRendererClient::CreateBrowserPluginDelegate - // to create a MimeHandlerViewContainer. - // 6. A MimeHandlerViewGuest and CefMimeHandlerViewGuestDelegate is created in - // the browser process. - // 7. MimeHandlerViewGuest navigates to the PDF extension URL. - // 8. Access to PDF extension resources is checked by - // CefExtensionsBrowserClient::AllowCrossRendererResourceLoad. - // 9. PDF extension resources are provided from bundle via - // CefExtensionsBrowserClient::LoadResourceFromResourceBundle, - // CefContentBrowserClient::RegisterNonNetworkSubresourceURLLoaderFactories - // and CefComponentExtensionResourceManager. - // 10.The PDF extension (chrome/browser/resources/pdf/browser_api.js) calls - // chrome.mimeHandlerPrivate.getStreamInfo to retrieve the PDF resource - // stream. This API is implemented using Mojo as described in - // libcef/common/extensions/api/README.txt. - // 11.The PDF extension requests a plugin to handle - // kPDFPluginOutOfProcessMimeType which loads the PDF PPAPI plugin. - // 12.Routing of print-related commands are handled by ChromePDFPrintClient - // and CefPrintRenderFrameHelperDelegate in the renderer process. - // 13.The PDF extension is granted access to chrome://resources via - // CefExtensionWebContentsObserver::RenderViewCreated in the browser + // load in the browser process and registers the PDF resource as a stream + // via MimeHandlerStreamManager::AddStream. + // 5. PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse triggers + // creation of a MimeHandlerViewEmbedder in the browser process via + // MimeHandlerViewAttachHelper::OverrideBodyForInterceptedResponse. + // 6. MimeHandlerViewEmbedder::ReadyToCommitNavigation is called and sends a + // Mojo message to MimeHandlerViewContainerManager::SetInternalId in the + // owner renderer process. + // 7. The MimeHandlerViewContainerManager is created in the owner renderer + // process via MimeHandlerViewContainerManager::BindReceiver and the + // SetInternalId call arrives. + // 8. HTMLPlugInElement::RequestObject is called in the owner renderer process + // to handle the PDF file frame/object/embed tag. This results in calls to + // ContentBrowserClient::GetPluginMimeTypesWithExternalHandlers (browser + // process) and ContentRendererClient::IsPluginHandledExternally (owner + // renderer process), and determines that the plugin should be handled + // externally (handled_externally=true). + // 9. MimeHandlerViewContainerManager::IsManagedByContainerManager sends a + // Mojo message to MimeHandlerViewEmbedder::ReadyToCreateMimeHandlerView + // in the browser process. + // 10.MimeHandlerViewEmbedder::RenderFrameCreated triggers creation of a + // MimeHandlerViewGuest and CefMimeHandlerViewGuestDelegate in the browser // process. + // 11.MimeHandlerViewGuest::CreateWebContents creates a new guest WebContents + // (is_guest_view=true) to host the PDF extension and the PDF resource + // stream is retrieved via MimeHandlerStreamManager::ReleaseStream. + // 12.MimeHandlerViewGuest::DidAttachToEmbedder calls + // CefMimeHandlerViewGuestDelegate::OnGuestAttached to associate the guest + // WebContents routing IDs with the owner CefBrowser. MimeHandlerViewGuest + // then loads the extension URL (index.html) in the guest WebContents. + // 13.Creation of the RenderFrame in the guest renderer process triggers a + // sync IPC call from CefContentRendererClient::MaybeCreateBrowser to + // CefBrowserInfoManager::GetBrowserInfo in the browser process to retrieve + // the CefBrowser information, which will be immediately available due to + // step 12. + // 14.The PDF extension begins to load. Extension resource requests are + // handled via ExtensionURLLoaderFactory::CreateLoaderAndStart in the + // browser process. Access to PDF extension resources is checked by + // CefExtensionsBrowserClient::AllowCrossRendererResourceLoad and + // PDF extension resources are provided from bundle via + // CefExtensionsBrowserClient::LoadResourceFromResourceBundle + // and CefComponentExtensionResourceManager. Access to chrome://resources + // is granted via CefExtensionWebContentsObserver::RenderViewCreated. + // 15.The PDF extension calls chrome.mimeHandlerPrivate.getStreamInfo + // (chrome/browser/resources/pdf/browser_api.js) to retrieve the PDF + // resource stream. This API is implemented using Mojo as described in + // libcef/common/extensions/api/README.txt. + // 16.The PDF extension requests the PDF PPAPI plugin to handle + // kPDFPluginOutOfProcessMimeType. Approval arrives in the guest renderer + // process via ExtensionFrameHelper::OnExtensionResponse which calls + // NativeExtensionBindingsSystem::HandleResponse. This triggers creation of + // an HTMLPlugInElement via native V8 bindings to host the PDF plugin. + // 17.HTMLPlugInElement::RequestObject is called in the guest renderer process + // and determines that the PDF PPAPI plugin should be handled internally + // (handled_externally=false). A PluginDocument is created and + // CefContentRendererClient::OverrideCreatePlugin is called to create a + // WebPlugin. + // 18.The PDF extension and PDF plugin are now loaded. Print commands, if + // any, are handled in the guest renderer process by ChromePDFPrintClient + // and CefPrintRenderFrameHelperDelegate. + // 19.When navigating away from the PDF file or closing the owner CefBrowser + // the guest WebContents will be destroyed. This triggers a call to + // CefMimeHandlerViewGuestDelegate::OnGuestDetached which removes the + // routing ID association with the owner CefBrowser. if (PdfExtensionEnabled()) { LoadExtension(ParseManifest(pdf_extension_util::GetManifest()), base::FilePath(FILE_PATH_LITERAL("pdf")), true /* internal */, diff --git a/libcef/browser/extensions/mime_handler_view_guest_delegate.cc b/libcef/browser/extensions/mime_handler_view_guest_delegate.cc index 157e8afb6..32af32c41 100644 --- a/libcef/browser/extensions/mime_handler_view_guest_delegate.cc +++ b/libcef/browser/extensions/mime_handler_view_guest_delegate.cc @@ -17,22 +17,9 @@ namespace extensions { -namespace { - -CefRefPtr GetOwnerBrowser( - extensions::MimeHandlerViewGuest* guest) { - content::WebContents* owner_web_contents = guest->owner_web_contents(); - CefRefPtr owner_browser = - CefBrowserHostImpl::GetBrowserForContents(owner_web_contents); - DCHECK(owner_browser); - return owner_browser; -} - -} // namespace - CefMimeHandlerViewGuestDelegate::CefMimeHandlerViewGuestDelegate( MimeHandlerViewGuest* guest) - : guest_(guest) {} + : guest_(guest), owner_web_contents_(guest_->owner_web_contents()) {} CefMimeHandlerViewGuestDelegate::~CefMimeHandlerViewGuestDelegate() {} @@ -40,7 +27,10 @@ void CefMimeHandlerViewGuestDelegate::OverrideWebContentsCreateParams( content::WebContents::CreateParams* params) { DCHECK(params->guest_delegate); - CefRefPtr owner_browser = GetOwnerBrowser(guest_); + CefRefPtr owner_browser = + CefBrowserHostImpl::GetBrowserForContents(owner_web_contents_); + DCHECK(owner_browser); + if (owner_browser->IsWindowless()) { CefWebContentsViewOSR* view_osr = new CefWebContentsViewOSR( owner_browser->GetBackgroundColor(), false, false); @@ -49,24 +39,29 @@ void CefMimeHandlerViewGuestDelegate::OverrideWebContentsCreateParams( } } -void CefMimeHandlerViewGuestDelegate::OnGuestAttached( - content::WebContentsView* parent_view) { +void CefMimeHandlerViewGuestDelegate::OnGuestAttached() { content::WebContents* web_contents = guest_->web_contents(); DCHECK(web_contents); + CefRefPtr owner_browser = + CefBrowserHostImpl::GetBrowserForContents(owner_web_contents_); + DCHECK(owner_browser); + // Associate guest state information with the owner browser. - GetOwnerBrowser(guest_)->browser_info()->MaybeCreateFrame( - web_contents->GetMainFrame(), true /* is_guest_view */); + owner_browser->browser_info()->MaybeCreateFrame(web_contents->GetMainFrame(), + true /* is_guest_view */); } -void CefMimeHandlerViewGuestDelegate::OnGuestDetached( - content::WebContentsView* parent_view) { +void CefMimeHandlerViewGuestDelegate::OnGuestDetached() { content::WebContents* web_contents = guest_->web_contents(); DCHECK(web_contents); + CefRefPtr owner_browser = + CefBrowserHostImpl::GetBrowserForContents(owner_web_contents_); + DCHECK(owner_browser); + // Disassociate guest state information with the owner browser. - GetOwnerBrowser(guest_)->browser_info()->RemoveFrame( - web_contents->GetMainFrame()); + owner_browser->browser_info()->RemoveFrame(web_contents->GetMainFrame()); } bool CefMimeHandlerViewGuestDelegate::HandleContextMenu( @@ -83,7 +78,11 @@ bool CefMimeHandlerViewGuestDelegate::HandleContextMenu( new_params.x += guest_coordinates.x(); new_params.y += guest_coordinates.y(); - return GetOwnerBrowser(guest_)->HandleContextMenu(web_contents, new_params); + CefRefPtr owner_browser = + CefBrowserHostImpl::GetBrowserForContents(owner_web_contents_); + DCHECK(owner_browser); + + return owner_browser->HandleContextMenu(web_contents, new_params); } } // namespace extensions diff --git a/libcef/browser/extensions/mime_handler_view_guest_delegate.h b/libcef/browser/extensions/mime_handler_view_guest_delegate.h index ee6c9be7c..46e34cfac 100644 --- a/libcef/browser/extensions/mime_handler_view_guest_delegate.h +++ b/libcef/browser/extensions/mime_handler_view_guest_delegate.h @@ -23,13 +23,14 @@ class CefMimeHandlerViewGuestDelegate : public MimeHandlerViewGuestDelegate { // MimeHandlerViewGuestDelegate methods. void OverrideWebContentsCreateParams( content::WebContents::CreateParams* params) override; - void OnGuestAttached(content::WebContentsView* parent_view) override; - void OnGuestDetached(content::WebContentsView* parent_view) override; + void OnGuestAttached() override; + void OnGuestDetached() override; bool HandleContextMenu(content::WebContents* web_contents, const content::ContextMenuParams& params) override; private: MimeHandlerViewGuest* guest_; // Owns us. + content::WebContents* owner_web_contents_; DISALLOW_COPY_AND_ASSIGN(CefMimeHandlerViewGuestDelegate); }; diff --git a/libcef/browser/extensions/pdf_web_contents_helper_client.cc b/libcef/browser/extensions/pdf_web_contents_helper_client.cc index 950579068..910aa0e48 100644 --- a/libcef/browser/extensions/pdf_web_contents_helper_client.cc +++ b/libcef/browser/extensions/pdf_web_contents_helper_client.cc @@ -4,6 +4,8 @@ #include "libcef/browser/extensions/pdf_web_contents_helper_client.h" +#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h" + namespace extensions { CefPDFWebContentsHelperClient::CefPDFWebContentsHelperClient() {} @@ -21,6 +23,11 @@ void CefPDFWebContentsHelperClient::OnSaveURL(content::WebContents* contents) {} void CefPDFWebContentsHelperClient::SetPluginCanSave( content::WebContents* contents, - bool can_save) {} + bool can_save) { + auto* guest_view = + extensions::MimeHandlerViewGuest::FromWebContents(contents); + if (guest_view) + guest_view->SetPluginCanSave(can_save); +} } // namespace extensions diff --git a/libcef/browser/native/browser_platform_delegate_native.cc b/libcef/browser/native/browser_platform_delegate_native.cc index d056bb88a..0236dde32 100644 --- a/libcef/browser/native/browser_platform_delegate_native.cc +++ b/libcef/browser/native/browser_platform_delegate_native.cc @@ -8,6 +8,7 @@ #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h" +#include "third_party/blink/public/platform/web_mouse_event.h" CefBrowserPlatformDelegateNative::CefBrowserPlatformDelegateNative( const CefWindowInfo& window_info, @@ -38,30 +39,6 @@ void CefBrowserPlatformDelegateNative::SynchronizeVisualProperties() { host->GetWidget()->SynchronizeVisualProperties(); } -void CefBrowserPlatformDelegateNative::SendKeyEvent( - const content::NativeWebKeyboardEvent& event) { - content::RenderViewHost* host = browser_->web_contents()->GetRenderViewHost(); - if (host) - host->GetWidget()->ForwardKeyboardEvent(event); -} - -void CefBrowserPlatformDelegateNative::SendMouseEvent( - const blink::WebMouseEvent& event) { - content::RenderViewHost* host = browser_->web_contents()->GetRenderViewHost(); - if (host) - host->GetWidget()->ForwardMouseEvent(event); -} - -void CefBrowserPlatformDelegateNative::SendMouseWheelEvent( - const blink::WebMouseWheelEvent& event) { - content::RenderViewHost* host = browser_->web_contents()->GetRenderViewHost(); - if (host) - host->GetWidget()->ForwardWheelEvent(event); -} - -void CefBrowserPlatformDelegateNative::SendTouchEvent( - const CefTouchEvent& event) {} - bool CefBrowserPlatformDelegateNative::IsWindowless() const { return false; } diff --git a/libcef/browser/native/browser_platform_delegate_native.h b/libcef/browser/native/browser_platform_delegate_native.h index f87132b83..dc04cb513 100644 --- a/libcef/browser/native/browser_platform_delegate_native.h +++ b/libcef/browser/native/browser_platform_delegate_native.h @@ -29,25 +29,44 @@ class CefBrowserPlatformDelegateNative : public CefBrowserPlatformDelegate { bool CanUseExternalBeginFrame() const override; SkColor GetBackgroundColor() const override; void SynchronizeVisualProperties() override; - void SendKeyEvent(const content::NativeWebKeyboardEvent& event) override; - void SendMouseEvent(const blink::WebMouseEvent& event) override; - void SendMouseWheelEvent(const blink::WebMouseWheelEvent& event) override; - void SendTouchEvent(const CefTouchEvent& event) override; bool IsWindowless() const override; bool IsViewsHosted() const override; + // Translate CEF events to Chromium/Blink Web events. + virtual content::NativeWebKeyboardEvent TranslateWebKeyEvent( + const CefKeyEvent& key_event) const = 0; + virtual blink::WebMouseEvent TranslateWebClickEvent( + const CefMouseEvent& mouse_event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) const = 0; + virtual blink::WebMouseEvent TranslateWebMoveEvent( + const CefMouseEvent& mouse_event, + bool mouseLeave) const = 0; + virtual blink::WebMouseWheelEvent TranslateWebWheelEvent( + const CefMouseEvent& mouse_event, + int deltaX, + int deltaY) const = 0; + const CefWindowInfo& window_info() const { return window_info_; } - void set_windowless_handler(WindowlessHandler* handler) { - windowless_handler_ = handler; - } - protected: + // Delegates that can wrap a native delegate. + friend class CefBrowserPlatformDelegateBackground; + friend class CefBrowserPlatformDelegateOsr; + friend class CefBrowserPlatformDelegateViews; + CefBrowserPlatformDelegateNative(const CefWindowInfo& window_info, SkColor background_color, bool use_shared_texture, bool use_external_begin_frame); + // Methods used by delegates that can wrap a native delegate. + void set_windowless_handler(WindowlessHandler* handler) { + windowless_handler_ = handler; + } + void set_browser(CefBrowserHostImpl* browser) { browser_ = browser; } + CefWindowInfo window_info_; const SkColor background_color_; const bool use_shared_texture_; diff --git a/libcef/browser/native/browser_platform_delegate_native_aura.cc b/libcef/browser/native/browser_platform_delegate_native_aura.cc new file mode 100644 index 000000000..e97d2af85 --- /dev/null +++ b/libcef/browser/native/browser_platform_delegate_native_aura.cc @@ -0,0 +1,232 @@ +// Copyright 2020 The Chromium Embedded Framework Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "libcef/browser/native/browser_platform_delegate_native_aura.h" + +#include "content/browser/renderer_host/render_widget_host_view_aura.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_widget_host.h" +#include "ui/events/blink/blink_event_util.h" +#include "ui/events/blink/web_input_event.h" +#include "ui/gfx/geometry/vector2d.h" + +CefBrowserPlatformDelegateNativeAura::CefBrowserPlatformDelegateNativeAura( + const CefWindowInfo& window_info, + SkColor background_color, + bool use_shared_texture, + bool use_external_begin_frame) + : CefBrowserPlatformDelegateNative(window_info, + background_color, + use_shared_texture, + use_external_begin_frame) {} + +void CefBrowserPlatformDelegateNativeAura::SendKeyEvent( + const CefKeyEvent& event) { + auto view = GetHostView(); + if (!view) + return; + + ui::KeyEvent ui_event = TranslateUiKeyEvent(event); + view->OnKeyEvent(&ui_event); +} + +void CefBrowserPlatformDelegateNativeAura::SendMouseClickEvent( + const CefMouseEvent& event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) { + auto view = GetHostView(); + if (!view) + return; + + ui::MouseEvent ui_event = + TranslateUiClickEvent(event, type, mouseUp, clickCount); + view->OnMouseEvent(&ui_event); +} + +void CefBrowserPlatformDelegateNativeAura::SendMouseMoveEvent( + const CefMouseEvent& event, + bool mouseLeave) { + auto view = GetHostView(); + if (!view) + return; + + ui::MouseEvent ui_event = TranslateUiMoveEvent(event, mouseLeave); + view->OnMouseEvent(&ui_event); +} + +void CefBrowserPlatformDelegateNativeAura::SendMouseWheelEvent( + const CefMouseEvent& event, + int deltaX, + int deltaY) { + auto view = GetHostView(); + if (!view) + return; + + ui::MouseWheelEvent ui_event = TranslateUiWheelEvent(event, deltaX, deltaY); + view->OnMouseEvent(&ui_event); +} + +void CefBrowserPlatformDelegateNativeAura::SendTouchEvent( + const CefTouchEvent& event) { + NOTIMPLEMENTED(); +} + +content::NativeWebKeyboardEvent +CefBrowserPlatformDelegateNativeAura::TranslateWebKeyEvent( + const CefKeyEvent& key_event) const { + return content::NativeWebKeyboardEvent(TranslateUiKeyEvent(key_event)); +} + +blink::WebMouseEvent +CefBrowserPlatformDelegateNativeAura::TranslateWebClickEvent( + const CefMouseEvent& mouse_event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) const { + return ui::MakeWebMouseEvent( + TranslateUiClickEvent(mouse_event, type, mouseUp, clickCount)); +} + +blink::WebMouseEvent +CefBrowserPlatformDelegateNativeAura::TranslateWebMoveEvent( + const CefMouseEvent& mouse_event, + bool mouseLeave) const { + return ui::MakeWebMouseEvent(TranslateUiMoveEvent(mouse_event, mouseLeave)); +} + +blink::WebMouseWheelEvent +CefBrowserPlatformDelegateNativeAura::TranslateWebWheelEvent( + const CefMouseEvent& mouse_event, + int deltaX, + int deltaY) const { + return ui::MakeWebMouseWheelEvent( + TranslateUiWheelEvent(mouse_event, deltaX, deltaY)); +} + +ui::MouseEvent CefBrowserPlatformDelegateNativeAura::TranslateUiClickEvent( + const CefMouseEvent& mouse_event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) const { + DCHECK_GE(clickCount, 1); + + ui::EventType event_type = + mouseUp ? ui::ET_MOUSE_RELEASED : ui::ET_MOUSE_PRESSED; + gfx::PointF location(mouse_event.x, mouse_event.y); + gfx::PointF root_location( + GetScreenPoint(gfx::Point(mouse_event.x, mouse_event.y))); + base::TimeTicks time_stamp = GetEventTimeStamp(); + int flags = TranslateUiEventModifiers(mouse_event.modifiers); + + int changed_button_flags = 0; + switch (type) { + case MBT_LEFT: + changed_button_flags |= ui::EF_LEFT_MOUSE_BUTTON; + break; + case MBT_MIDDLE: + changed_button_flags |= ui::EF_MIDDLE_MOUSE_BUTTON; + break; + case MBT_RIGHT: + changed_button_flags |= ui::EF_RIGHT_MOUSE_BUTTON; + break; + default: + NOTREACHED(); + } + + ui::MouseEvent result(event_type, location, root_location, time_stamp, flags, + changed_button_flags); + result.SetClickCount(clickCount); + return result; +} + +ui::MouseEvent CefBrowserPlatformDelegateNativeAura::TranslateUiMoveEvent( + const CefMouseEvent& mouse_event, + bool mouseLeave) const { + ui::EventType event_type = + mouseLeave ? ui::ET_MOUSE_EXITED : ui::ET_MOUSE_MOVED; + gfx::PointF location(mouse_event.x, mouse_event.y); + gfx::PointF root_location( + GetScreenPoint(gfx::Point(mouse_event.x, mouse_event.y))); + base::TimeTicks time_stamp = GetEventTimeStamp(); + int flags = TranslateUiEventModifiers(mouse_event.modifiers); + + int changed_button_flags = 0; + if (!mouseLeave) { + changed_button_flags = TranslateUiChangedButtonFlags(mouse_event.modifiers); + } + + return ui::MouseEvent(event_type, location, root_location, time_stamp, flags, + changed_button_flags); +} + +ui::MouseWheelEvent CefBrowserPlatformDelegateNativeAura::TranslateUiWheelEvent( + const CefMouseEvent& mouse_event, + int deltaX, + int deltaY) const { + gfx::Vector2d offset(GetUiWheelEventOffset(deltaX, deltaY)); + DCHECK(!offset.IsZero()); + + gfx::PointF location(mouse_event.x, mouse_event.y); + gfx::PointF root_location( + GetScreenPoint(gfx::Point(mouse_event.x, mouse_event.y))); + base::TimeTicks time_stamp = GetEventTimeStamp(); + int flags = TranslateUiEventModifiers(mouse_event.modifiers); + int changed_button_flags = + TranslateUiChangedButtonFlags(mouse_event.modifiers); + + return ui::MouseWheelEvent(offset, location, root_location, time_stamp, flags, + changed_button_flags); +} + +gfx::Vector2d CefBrowserPlatformDelegateNativeAura::GetUiWheelEventOffset( + int deltaX, + int deltaY) const { + return gfx::Vector2d(deltaX, deltaY); +} + +// static +int CefBrowserPlatformDelegateNativeAura::TranslateUiEventModifiers( + uint32 cef_modifiers) { + int result = 0; + // Set modifiers based on key state. + if (cef_modifiers & EVENTFLAG_SHIFT_DOWN) + result |= ui::EF_SHIFT_DOWN; + if (cef_modifiers & EVENTFLAG_CONTROL_DOWN) + result |= ui::EF_CONTROL_DOWN; + if (cef_modifiers & EVENTFLAG_ALT_DOWN) + result |= ui::EF_ALT_DOWN; + if (cef_modifiers & EVENTFLAG_COMMAND_DOWN) + result |= ui::EF_COMMAND_DOWN; + if (cef_modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON) + result |= ui::EF_LEFT_MOUSE_BUTTON; + if (cef_modifiers & EVENTFLAG_MIDDLE_MOUSE_BUTTON) + result |= ui::EF_MIDDLE_MOUSE_BUTTON; + if (cef_modifiers & EVENTFLAG_RIGHT_MOUSE_BUTTON) + result |= ui::EF_RIGHT_MOUSE_BUTTON; + if (cef_modifiers & EVENTFLAG_CAPS_LOCK_ON) + result |= ui::EF_CAPS_LOCK_ON; + if (cef_modifiers & EVENTFLAG_NUM_LOCK_ON) + result |= ui::EF_NUM_LOCK_ON; + return result; +} + +// static +int CefBrowserPlatformDelegateNativeAura::TranslateUiChangedButtonFlags( + uint32 cef_modifiers) { + int result = 0; + if (cef_modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON) + result |= ui::EF_LEFT_MOUSE_BUTTON; + else if (cef_modifiers & EVENTFLAG_MIDDLE_MOUSE_BUTTON) + result |= ui::EF_MIDDLE_MOUSE_BUTTON; + else if (cef_modifiers & EVENTFLAG_RIGHT_MOUSE_BUTTON) + result |= ui::EF_RIGHT_MOUSE_BUTTON; + return result; +} + +content::RenderWidgetHostViewAura* +CefBrowserPlatformDelegateNativeAura::GetHostView() const { + return static_cast( + browser_->web_contents()->GetRenderWidgetHostView()); +} diff --git a/libcef/browser/native/browser_platform_delegate_native_aura.h b/libcef/browser/native/browser_platform_delegate_native_aura.h new file mode 100644 index 000000000..96b5a41d7 --- /dev/null +++ b/libcef/browser/native/browser_platform_delegate_native_aura.h @@ -0,0 +1,81 @@ +// Copyright 2020 The Chromium Embedded Framework Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CEF_LIBCEF_BROWSER_NATIVE_BROWSER_PLATFORM_DELEGATE_NATIVE_AURA_H_ +#define CEF_LIBCEF_BROWSER_NATIVE_BROWSER_PLATFORM_DELEGATE_NATIVE_AURA_H_ + +#include "libcef/browser/native/browser_platform_delegate_native.h" + +#include "ui/events/event.h" + +namespace content { +class RenderWidgetHostViewAura; +} + +namespace gfx { +class Vector2d; +} + +// Windowed browser implementation for Aura platforms. +class CefBrowserPlatformDelegateNativeAura + : public CefBrowserPlatformDelegateNative { + public: + CefBrowserPlatformDelegateNativeAura(const CefWindowInfo& window_info, + SkColor background_color, + bool use_shared_texture, + bool use_external_begin_frame); + + // CefBrowserPlatformDelegate methods: + void SendKeyEvent(const CefKeyEvent& event) override; + void SendMouseClickEvent(const CefMouseEvent& event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) override; + void SendMouseMoveEvent(const CefMouseEvent& event, bool mouseLeave) override; + void SendMouseWheelEvent(const CefMouseEvent& event, + int deltaX, + int deltaY) override; + void SendTouchEvent(const CefTouchEvent& event) override; + + // CefBrowserPlatformDelegateNative methods: + content::NativeWebKeyboardEvent TranslateWebKeyEvent( + const CefKeyEvent& key_event) const override; + blink::WebMouseEvent TranslateWebClickEvent( + const CefMouseEvent& mouse_event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) const override; + blink::WebMouseEvent TranslateWebMoveEvent(const CefMouseEvent& mouse_event, + bool mouseLeave) const override; + blink::WebMouseWheelEvent TranslateWebWheelEvent( + const CefMouseEvent& mouse_event, + int deltaX, + int deltaY) const override; + + // Translate CEF events to Chromium UI events. + virtual ui::KeyEvent TranslateUiKeyEvent( + const CefKeyEvent& key_event) const = 0; + virtual ui::MouseEvent TranslateUiClickEvent( + const CefMouseEvent& mouse_event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) const; + virtual ui::MouseEvent TranslateUiMoveEvent(const CefMouseEvent& mouse_event, + bool mouseLeave) const; + virtual ui::MouseWheelEvent TranslateUiWheelEvent( + const CefMouseEvent& mouse_event, + int deltaX, + int deltaY) const; + virtual gfx::Vector2d GetUiWheelEventOffset(int deltaX, int deltaY) const; + virtual base::TimeTicks GetEventTimeStamp() const = 0; + + protected: + static int TranslateUiEventModifiers(uint32 cef_modifiers); + static int TranslateUiChangedButtonFlags(uint32 cef_modifiers); + + private: + content::RenderWidgetHostViewAura* GetHostView() const; +}; + +#endif // CEF_LIBCEF_BROWSER_NATIVE_BROWSER_PLATFORM_DELEGATE_NATIVE_AURA_H_ diff --git a/libcef/browser/native/browser_platform_delegate_native_linux.cc b/libcef/browser/native/browser_platform_delegate_native_linux.cc index 906398f44..491610aa1 100644 --- a/libcef/browser/native/browser_platform_delegate_native_linux.cc +++ b/libcef/browser/native/browser_platform_delegate_native_linux.cc @@ -46,10 +46,10 @@ CefBrowserPlatformDelegateNativeLinux::CefBrowserPlatformDelegateNativeLinux( const CefWindowInfo& window_info, SkColor background_color, bool use_external_begin_frame) - : CefBrowserPlatformDelegateNative(window_info, - background_color, - false, - use_external_begin_frame), + : CefBrowserPlatformDelegateNativeAura(window_info, + background_color, + false, + use_external_begin_frame), host_window_created_(false), window_widget_(nullptr) {} @@ -256,129 +256,6 @@ bool CefBrowserPlatformDelegateNativeLinux::HandleKeyboardEvent( // static void CefBrowserPlatformDelegate::HandleExternalProtocol(const GURL& url) {} -void CefBrowserPlatformDelegateNativeLinux::TranslateKeyEvent( - content::NativeWebKeyboardEvent& result, - const CefKeyEvent& key_event) const { - result.windows_key_code = key_event.windows_key_code; - result.native_key_code = key_event.native_key_code; - result.is_system_key = key_event.is_system_key ? 1 : 0; - switch (key_event.type) { - case KEYEVENT_RAWKEYDOWN: - case KEYEVENT_KEYDOWN: - result.SetType(blink::WebInputEvent::kRawKeyDown); - break; - case KEYEVENT_KEYUP: - result.SetType(blink::WebInputEvent::kKeyUp); - break; - case KEYEVENT_CHAR: - result.SetType(blink::WebInputEvent::kChar); - break; - default: - NOTREACHED(); - } - -#if defined(USE_X11) - // Populate DOM values that will be passed to JavaScript handlers via - // KeyboardEvent. - result.dom_code = static_cast( - ui::KeycodeConverter::NativeKeycodeToDomCode(key_event.native_key_code)); - int keysym = ui::XKeysymForWindowsKeyCode( - static_cast(key_event.windows_key_code), - !!(key_event.modifiers & EVENTFLAG_SHIFT_DOWN)); - base::char16 ch = ui::GetUnicodeCharacterFromXKeySym(keysym); - result.dom_key = static_cast(ui::XKeySymToDomKey(keysym, ch)); - - result.text[0] = key_event.character; - result.unmodified_text[0] = key_event.unmodified_character; - - result.SetModifiers(result.GetModifiers() | - TranslateModifiers(key_event.modifiers)); -#endif // defined(USE_X11) -} - -void CefBrowserPlatformDelegateNativeLinux::TranslateClickEvent( - blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - CefBrowserHost::MouseButtonType type, - bool mouseUp, - int clickCount) const { - TranslateMouseEvent(result, mouse_event); - - switch (type) { - case MBT_LEFT: - result.SetType(mouseUp ? blink::WebInputEvent::kMouseUp - : blink::WebInputEvent::kMouseDown); - result.button = blink::WebMouseEvent::Button::kLeft; - break; - case MBT_MIDDLE: - result.SetType(mouseUp ? blink::WebInputEvent::kMouseUp - : blink::WebInputEvent::kMouseDown); - result.button = blink::WebMouseEvent::Button::kMiddle; - break; - case MBT_RIGHT: - result.SetType(mouseUp ? blink::WebInputEvent::kMouseUp - : blink::WebInputEvent::kMouseDown); - result.button = blink::WebMouseEvent::Button::kRight; - break; - default: - NOTREACHED(); - } - - result.click_count = clickCount; -} - -void CefBrowserPlatformDelegateNativeLinux::TranslateMoveEvent( - blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - bool mouseLeave) const { - TranslateMouseEvent(result, mouse_event); - - if (!mouseLeave) { - result.SetType(blink::WebInputEvent::kMouseMove); - if (mouse_event.modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON) - result.button = blink::WebMouseEvent::Button::kLeft; - else if (mouse_event.modifiers & EVENTFLAG_MIDDLE_MOUSE_BUTTON) - result.button = blink::WebMouseEvent::Button::kMiddle; - else if (mouse_event.modifiers & EVENTFLAG_RIGHT_MOUSE_BUTTON) - result.button = blink::WebMouseEvent::Button::kRight; - else - result.button = blink::WebMouseEvent::Button::kNoButton; - } else { - result.SetType(blink::WebInputEvent::kMouseLeave); - result.button = blink::WebMouseEvent::Button::kNoButton; - } - - result.click_count = 0; -} - -void CefBrowserPlatformDelegateNativeLinux::TranslateWheelEvent( - blink::WebMouseWheelEvent& result, - const CefMouseEvent& mouse_event, - int deltaX, - int deltaY) const { - result = blink::WebMouseWheelEvent(); - TranslateMouseEvent(result, mouse_event); - - result.SetType(blink::WebInputEvent::kMouseWheel); - - static const double scrollbarPixelsPerGtkTick = 40.0; - result.delta_x = deltaX; - result.delta_y = deltaY; - result.wheel_ticks_x = deltaX / scrollbarPixelsPerGtkTick; - result.wheel_ticks_y = deltaY / scrollbarPixelsPerGtkTick; - result.delta_units = - ui::input_types::ScrollGranularity::kScrollByPrecisePixel; - - if (mouse_event.modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON) - result.button = blink::WebMouseEvent::Button::kLeft; - else if (mouse_event.modifiers & EVENTFLAG_MIDDLE_MOUSE_BUTTON) - result.button = blink::WebMouseEvent::Button::kMiddle; - else if (mouse_event.modifiers & EVENTFLAG_RIGHT_MOUSE_BUTTON) - result.button = blink::WebMouseEvent::Button::kRight; - else - result.button = blink::WebMouseEvent::Button::kNoButton; -} - CefEventHandle CefBrowserPlatformDelegateNativeLinux::GetEventHandle( const content::NativeWebKeyboardEvent& event) const { if (!event.os_event) @@ -392,27 +269,6 @@ CefBrowserPlatformDelegateNativeLinux::CreateMenuRunner() { return base::WrapUnique(new CefMenuRunnerLinux); } -void CefBrowserPlatformDelegateNativeLinux::TranslateMouseEvent( - blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event) const { - // position - result.SetPositionInWidget(mouse_event.x, mouse_event.y); - - const gfx::Point& screen_pt = - GetScreenPoint(gfx::Point(mouse_event.x, mouse_event.y)); - result.SetPositionInScreen(screen_pt.x(), screen_pt.y()); - - // modifiers - result.SetModifiers(result.GetModifiers() | - TranslateModifiers(mouse_event.modifiers)); - - // timestamp - result.SetTimeStamp(base::TimeTicks() + - base::TimeDelta::FromSeconds(GetSystemUptime())); - - result.pointer_type = blink::WebPointerProperties::PointerType::kMouse; -} - gfx::Point CefBrowserPlatformDelegateNativeLinux::GetDialogPosition( const gfx::Size& size) { const gfx::Size& max_size = GetMaximumDialogSize(); @@ -423,3 +279,41 @@ gfx::Point CefBrowserPlatformDelegateNativeLinux::GetDialogPosition( gfx::Size CefBrowserPlatformDelegateNativeLinux::GetMaximumDialogSize() { return GetWindowWidget()->GetWindowBoundsInScreen().size(); } + +ui::KeyEvent CefBrowserPlatformDelegateNativeLinux::TranslateUiKeyEvent( + const CefKeyEvent& key_event) const { + int flags = TranslateUiEventModifiers(key_event.modifiers); + ui::KeyboardCode key_code = + static_cast(key_event.windows_key_code); + ui::DomCode dom_code = + ui::KeycodeConverter::NativeKeycodeToDomCode(key_event.native_key_code); + int keysym = ui::XKeysymForWindowsKeyCode( + key_code, !!(key_event.modifiers & EVENTFLAG_SHIFT_DOWN)); + base::char16 character = ui::GetUnicodeCharacterFromXKeySym(keysym); + base::TimeTicks time_stamp = GetEventTimeStamp(); + + if (key_event.type == KEYEVENT_CHAR) { + return ui::KeyEvent(character, key_code, dom_code, flags, time_stamp); + } + + ui::EventType type = ui::ET_UNKNOWN; + switch (key_event.type) { + case KEYEVENT_RAWKEYDOWN: + case KEYEVENT_KEYDOWN: + type = ui::ET_KEY_PRESSED; + break; + case KEYEVENT_KEYUP: + type = ui::ET_KEY_RELEASED; + break; + default: + NOTREACHED(); + } + + ui::DomKey dom_key = ui::XKeySymToDomKey(keysym, character); + return ui::KeyEvent(type, key_code, dom_code, flags, dom_key, time_stamp); +} + +base::TimeTicks CefBrowserPlatformDelegateNativeLinux::GetEventTimeStamp() + const { + return base::TimeTicks() + base::TimeDelta::FromSeconds(GetSystemUptime()); +} diff --git a/libcef/browser/native/browser_platform_delegate_native_linux.h b/libcef/browser/native/browser_platform_delegate_native_linux.h index 2249114bb..96ee95a76 100644 --- a/libcef/browser/native/browser_platform_delegate_native_linux.h +++ b/libcef/browser/native/browser_platform_delegate_native_linux.h @@ -5,7 +5,7 @@ #ifndef CEF_LIBCEF_BROWSER_NATIVE_BROWSER_PLATFORM_DELEGATE_NATIVE_LINUX_H_ #define CEF_LIBCEF_BROWSER_NATIVE_BROWSER_PLATFORM_DELEGATE_NATIVE_LINUX_H_ -#include "libcef/browser/native/browser_platform_delegate_native.h" +#include "libcef/browser/native/browser_platform_delegate_native_aura.h" #if defined(USE_X11) class CefWindowX11; @@ -13,7 +13,7 @@ class CefWindowX11; // Windowed browser implementation for Linux. class CefBrowserPlatformDelegateNativeLinux - : public CefBrowserPlatformDelegateNative { + : public CefBrowserPlatformDelegateNativeAura { public: CefBrowserPlatformDelegateNativeLinux(const CefWindowInfo& window_info, SkColor background_color, @@ -32,30 +32,17 @@ class CefBrowserPlatformDelegateNativeLinux void ViewText(const std::string& text) override; bool HandleKeyboardEvent( const content::NativeWebKeyboardEvent& event) override; - void TranslateKeyEvent(content::NativeWebKeyboardEvent& result, - const CefKeyEvent& key_event) const override; - void TranslateClickEvent(blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - CefBrowserHost::MouseButtonType type, - bool mouseUp, - int clickCount) const override; - void TranslateMoveEvent(blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - bool mouseLeave) const override; - void TranslateWheelEvent(blink::WebMouseWheelEvent& result, - const CefMouseEvent& mouse_event, - int deltaX, - int deltaY) const override; CefEventHandle GetEventHandle( const content::NativeWebKeyboardEvent& event) const override; std::unique_ptr CreateMenuRunner() override; gfx::Point GetDialogPosition(const gfx::Size& size) override; gfx::Size GetMaximumDialogSize() override; - private: - void TranslateMouseEvent(blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event) const; + // CefBrowserPlatformDelegateNativeAura methods: + ui::KeyEvent TranslateUiKeyEvent(const CefKeyEvent& key_event) const override; + base::TimeTicks GetEventTimeStamp() const override; + private: // True if the host window has been created. bool host_window_created_; diff --git a/libcef/browser/native/browser_platform_delegate_native_mac.h b/libcef/browser/native/browser_platform_delegate_native_mac.h index 11ee14780..e421a390e 100644 --- a/libcef/browser/native/browser_platform_delegate_native_mac.h +++ b/libcef/browser/native/browser_platform_delegate_native_mac.h @@ -7,6 +7,10 @@ #include "libcef/browser/native/browser_platform_delegate_native.h" +namespace content { +class RenderWidgetHostViewMac; +} + // Windowed browser implementation for Mac OS X. class CefBrowserPlatformDelegateNativeMac : public CefBrowserPlatformDelegateNative { @@ -19,25 +23,21 @@ class CefBrowserPlatformDelegateNativeMac bool CreateHostWindow() override; void CloseHostWindow() override; CefWindowHandle GetHostWindowHandle() const override; + void SendKeyEvent(const CefKeyEvent& event) override; + void SendMouseClickEvent(const CefMouseEvent& event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) override; + void SendMouseMoveEvent(const CefMouseEvent& event, bool mouseLeave) override; + void SendMouseWheelEvent(const CefMouseEvent& event, + int deltaX, + int deltaY) override; + void SendTouchEvent(const CefTouchEvent& event) override; void SendFocusEvent(bool setFocus) override; gfx::Point GetScreenPoint(const gfx::Point& view) const override; void ViewText(const std::string& text) override; bool HandleKeyboardEvent( const content::NativeWebKeyboardEvent& event) override; - void TranslateKeyEvent(content::NativeWebKeyboardEvent& result, - const CefKeyEvent& key_event) const override; - void TranslateClickEvent(blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - CefBrowserHost::MouseButtonType type, - bool mouseUp, - int clickCount) const override; - void TranslateMoveEvent(blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - bool mouseLeave) const override; - void TranslateWheelEvent(blink::WebMouseWheelEvent& result, - const CefMouseEvent& mouse_event, - int deltaX, - int deltaY) const override; CefEventHandle GetEventHandle( const content::NativeWebKeyboardEvent& event) const override; std::unique_ptr CreateFileDialogRunner() override; @@ -47,9 +47,26 @@ class CefBrowserPlatformDelegateNativeMac gfx::Point GetDialogPosition(const gfx::Size& size) override; gfx::Size GetMaximumDialogSize() override; + // CefBrowserPlatformDelegateNative methods: + content::NativeWebKeyboardEvent TranslateWebKeyEvent( + const CefKeyEvent& key_event) const override; + blink::WebMouseEvent TranslateWebClickEvent( + const CefMouseEvent& mouse_event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) const override; + blink::WebMouseEvent TranslateWebMoveEvent(const CefMouseEvent& mouse_event, + bool mouseLeave) const override; + blink::WebMouseWheelEvent TranslateWebWheelEvent( + const CefMouseEvent& mouse_event, + int deltaX, + int deltaY) const override; + private: - void TranslateMouseEvent(blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event) const; + void TranslateWebMouseEvent(blink::WebMouseEvent& result, + const CefMouseEvent& mouse_event) const; + + content::RenderWidgetHostViewMac* GetHostView() const; // True if the host window has been created. bool host_window_created_; diff --git a/libcef/browser/native/browser_platform_delegate_native_mac.mm b/libcef/browser/native/browser_platform_delegate_native_mac.mm index d754c9cfc..f14b9a281 100644 --- a/libcef/browser/native/browser_platform_delegate_native_mac.mm +++ b/libcef/browser/native/browser_platform_delegate_native_mac.mm @@ -17,6 +17,7 @@ #include "base/mac/scoped_nsautorelease_pool.h" #include "base/memory/ptr_util.h" #include "base/threading/thread_restrictions.h" +#include "content/browser/renderer_host/render_widget_host_view_mac.h" #include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" @@ -25,6 +26,7 @@ #include "third_party/blink/public/platform/web_mouse_wheel_event.h" #import "ui/base/cocoa/cocoa_base_utils.h" #import "ui/base/cocoa/underlay_opengl_hosting_window.h" +#include "ui/events/base_event_utils.h" #include "ui/events/keycodes/keyboard_codes_posix.h" #include "ui/gfx/geometry/rect.h" @@ -255,9 +257,61 @@ CefWindowHandle CefBrowserPlatformDelegateNativeMac::GetHostWindowHandle() return window_info_.view; } +void CefBrowserPlatformDelegateNativeMac::SendKeyEvent( + const CefKeyEvent& event) { + auto view = GetHostView(); + if (!view) + return; + + content::NativeWebKeyboardEvent web_event = TranslateWebKeyEvent(event); + view->ForwardKeyboardEvent(web_event, ui::LatencyInfo()); +} + +void CefBrowserPlatformDelegateNativeMac::SendMouseClickEvent( + const CefMouseEvent& event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) { + auto view = GetHostView(); + if (!view) + return; + + blink::WebMouseEvent web_event = + TranslateWebClickEvent(event, type, mouseUp, clickCount); + view->RouteOrProcessMouseEvent(web_event); +} + +void CefBrowserPlatformDelegateNativeMac::SendMouseMoveEvent( + const CefMouseEvent& event, + bool mouseLeave) { + auto view = GetHostView(); + if (!view) + return; + + blink::WebMouseEvent web_event = TranslateWebMoveEvent(event, mouseLeave); + view->RouteOrProcessMouseEvent(web_event); +} + +void CefBrowserPlatformDelegateNativeMac::SendMouseWheelEvent( + const CefMouseEvent& event, + int deltaX, + int deltaY) { + auto view = GetHostView(); + if (!view) + return; + + blink::WebMouseWheelEvent web_event = + TranslateWebWheelEvent(event, deltaX, deltaY); + view->RouteOrProcessMouseEvent(web_event); +} + +void CefBrowserPlatformDelegateNativeMac::SendTouchEvent( + const CefTouchEvent& event) { + NOTIMPLEMENTED(); +} + void CefBrowserPlatformDelegateNativeMac::SendFocusEvent(bool setFocus) { - content::RenderWidgetHostView* view = - browser_->web_contents()->GetRenderWidgetHostView(); + auto view = GetHostView(); if (view) { view->SetActive(setFocus); @@ -304,15 +358,51 @@ bool CefBrowserPlatformDelegateNativeMac::HandleKeyboardEvent( // static void CefBrowserPlatformDelegate::HandleExternalProtocol(const GURL& url) {} -void CefBrowserPlatformDelegateNativeMac::TranslateKeyEvent( - content::NativeWebKeyboardEvent& result, +CefEventHandle CefBrowserPlatformDelegateNativeMac::GetEventHandle( + const content::NativeWebKeyboardEvent& event) const { + return event.os_event; +} + +std::unique_ptr +CefBrowserPlatformDelegateNativeMac::CreateFileDialogRunner() { + return base::WrapUnique(new CefFileDialogRunnerMac); +} + +std::unique_ptr +CefBrowserPlatformDelegateNativeMac::CreateJavaScriptDialogRunner() { + return base::WrapUnique(new CefJavaScriptDialogRunnerMac); +} + +std::unique_ptr +CefBrowserPlatformDelegateNativeMac::CreateMenuRunner() { + return base::WrapUnique(new CefMenuRunnerMac); +} + +gfx::Point CefBrowserPlatformDelegateNativeMac::GetDialogPosition( + const gfx::Size& size) { + // Dialogs are always re-positioned by the constrained window sheet controller + // so nothing interesting to return yet. + return gfx::Point(); +} + +gfx::Size CefBrowserPlatformDelegateNativeMac::GetMaximumDialogSize() { + // The dialog should try to fit within the overlay for the web contents. + // Note that, for things like print preview, this is just a suggested maximum. + return browser_->web_contents()->GetContainerBounds().size(); +} + +content::NativeWebKeyboardEvent +CefBrowserPlatformDelegateNativeMac::TranslateWebKeyEvent( const CefKeyEvent& key_event) const { + content::NativeWebKeyboardEvent result(blink::WebInputEvent::kUndefined, + blink::WebInputEvent::kNoModifiers, + ui::EventTimeForNow()); + // Use a synthetic NSEvent in order to obtain the windowsKeyCode member from // the NativeWebKeyboardEvent constructor. This is the only member which can // not be easily translated (without hardcoding keyCodes) // Determining whether a modifier key is left or right seems to be done // through the key code as well. - NSEventType event_type; if (key_event.character == 0 && key_event.unmodified_character == 0) { // Check if both character and unmodified_characther are empty to determine @@ -357,15 +447,18 @@ void CefBrowserPlatformDelegateNativeMac::TranslateKeyEvent( result.SetType(blink::WebInputEvent::kChar); result.is_system_key = key_event.is_system_key; + + return result; } -void CefBrowserPlatformDelegateNativeMac::TranslateClickEvent( - blink::WebMouseEvent& result, +blink::WebMouseEvent +CefBrowserPlatformDelegateNativeMac::TranslateWebClickEvent( const CefMouseEvent& mouse_event, CefBrowserHost::MouseButtonType type, bool mouseUp, int clickCount) const { - TranslateMouseEvent(result, mouse_event); + blink::WebMouseEvent result; + TranslateWebMouseEvent(result, mouse_event); switch (type) { case MBT_LEFT: @@ -388,13 +481,15 @@ void CefBrowserPlatformDelegateNativeMac::TranslateClickEvent( } result.click_count = clickCount; + + return result; } -void CefBrowserPlatformDelegateNativeMac::TranslateMoveEvent( - blink::WebMouseEvent& result, +blink::WebMouseEvent CefBrowserPlatformDelegateNativeMac::TranslateWebMoveEvent( const CefMouseEvent& mouse_event, bool mouseLeave) const { - TranslateMouseEvent(result, mouse_event); + blink::WebMouseEvent result; + TranslateWebMouseEvent(result, mouse_event); if (!mouseLeave) { result.SetType(blink::WebInputEvent::kMouseMove); @@ -412,15 +507,17 @@ void CefBrowserPlatformDelegateNativeMac::TranslateMoveEvent( } result.click_count = 0; + + return result; } -void CefBrowserPlatformDelegateNativeMac::TranslateWheelEvent( - blink::WebMouseWheelEvent& result, +blink::WebMouseWheelEvent +CefBrowserPlatformDelegateNativeMac::TranslateWebWheelEvent( const CefMouseEvent& mouse_event, int deltaX, int deltaY) const { - result = blink::WebMouseWheelEvent(); - TranslateMouseEvent(result, mouse_event); + blink::WebMouseWheelEvent result; + TranslateWebMouseEvent(result, mouse_event); result.SetType(blink::WebInputEvent::kMouseWheel); @@ -429,7 +526,8 @@ void CefBrowserPlatformDelegateNativeMac::TranslateWheelEvent( result.delta_y = deltaY; result.wheel_ticks_x = deltaX / scrollbarPixelsPerCocoaTick; result.wheel_ticks_y = deltaY / scrollbarPixelsPerCocoaTick; - result.delta_units = ui::input_types::ScrollGranularity::kScrollByPrecisePixel; + result.delta_units = + ui::input_types::ScrollGranularity::kScrollByPrecisePixel; if (mouse_event.modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON) result.button = blink::WebMouseEvent::Button::kLeft; @@ -439,29 +537,11 @@ void CefBrowserPlatformDelegateNativeMac::TranslateWheelEvent( result.button = blink::WebMouseEvent::Button::kRight; else result.button = blink::WebMouseEvent::Button::kNoButton; + + return result; } -CefEventHandle CefBrowserPlatformDelegateNativeMac::GetEventHandle( - const content::NativeWebKeyboardEvent& event) const { - return event.os_event; -} - -std::unique_ptr -CefBrowserPlatformDelegateNativeMac::CreateFileDialogRunner() { - return base::WrapUnique(new CefFileDialogRunnerMac); -} - -std::unique_ptr -CefBrowserPlatformDelegateNativeMac::CreateJavaScriptDialogRunner() { - return base::WrapUnique(new CefJavaScriptDialogRunnerMac); -} - -std::unique_ptr -CefBrowserPlatformDelegateNativeMac::CreateMenuRunner() { - return base::WrapUnique(new CefMenuRunnerMac); -} - -void CefBrowserPlatformDelegateNativeMac::TranslateMouseEvent( +void CefBrowserPlatformDelegateNativeMac::TranslateWebMouseEvent( blink::WebMouseEvent& result, const CefMouseEvent& mouse_event) const { // position @@ -473,24 +553,17 @@ void CefBrowserPlatformDelegateNativeMac::TranslateMouseEvent( // modifiers result.SetModifiers(result.GetModifiers() | - TranslateModifiers(mouse_event.modifiers)); + TranslateWebEventModifiers(mouse_event.modifiers)); - // timestamp - Mac OSX specific + // timestamp result.SetTimeStamp(base::TimeTicks() + base::TimeDelta::FromSeconds(currentEventTimestamp())); result.pointer_type = blink::WebPointerProperties::PointerType::kMouse; } -gfx::Point CefBrowserPlatformDelegateNativeMac::GetDialogPosition( - const gfx::Size& size) { - // Dialogs are always re-positioned by the constrained window sheet controller - // so nothing interesting to return yet. - return gfx::Point(); -} - -gfx::Size CefBrowserPlatformDelegateNativeMac::GetMaximumDialogSize() { - // The dialog should try to fit within the overlay for the web contents. - // Note that, for things like print preview, this is just a suggested maximum. - return browser_->web_contents()->GetContainerBounds().size(); +content::RenderWidgetHostViewMac* +CefBrowserPlatformDelegateNativeMac::GetHostView() const { + return static_cast( + browser_->web_contents()->GetRenderWidgetHostView()); } diff --git a/libcef/browser/native/browser_platform_delegate_native_win.cc b/libcef/browser/native/browser_platform_delegate_native_win.cc index dcd953f88..9b07e1c03 100644 --- a/libcef/browser/native/browser_platform_delegate_native_win.cc +++ b/libcef/browser/native/browser_platform_delegate_native_win.cc @@ -32,6 +32,7 @@ #include "ui/events/keycodes/dom/keycode_converter.h" #include "ui/events/keycodes/keyboard_code_conversion_win.h" #include "ui/events/keycodes/platform_key_map_win.h" +#include "ui/gfx/geometry/vector2d.h" #include "ui/gfx/win/hwnd_util.h" #include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h" #include "ui/views/widget/widget.h" @@ -128,10 +129,10 @@ CefBrowserPlatformDelegateNativeWin::CefBrowserPlatformDelegateNativeWin( SkColor background_color, bool use_shared_texture, bool use_external_begin_frame) - : CefBrowserPlatformDelegateNative(window_info, - background_color, - use_shared_texture, - use_external_begin_frame), + : CefBrowserPlatformDelegateNativeAura(window_info, + background_color, + use_shared_texture, + use_external_begin_frame), host_window_created_(false), window_widget_(nullptr) {} @@ -404,153 +405,6 @@ void CefBrowserPlatformDelegate::HandleExternalProtocol(const GURL& url) { CEF_POST_USER_VISIBLE_TASK(base::Bind(ExecuteExternalProtocol, url)); } -void CefBrowserPlatformDelegateNativeWin::TranslateKeyEvent( - content::NativeWebKeyboardEvent& result, - const CefKeyEvent& key_event) const { - result.windows_key_code = key_event.windows_key_code; - result.native_key_code = key_event.native_key_code; - result.is_system_key = key_event.is_system_key ? 1 : 0; - switch (key_event.type) { - case KEYEVENT_RAWKEYDOWN: - case KEYEVENT_KEYDOWN: - result.SetType(blink::WebInputEvent::kRawKeyDown); - break; - case KEYEVENT_KEYUP: - result.SetType(blink::WebInputEvent::kKeyUp); - break; - case KEYEVENT_CHAR: - result.SetType(blink::WebInputEvent::kChar); - break; - default: - NOTREACHED(); - } - - // Populate DOM values that will be passed to JavaScript handlers via - // KeyboardEvent. - result.dom_code = static_cast( - ui::KeycodeConverter::NativeKeycodeToDomCode(key_event.native_key_code)); - if (result.GetType() == blink::WebInputEvent::kChar) { - result.dom_key = ui::DomKey::FromCharacter(key_event.windows_key_code); - } else { - // TODO(cef): CefKeyEvent does not currently pass extended key status (see - // WM_KEYDOWN docs) which would be necessary to pass EF_IS_EXTENDED_KEY as - // the |flags| parameter to DomKeyFromKeyboardCode(). - int flags = 0; - result.dom_key = ui::PlatformKeyMap::DomKeyFromKeyboardCode( - ui::KeyboardCodeForWindowsKeyCode(key_event.windows_key_code), &flags); - } - - if (result.GetType() == blink::WebInputEvent::kChar || - result.GetType() == blink::WebInputEvent::kRawKeyDown) { - result.text[0] = result.windows_key_code; - result.unmodified_text[0] = result.windows_key_code; - } - - result.SetModifiers(result.GetModifiers() | - TranslateModifiers(key_event.modifiers)); -} - -void CefBrowserPlatformDelegateNativeWin::TranslateClickEvent( - blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - CefBrowserHost::MouseButtonType type, - bool mouseUp, - int clickCount) const { - TranslateMouseEvent(result, mouse_event); - - switch (type) { - case MBT_LEFT: - result.SetType(mouseUp ? blink::WebInputEvent::kMouseUp - : blink::WebInputEvent::kMouseDown); - result.button = blink::WebMouseEvent::Button::kLeft; - break; - case MBT_MIDDLE: - result.SetType(mouseUp ? blink::WebInputEvent::kMouseUp - : blink::WebInputEvent::kMouseDown); - result.button = blink::WebMouseEvent::Button::kMiddle; - break; - case MBT_RIGHT: - result.SetType(mouseUp ? blink::WebInputEvent::kMouseUp - : blink::WebInputEvent::kMouseDown); - result.button = blink::WebMouseEvent::Button::kRight; - break; - default: - NOTREACHED(); - } - - result.click_count = clickCount; -} - -void CefBrowserPlatformDelegateNativeWin::TranslateMoveEvent( - blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - bool mouseLeave) const { - TranslateMouseEvent(result, mouse_event); - - if (!mouseLeave) { - result.SetType(blink::WebInputEvent::kMouseMove); - if (mouse_event.modifiers & EVENTFLAG_LEFT_MOUSE_BUTTON) - result.button = blink::WebMouseEvent::Button::kLeft; - else if (mouse_event.modifiers & EVENTFLAG_MIDDLE_MOUSE_BUTTON) - result.button = blink::WebMouseEvent::Button::kMiddle; - else if (mouse_event.modifiers & EVENTFLAG_RIGHT_MOUSE_BUTTON) - result.button = blink::WebMouseEvent::Button::kRight; - else - result.button = blink::WebMouseEvent::Button::kNoButton; - } else { - result.SetType(blink::WebInputEvent::kMouseLeave); - result.button = blink::WebMouseEvent::Button::kNoButton; - } - - result.click_count = 0; -} - -void CefBrowserPlatformDelegateNativeWin::TranslateWheelEvent( - blink::WebMouseWheelEvent& result, - const CefMouseEvent& mouse_event, - int deltaX, - int deltaY) const { - TranslateMouseEvent(result, mouse_event); - - result.SetType(blink::WebInputEvent::kMouseWheel); - result.button = blink::WebMouseEvent::Button::kNoButton; - - float wheelDelta; - bool horizontalScroll = false; - - wheelDelta = static_cast(deltaY ? deltaY : deltaX); - - horizontalScroll = (deltaY == 0); - - static const ULONG defaultScrollCharsPerWheelDelta = 1; - static const FLOAT scrollbarPixelsPerLine = 100.0f / 3.0f; - static const ULONG defaultScrollLinesPerWheelDelta = 3; - wheelDelta /= WHEEL_DELTA; - float scrollDelta = wheelDelta; - if (horizontalScroll) { - ULONG scrollChars = defaultScrollCharsPerWheelDelta; - SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scrollChars, 0); - scrollDelta *= static_cast(scrollChars) * scrollbarPixelsPerLine; - } else { - ULONG scrollLines = defaultScrollLinesPerWheelDelta; - SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, 0); - if (scrollLines == WHEEL_PAGESCROLL) - result.delta_units = ui::input_types::ScrollGranularity::kScrollByPage; - if (result.delta_units != ui::input_types::ScrollGranularity::kScrollByPage) - scrollDelta *= static_cast(scrollLines) * scrollbarPixelsPerLine; - } - - // Set scroll amount based on above calculations. WebKit expects positive - // deltaY to mean "scroll up" and positive deltaX to mean "scroll left". - if (horizontalScroll) { - result.delta_x = scrollDelta; - result.wheel_ticks_x = wheelDelta; - } else { - result.delta_y = scrollDelta; - result.wheel_ticks_y = wheelDelta; - } -} - CefEventHandle CefBrowserPlatformDelegateNativeWin::GetEventHandle( const content::NativeWebKeyboardEvent& event) const { if (!event.os_event) @@ -573,27 +427,6 @@ CefBrowserPlatformDelegateNativeWin::CreateMenuRunner() { return base::WrapUnique(new CefMenuRunnerWin); } -void CefBrowserPlatformDelegateNativeWin::TranslateMouseEvent( - blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event) const { - // position - result.SetPositionInWidget(mouse_event.x, mouse_event.y); - - const gfx::Point& screen_pt = - GetScreenPoint(gfx::Point(mouse_event.x, mouse_event.y)); - result.SetPositionInScreen(screen_pt.x(), screen_pt.y()); - - // modifiers - result.SetModifiers(result.GetModifiers() | - TranslateModifiers(mouse_event.modifiers)); - - // timestamp - result.SetTimeStamp(base::TimeTicks() + - base::TimeDelta::FromMilliseconds(GetMessageTime())); - - result.pointer_type = blink::WebPointerProperties::PointerType::kMouse; -} - gfx::Point CefBrowserPlatformDelegateNativeWin::GetDialogPosition( const gfx::Size& size) { const gfx::Size& max_size = GetMaximumDialogSize(); @@ -605,6 +438,66 @@ gfx::Size CefBrowserPlatformDelegateNativeWin::GetMaximumDialogSize() { return GetWindowWidget()->GetWindowBoundsInScreen().size(); } +ui::KeyEvent CefBrowserPlatformDelegateNativeWin::TranslateUiKeyEvent( + const CefKeyEvent& key_event) const { + int flags = TranslateUiEventModifiers(key_event.modifiers); + ui::KeyboardCode key_code = + ui::KeyboardCodeForWindowsKeyCode(key_event.windows_key_code); + ui::DomCode dom_code = + ui::KeycodeConverter::NativeKeycodeToDomCode(key_event.native_key_code); + base::TimeTicks time_stamp = GetEventTimeStamp(); + + if (key_event.type == KEYEVENT_CHAR) { + return ui::KeyEvent(key_event.windows_key_code /* character */, key_code, + dom_code, flags, time_stamp); + } + + ui::EventType type = ui::ET_UNKNOWN; + switch (key_event.type) { + case KEYEVENT_RAWKEYDOWN: + case KEYEVENT_KEYDOWN: + type = ui::ET_KEY_PRESSED; + break; + case KEYEVENT_KEYUP: + type = ui::ET_KEY_RELEASED; + break; + default: + NOTREACHED(); + } + + ui::DomKey dom_key = + ui::PlatformKeyMap::DomKeyFromKeyboardCode(key_code, &flags); + return ui::KeyEvent(type, key_code, dom_code, flags, dom_key, time_stamp); +} + +gfx::Vector2d CefBrowserPlatformDelegateNativeWin::GetUiWheelEventOffset( + int deltaX, + int deltaY) const { + static const ULONG defaultScrollCharsPerWheelDelta = 1; + static const FLOAT scrollbarPixelsPerLine = 100.0f / 3.0f; + static const ULONG defaultScrollLinesPerWheelDelta = 3; + + float wheelDeltaX = float(deltaX) / WHEEL_DELTA; + float wheelDeltaY = float(deltaY) / WHEEL_DELTA; + float scrollDeltaX = wheelDeltaX; + float scrollDeltaY = wheelDeltaY; + + ULONG scrollChars = defaultScrollCharsPerWheelDelta; + SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scrollChars, 0); + scrollDeltaX *= static_cast(scrollChars) * scrollbarPixelsPerLine; + + ULONG scrollLines = defaultScrollLinesPerWheelDelta; + SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, 0); + scrollDeltaY *= static_cast(scrollLines) * scrollbarPixelsPerLine; + + return gfx::Vector2d(scrollDeltaX, scrollDeltaY); +} + +base::TimeTicks CefBrowserPlatformDelegateNativeWin::GetEventTimeStamp() const { + return base::TimeTicks() + + base::TimeDelta::FromMilliseconds(GetMessageTime()); +} + // static void CefBrowserPlatformDelegateNativeWin::RegisterWindowClass() { static bool registered = false; diff --git a/libcef/browser/native/browser_platform_delegate_native_win.h b/libcef/browser/native/browser_platform_delegate_native_win.h index a1d95e9db..e1dd0a097 100644 --- a/libcef/browser/native/browser_platform_delegate_native_win.h +++ b/libcef/browser/native/browser_platform_delegate_native_win.h @@ -7,11 +7,11 @@ #include -#include "libcef/browser/native/browser_platform_delegate_native.h" +#include "libcef/browser/native/browser_platform_delegate_native_aura.h" // Windowed browser implementation for Windows. class CefBrowserPlatformDelegateNativeWin - : public CefBrowserPlatformDelegateNative { + : public CefBrowserPlatformDelegateNativeAura { public: CefBrowserPlatformDelegateNativeWin(const CefWindowInfo& window_info, SkColor background_color, @@ -31,20 +31,6 @@ class CefBrowserPlatformDelegateNativeWin void ViewText(const std::string& text) override; bool HandleKeyboardEvent( const content::NativeWebKeyboardEvent& event) override; - void TranslateKeyEvent(content::NativeWebKeyboardEvent& result, - const CefKeyEvent& key_event) const override; - void TranslateClickEvent(blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - CefBrowserHost::MouseButtonType type, - bool mouseUp, - int clickCount) const override; - void TranslateMoveEvent(blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - bool mouseLeave) const override; - void TranslateWheelEvent(blink::WebMouseWheelEvent& result, - const CefMouseEvent& mouse_event, - int deltaX, - int deltaY) const override; CefEventHandle GetEventHandle( const content::NativeWebKeyboardEvent& event) const override; std::unique_ptr CreateFileDialogRunner() override; @@ -54,10 +40,12 @@ class CefBrowserPlatformDelegateNativeWin gfx::Point GetDialogPosition(const gfx::Size& size) override; gfx::Size GetMaximumDialogSize() override; - private: - void TranslateMouseEvent(blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event) const; + // CefBrowserPlatformDelegateNativeAura methods: + ui::KeyEvent TranslateUiKeyEvent(const CefKeyEvent& key_event) const override; + gfx::Vector2d GetUiWheelEventOffset(int deltaX, int deltaY) const override; + base::TimeTicks GetEventTimeStamp() const override; + private: static void RegisterWindowClass(); static LPCTSTR GetWndClass(); static LRESULT CALLBACK WndProc(HWND hwnd, diff --git a/libcef/browser/osr/browser_platform_delegate_osr.cc b/libcef/browser/osr/browser_platform_delegate_osr.cc index 66f63b019..b41690e3d 100644 --- a/libcef/browser/osr/browser_platform_delegate_osr.cc +++ b/libcef/browser/osr/browser_platform_delegate_osr.cc @@ -91,25 +91,53 @@ void CefBrowserPlatformDelegateOsr::SynchronizeVisualProperties() { view->SynchronizeVisualProperties(); } -void CefBrowserPlatformDelegateOsr::SendKeyEvent( - const content::NativeWebKeyboardEvent& event) { +void CefBrowserPlatformDelegateOsr::SendKeyEvent(const CefKeyEvent& event) { CefRenderWidgetHostViewOSR* view = GetOSRHostView(); - if (view) - view->SendKeyEvent(event); + if (!view) + return; + + content::NativeWebKeyboardEvent web_event = + native_delegate_->TranslateWebKeyEvent(event); + view->SendKeyEvent(web_event); } -void CefBrowserPlatformDelegateOsr::SendMouseEvent( - const blink::WebMouseEvent& event) { +void CefBrowserPlatformDelegateOsr::SendMouseClickEvent( + const CefMouseEvent& event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) { CefRenderWidgetHostViewOSR* view = GetOSRHostView(); - if (view) - view->SendMouseEvent(event); + if (!view) + return; + + blink::WebMouseEvent web_event = native_delegate_->TranslateWebClickEvent( + event, type, mouseUp, clickCount); + view->SendMouseEvent(web_event); +} + +void CefBrowserPlatformDelegateOsr::SendMouseMoveEvent( + const CefMouseEvent& event, + bool mouseLeave) { + CefRenderWidgetHostViewOSR* view = GetOSRHostView(); + if (!view) + return; + + blink::WebMouseEvent web_event = + native_delegate_->TranslateWebMoveEvent(event, mouseLeave); + view->SendMouseEvent(web_event); } void CefBrowserPlatformDelegateOsr::SendMouseWheelEvent( - const blink::WebMouseWheelEvent& event) { + const CefMouseEvent& event, + int deltaX, + int deltaY) { CefRenderWidgetHostViewOSR* view = GetOSRHostView(); - if (view) - view->SendMouseWheelEvent(event); + if (!view) + return; + + blink::WebMouseWheelEvent web_event = + native_delegate_->TranslateWebWheelEvent(event, deltaX, deltaY); + view->SendMouseWheelEvent(web_event); } void CefBrowserPlatformDelegateOsr::SendTouchEvent(const CefTouchEvent& event) { @@ -146,37 +174,6 @@ bool CefBrowserPlatformDelegateOsr::HandleKeyboardEvent( return native_delegate_->HandleKeyboardEvent(event); } -void CefBrowserPlatformDelegateOsr::TranslateKeyEvent( - content::NativeWebKeyboardEvent& result, - const CefKeyEvent& key_event) const { - native_delegate_->TranslateKeyEvent(result, key_event); -} - -void CefBrowserPlatformDelegateOsr::TranslateClickEvent( - blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - CefBrowserHost::MouseButtonType type, - bool mouseUp, - int clickCount) const { - native_delegate_->TranslateClickEvent(result, mouse_event, type, mouseUp, - clickCount); -} - -void CefBrowserPlatformDelegateOsr::TranslateMoveEvent( - blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - bool mouseLeave) const { - native_delegate_->TranslateMoveEvent(result, mouse_event, mouseLeave); -} - -void CefBrowserPlatformDelegateOsr::TranslateWheelEvent( - blink::WebMouseWheelEvent& result, - const CefMouseEvent& mouse_event, - int deltaX, - int deltaY) const { - native_delegate_->TranslateWheelEvent(result, mouse_event, deltaX, deltaY); -} - CefEventHandle CefBrowserPlatformDelegateOsr::GetEventHandle( const content::NativeWebKeyboardEvent& event) const { return native_delegate_->GetEventHandle(event); @@ -306,7 +303,7 @@ void CefBrowserPlatformDelegateOsr::DragTargetDragEnter( const gfx::Point& screen_pt = GetScreenPoint(client_pt); blink::WebDragOperationsMask ops = static_cast(allowed_ops); - int modifiers = TranslateModifiers(event.modifiers); + int modifiers = TranslateWebEventModifiers(event.modifiers); current_rwh_for_drag_->FilterDropData(drop_data); @@ -370,7 +367,7 @@ void CefBrowserPlatformDelegateOsr::DragTargetDragOver( blink::WebDragOperationsMask ops = static_cast(allowed_ops); - int modifiers = TranslateModifiers(event.modifiers); + int modifiers = TranslateWebEventModifiers(event.modifiers); target_rwh->DragTargetDragOver(transformed_pt, gfx::PointF(screen_pt), ops, modifiers); @@ -440,7 +437,7 @@ void CefBrowserPlatformDelegateOsr::DragTargetDrop(const CefMouseEvent& event) { static_cast(drag_data_.get()); base::AutoLock lock_scope(data_impl->lock()); content::DropData* drop_data = data_impl->drop_data(); - int modifiers = TranslateModifiers(event.modifiers); + int modifiers = TranslateWebEventModifiers(event.modifiers); target_rwh->DragTargetDrop(*drop_data, transformed_pt, gfx::PointF(screen_pt), modifiers); diff --git a/libcef/browser/osr/browser_platform_delegate_osr.h b/libcef/browser/osr/browser_platform_delegate_osr.h index fcf353e7a..b5fb8d504 100644 --- a/libcef/browser/osr/browser_platform_delegate_osr.h +++ b/libcef/browser/osr/browser_platform_delegate_osr.h @@ -31,30 +31,21 @@ class CefBrowserPlatformDelegateOsr bool CanUseSharedTexture() const override; bool CanUseExternalBeginFrame() const override; void SynchronizeVisualProperties() override; - void SendExternalBeginFrame() override; - void SendKeyEvent(const content::NativeWebKeyboardEvent& event) override; - void SendMouseEvent(const blink::WebMouseEvent& event) override; - void SendMouseWheelEvent(const blink::WebMouseWheelEvent& event) override; + void SendKeyEvent(const CefKeyEvent& event) override; + void SendMouseClickEvent(const CefMouseEvent& event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) override; + void SendMouseMoveEvent(const CefMouseEvent& event, bool mouseLeave) override; + void SendMouseWheelEvent(const CefMouseEvent& event, + int deltaX, + int deltaY) override; void SendTouchEvent(const CefTouchEvent& event) override; void SendFocusEvent(bool setFocus) override; gfx::Point GetScreenPoint(const gfx::Point& view) const override; void ViewText(const std::string& text) override; bool HandleKeyboardEvent( const content::NativeWebKeyboardEvent& event) override; - void TranslateKeyEvent(content::NativeWebKeyboardEvent& result, - const CefKeyEvent& key_event) const override; - void TranslateClickEvent(blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - CefBrowserHost::MouseButtonType type, - bool mouseUp, - int clickCount) const override; - void TranslateMoveEvent(blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - bool mouseLeave) const override; - void TranslateWheelEvent(blink::WebMouseWheelEvent& result, - const CefMouseEvent& mouse_event, - int deltaX, - int deltaY) const override; CefEventHandle GetEventHandle( const content::NativeWebKeyboardEvent& event) const override; std::unique_ptr CreateFileDialogRunner() override; @@ -66,6 +57,7 @@ class CefBrowserPlatformDelegateOsr void WasHidden(bool hidden) override; void NotifyScreenInfoChanged() override; void Invalidate(cef_paint_element_type_t type) override; + void SendExternalBeginFrame() override; void SetWindowlessFrameRate(int frame_rate) override; void ImeSetComposition(const CefString& text, const std::vector& underlines, diff --git a/libcef/browser/views/browser_platform_delegate_views.cc b/libcef/browser/views/browser_platform_delegate_views.cc index 65128d3a1..3c7e649bc 100644 --- a/libcef/browser/views/browser_platform_delegate_views.cc +++ b/libcef/browser/views/browser_platform_delegate_views.cc @@ -76,6 +76,7 @@ void CefBrowserPlatformDelegateViews::BrowserCreated( CefBrowserHostImpl* browser) { CefBrowserPlatformDelegate::BrowserCreated(browser); + native_delegate_->set_browser(browser); browser_view_->BrowserCreated(browser, GetBoundsChangedCallback()); } @@ -97,6 +98,7 @@ void CefBrowserPlatformDelegateViews::BrowserDestroyed( CefBrowserHostImpl* browser) { CefBrowserPlatformDelegate::BrowserDestroyed(browser); + native_delegate_->set_browser(nullptr); browser_view_->BrowserDestroyed(browser); browser_view_ = nullptr; } @@ -183,34 +185,38 @@ SkColor CefBrowserPlatformDelegateViews::GetBackgroundColor() const { } void CefBrowserPlatformDelegateViews::SynchronizeVisualProperties() { - content::RenderViewHost* host = browser_->web_contents()->GetRenderViewHost(); - if (host) - host->GetWidget()->SynchronizeVisualProperties(); + native_delegate_->SynchronizeVisualProperties(); } -void CefBrowserPlatformDelegateViews::SendKeyEvent( - const content::NativeWebKeyboardEvent& event) { - content::RenderViewHost* host = browser_->web_contents()->GetRenderViewHost(); - if (host) - host->GetWidget()->ForwardKeyboardEvent(event); +void CefBrowserPlatformDelegateViews::SendKeyEvent(const CefKeyEvent& event) { + native_delegate_->SendKeyEvent(event); } -void CefBrowserPlatformDelegateViews::SendMouseEvent( - const blink::WebMouseEvent& event) { - content::RenderViewHost* host = browser_->web_contents()->GetRenderViewHost(); - if (host) - host->GetWidget()->ForwardMouseEvent(event); +void CefBrowserPlatformDelegateViews::SendMouseClickEvent( + const CefMouseEvent& event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) { + native_delegate_->SendMouseClickEvent(event, type, mouseUp, clickCount); +} + +void CefBrowserPlatformDelegateViews::SendMouseMoveEvent( + const CefMouseEvent& event, + bool mouseLeave) { + native_delegate_->SendMouseMoveEvent(event, mouseLeave); } void CefBrowserPlatformDelegateViews::SendMouseWheelEvent( - const blink::WebMouseWheelEvent& event) { - content::RenderViewHost* host = browser_->web_contents()->GetRenderViewHost(); - if (host) - host->GetWidget()->ForwardWheelEvent(event); + const CefMouseEvent& event, + int deltaX, + int deltaY) { + native_delegate_->SendMouseWheelEvent(event, deltaX, deltaY); } void CefBrowserPlatformDelegateViews::SendTouchEvent( - const CefTouchEvent& event) {} + const CefTouchEvent& event) { + native_delegate_->SendTouchEvent(event); +} void CefBrowserPlatformDelegateViews::SendFocusEvent(bool setFocus) { // Will result in a call to WebContents::Focus(). @@ -239,37 +245,6 @@ bool CefBrowserPlatformDelegateViews::HandleKeyboardEvent( return browser_view_->HandleKeyboardEvent(event); } -void CefBrowserPlatformDelegateViews::TranslateKeyEvent( - content::NativeWebKeyboardEvent& result, - const CefKeyEvent& key_event) const { - native_delegate_->TranslateKeyEvent(result, key_event); -} - -void CefBrowserPlatformDelegateViews::TranslateClickEvent( - blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - CefBrowserHost::MouseButtonType type, - bool mouseUp, - int clickCount) const { - native_delegate_->TranslateClickEvent(result, mouse_event, type, mouseUp, - clickCount); -} - -void CefBrowserPlatformDelegateViews::TranslateMoveEvent( - blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - bool mouseLeave) const { - native_delegate_->TranslateMoveEvent(result, mouse_event, mouseLeave); -} - -void CefBrowserPlatformDelegateViews::TranslateWheelEvent( - blink::WebMouseWheelEvent& result, - const CefMouseEvent& mouse_event, - int deltaX, - int deltaY) const { - native_delegate_->TranslateWheelEvent(result, mouse_event, deltaX, deltaY); -} - CefEventHandle CefBrowserPlatformDelegateViews::GetEventHandle( const content::NativeWebKeyboardEvent& event) const { return native_delegate_->GetEventHandle(event); diff --git a/libcef/browser/views/browser_platform_delegate_views.h b/libcef/browser/views/browser_platform_delegate_views.h index f452b39a8..c723f3d2c 100644 --- a/libcef/browser/views/browser_platform_delegate_views.h +++ b/libcef/browser/views/browser_platform_delegate_views.h @@ -43,29 +43,21 @@ class CefBrowserPlatformDelegateViews bool CanUseExternalBeginFrame() const override; SkColor GetBackgroundColor() const override; void SynchronizeVisualProperties() override; - void SendKeyEvent(const content::NativeWebKeyboardEvent& event) override; - void SendMouseEvent(const blink::WebMouseEvent& event) override; - void SendMouseWheelEvent(const blink::WebMouseWheelEvent& event) override; + void SendKeyEvent(const CefKeyEvent& event) override; + void SendMouseClickEvent(const CefMouseEvent& event, + CefBrowserHost::MouseButtonType type, + bool mouseUp, + int clickCount) override; + void SendMouseMoveEvent(const CefMouseEvent& event, bool mouseLeave) override; + void SendMouseWheelEvent(const CefMouseEvent& event, + int deltaX, + int deltaY) override; void SendTouchEvent(const CefTouchEvent& event) override; void SendFocusEvent(bool setFocus) override; gfx::Point GetScreenPoint(const gfx::Point& view) const override; void ViewText(const std::string& text) override; bool HandleKeyboardEvent( const content::NativeWebKeyboardEvent& event) override; - void TranslateKeyEvent(content::NativeWebKeyboardEvent& result, - const CefKeyEvent& key_event) const override; - void TranslateClickEvent(blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - CefBrowserHost::MouseButtonType type, - bool mouseUp, - int clickCount) const override; - void TranslateMoveEvent(blink::WebMouseEvent& result, - const CefMouseEvent& mouse_event, - bool mouseLeave) const override; - void TranslateWheelEvent(blink::WebMouseWheelEvent& result, - const CefMouseEvent& mouse_event, - int deltaX, - int deltaY) const override; CefEventHandle GetEventHandle( const content::NativeWebKeyboardEvent& event) const override; std::unique_ptr CreateFileDialogRunner() override; diff --git a/libcef/common/cef_switches.cc b/libcef/common/cef_switches.cc index f1881f47a..bbe78f0c2 100644 --- a/libcef/common/cef_switches.cc +++ b/libcef/common/cef_switches.cc @@ -116,6 +116,10 @@ const char kEnablePreferenceTesting[] = "enable-preference-testing"; // Enable print preview. extern const char kEnablePrintPreview[] = "enable-print-preview"; +// Disable the timeout for delivering new browser info to the renderer process. +extern const char kDisableNewBrowserInfoTimeout[] = + "disable-new-browser-info-timeout"; + #if defined(OS_MACOSX) // Path to the framework directory. const char kFrameworkDirPath[] = "framework-dir-path"; diff --git a/libcef/common/cef_switches.h b/libcef/common/cef_switches.h index 3ace92b35..12f9e588b 100644 --- a/libcef/common/cef_switches.h +++ b/libcef/common/cef_switches.h @@ -52,6 +52,7 @@ extern const char kPluginPolicy_Detect[]; extern const char kPluginPolicy_Block[]; extern const char kEnablePreferenceTesting[]; extern const char kEnablePrintPreview[]; +extern const char kDisableNewBrowserInfoTimeout[]; #if defined(OS_MACOSX) extern const char kFrameworkDirPath[]; diff --git a/libcef/common/main_delegate.cc b/libcef/common/main_delegate.cc index dca233267..38f19c029 100644 --- a/libcef/common/main_delegate.cc +++ b/libcef/common/main_delegate.cc @@ -615,13 +615,6 @@ bool CefMainDelegate::BasicStartupComplete(int* exit_code) { disable_features.push_back(network::features::kOutOfBlinkCors.name); } - if (features::kMimeHandlerViewInCrossProcessFrame.default_state == - base::FEATURE_ENABLED_BY_DEFAULT) { - // TODO: Add support for cross-process mime handler view (see issue #2727) - disable_features.push_back( - features::kMimeHandlerViewInCrossProcessFrame.name); - } - #if defined(OS_WIN) if (features::kCalculateNativeWinOcclusion.default_state == base::FEATURE_ENABLED_BY_DEFAULT) { diff --git a/libcef/renderer/blink_glue.cc b/libcef/renderer/blink_glue.cc index f8a464734..a24b4bceb 100644 --- a/libcef/renderer/blink_glue.cc +++ b/libcef/renderer/blink_glue.cc @@ -23,6 +23,7 @@ #include "third_party/blink/renderer/core/dom/node.h" #include "third_party/blink/renderer/core/editing/serializers/serialization.h" #include "third_party/blink/renderer/core/exported/web_view_impl.h" +#include "third_party/blink/renderer/core/frame/frame_owner.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" @@ -245,4 +246,9 @@ bool ResponseWasCached(const blink::WebURLResponse& response) { return response.ToResourceResponse().WasCached(); } +bool HasPluginFrameOwner(blink::WebLocalFrame* frame) { + blink::Frame* core_frame = blink::WebFrame::ToCoreFrame(*frame); + return core_frame->Owner() && core_frame->Owner()->IsPlugin(); +} + } // namespace blink_glue diff --git a/libcef/renderer/blink_glue.h b/libcef/renderer/blink_glue.h index 80516f11c..21d6bc12e 100644 --- a/libcef/renderer/blink_glue.h +++ b/libcef/renderer/blink_glue.h @@ -87,6 +87,9 @@ class BLINK_EXPORT CefScriptForbiddenScope final { BLINK_EXPORT bool ResponseWasCached(const blink::WebURLResponse& response); +// Returns true if the frame owner is a plugin. +BLINK_EXPORT bool HasPluginFrameOwner(blink::WebLocalFrame* frame); + } // namespace blink_glue #endif // CEF_LIBCEF_RENDERER_BLINK_GLUE_H_ diff --git a/libcef/renderer/content_renderer_client.cc b/libcef/renderer/content_renderer_client.cc index 7ccbe0284..7094573da 100644 --- a/libcef/renderer/content_renderer_client.cc +++ b/libcef/renderer/content_renderer_client.cc @@ -81,6 +81,7 @@ #include "content/public/renderer/render_view_visitor.h" #include "content/renderer/render_widget.h" #include "extensions/common/switches.h" +#include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.h" #include "extensions/renderer/renderer_extension_registry.h" #include "ipc/ipc_sync_channel.h" #include "media/base/media.h" @@ -90,6 +91,7 @@ #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/scheduler/web_renderer_process_type.h" #include "third_party/blink/public/platform/url_conversion.h" @@ -480,9 +482,16 @@ void CefContentRendererClient::RenderFrameCreated( new PepperHelper(render_frame); - if (extensions::ExtensionsEnabled()) + if (extensions::ExtensionsEnabled()) { extensions_renderer_client_->RenderFrameCreated(render_frame, registry); + blink::AssociatedInterfaceRegistry* associated_interfaces = + render_frame_observer->associated_interfaces(); + associated_interfaces->AddInterface(base::BindRepeating( + &extensions::MimeHandlerViewContainerManager::BindReceiver, + render_frame->GetRoutingID())); + } + const base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); if (!command_line->HasSwitch(switches::kDisableSpellChecking)) { @@ -747,8 +756,9 @@ CefRefPtr CefContentRendererClient::MaybeCreateBrowser( return nullptr; } - if (params.is_guest_view) { - // Don't create a CefBrowser for guest views. + if (params.is_guest_view || params.browser_id < 0) { + // Don't create a CefBrowser for guest views, or if the new browser info + // response has timed out. guest_views_.insert(std::make_pair( render_view, std::make_unique(render_view, params.is_windowless))); diff --git a/libcef/renderer/frame_impl.cc b/libcef/renderer/frame_impl.cc index d1c791b67..229ff1f82 100644 --- a/libcef/renderer/frame_impl.cc +++ b/libcef/renderer/frame_impl.cc @@ -315,6 +315,11 @@ bool CefFrameImpl::OnMessageReceived(const IPC::Message& message) { } void CefFrameImpl::OnDidFinishLoad() { + // Ignore notifications from the embedded frame hosting a mime-type plugin. + // We'll eventually receive a notification from the owner frame. + if (blink_glue::HasPluginFrameOwner(frame_)) + return; + blink::WebDocumentLoader* dl = frame_->GetDocumentLoader(); const int http_status_code = dl->GetResponse().HttpStatusCode(); Send(new CefHostMsg_DidFinishLoad(MSG_ROUTING_NONE, dl->GetUrl(), diff --git a/libcef/renderer/render_frame_observer.cc b/libcef/renderer/render_frame_observer.cc index ec1b48789..c58462807 100644 --- a/libcef/renderer/render_frame_observer.cc +++ b/libcef/renderer/render_frame_observer.cc @@ -25,6 +25,8 @@ #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_view.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" #include "third_party/blink/public/web/blink.h" #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_local_frame.h" @@ -42,6 +44,12 @@ void CefRenderFrameObserver::OnInterfaceRequestForFrame( registry_.TryBindInterface(interface_name, interface_pipe); } +bool CefRenderFrameObserver::OnAssociatedInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle* handle) { + return associated_interfaces_.TryBindInterface(interface_name, handle); +} + void CefRenderFrameObserver::DidCommitProvisionalLoad( bool is_same_document_navigation, ui::PageTransition transition) { diff --git a/libcef/renderer/render_frame_observer.h b/libcef/renderer/render_frame_observer.h index d03319ad4..f6b2559d8 100644 --- a/libcef/renderer/render_frame_observer.h +++ b/libcef/renderer/render_frame_observer.h @@ -7,6 +7,7 @@ #include "content/public/renderer/render_frame_observer.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; @@ -24,6 +25,9 @@ class CefRenderFrameObserver : public content::RenderFrameObserver { void OnInterfaceRequestForFrame( const std::string& interface_name, mojo::ScopedMessagePipeHandle* interface_pipe) override; + bool OnAssociatedInterfaceRequestForFrame( + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle* handle) override; void DidCommitProvisionalLoad(bool is_same_document_navigation, ui::PageTransition transition) override; void DidFailProvisionalLoad() override; @@ -40,6 +44,9 @@ class CefRenderFrameObserver : public content::RenderFrameObserver { bool OnMessageReceived(const IPC::Message& message) override; service_manager::BinderRegistry* registry() { return ®istry_; } + blink::AssociatedInterfaceRegistry* associated_interfaces() { + return &associated_interfaces_; + } void AttachFrame(CefFrameImpl* frame); @@ -48,6 +55,7 @@ class CefRenderFrameObserver : public content::RenderFrameObserver { void OnLoadError(); service_manager::BinderRegistry registry_; + blink::AssociatedInterfaceRegistry associated_interfaces_; CefFrameImpl* frame_ = nullptr; DISALLOW_COPY_AND_ASSIGN(CefRenderFrameObserver); diff --git a/patch/patch.cfg b/patch/patch.cfg index d557ee5ff..b67be9f48 100644 --- a/patch/patch.cfg +++ b/patch/patch.cfg @@ -113,9 +113,11 @@ patches = [ 'name': 'web_contents_1257_1565', }, { - # Support custom RenderWidgetHostViewOSR for BrowserPluginGuest. + # Support custom RenderWidgetHostViewOSR for MimeHandlerViewGuest and + # expose OnGuestAttached/Detached notifications. # https://bitbucket.org/chromiumembedded/cef/issues/1565 - 'name': 'browser_plugin_guest_1565', + # https://bitbucket.org/chromiumembedded/cef/issues/2727 + 'name': 'mime_handler_view_guest_1565_2727', }, { # Allow customization of the WebView background color. diff --git a/patch/patches/browser_plugin_guest_1565.patch b/patch/patches/mime_handler_view_guest_1565_2727.patch similarity index 82% rename from patch/patches/browser_plugin_guest_1565.patch rename to patch/patches/mime_handler_view_guest_1565_2727.patch index 1bccb150c..025e6046f 100644 --- a/patch/patches/browser_plugin_guest_1565.patch +++ b/patch/patches/mime_handler_view_guest_1565_2727.patch @@ -1,21 +1,8 @@ diff --git content/browser/browser_plugin/browser_plugin_guest.cc content/browser/browser_plugin/browser_plugin_guest.cc -index 6eb21be63dec..87ccc46f4d43 100644 +index 6eb21be63dec..8617eff6bfc8 100644 --- content/browser/browser_plugin/browser_plugin_guest.cc +++ content/browser/browser_plugin/browser_plugin_guest.cc -@@ -306,8 +306,11 @@ void BrowserPluginGuest::InitInternal( - static_cast(GetWebContents()->GetView()); - } - -- if (owner_web_contents_ && new_view) -+ if (owner_web_contents_ && new_view) { - new_view->OnGuestDetached(owner_web_contents_->GetView()); -+ if (delegate_) -+ delegate_->OnGuestDetached(owner_web_contents_->GetView()); -+ } - - // Once a BrowserPluginGuest has an embedder WebContents, it's considered to - // be attached. -@@ -820,10 +823,19 @@ void BrowserPluginGuest::OnWillAttachComplete( +@@ -820,7 +820,8 @@ void BrowserPluginGuest::OnWillAttachComplete( static_cast(GetWebContents()->GetView()); if (!web_contents()->GetRenderViewHost()->GetWidget()->GetView()) { web_contents_view->CreateViewForWidget( @@ -25,17 +12,6 @@ index 6eb21be63dec..87ccc46f4d43 100644 } } -+ if (delegate_) { -+ // Notify the delegate here instead of in InitInternal because InitInternal -+ // will now be called from Init before GuestViewBase::CompleteInit has set -+ // web_contents() to the guest WebContents. This behavior change is due to -+ // https://crrev.com/07263b56. -+ delegate_->OnGuestAttached(embedder_web_contents->GetView()); -+ } -+ - InitInternal(params, embedder_web_contents); - - attached_ = true; diff --git content/browser/frame_host/interstitial_page_impl.cc content/browser/frame_host/interstitial_page_impl.cc index 7bb71f92bb0a..a6b89a831044 100644 --- content/browser/frame_host/interstitial_page_impl.cc @@ -242,31 +218,8 @@ index 4721a9b3f511..dfdd46d0c5d2 100644 RenderWidgetHostViewMac* view = g_create_render_widget_host_view ? g_create_render_widget_host_view(render_widget_host, -diff --git content/public/browser/browser_plugin_guest_delegate.h content/public/browser/browser_plugin_guest_delegate.h -index ea12af6b86b8..f1211f374328 100644 ---- content/public/browser/browser_plugin_guest_delegate.h -+++ content/public/browser/browser_plugin_guest_delegate.h -@@ -20,6 +20,7 @@ class GuestHost; - class RenderFrameHost; - class RenderWidgetHost; - class SiteInstance; -+class WebContentsView; - - // Objects implement this interface to get notified about changes in the guest - // WebContents and to provide necessary functionality. -@@ -68,6 +69,10 @@ class CONTENT_EXPORT BrowserPluginGuestDelegate { - // content module. - virtual void SetGuestHost(GuestHost* guest_host) {} - -+ // Called when a guest is attached or detached. -+ virtual void OnGuestAttached(content::WebContentsView* parent_view) {} -+ virtual void OnGuestDetached(content::WebContentsView* parent_view) {} -+ - // TODO(ekaramad): A short workaround to force some types of guests to use - // a BrowserPlugin even when we are using cross process frames for guests. It - // should be removed after resolving https://crbug.com/642826). diff --git extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc -index fa13ab856de9..ddc70aedbab2 100644 +index fa13ab856de9..81216c2bc8ff 100644 --- extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc +++ extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc @@ -215,6 +215,8 @@ void MimeHandlerViewGuest::CreateWebContents( @@ -278,42 +231,42 @@ index fa13ab856de9..ddc70aedbab2 100644 // TODO(erikchen): Fix ownership semantics for guest views. // https://crbug.com/832879. std::move(callback).Run( -@@ -259,6 +261,18 @@ bool MimeHandlerViewGuest::ShouldDestroyOnDetach() const { +@@ -230,6 +232,9 @@ void MimeHandlerViewGuest::CreateWebContents( + } + + void MimeHandlerViewGuest::DidAttachToEmbedder() { ++ if (delegate_) ++ delegate_->OnGuestAttached(); ++ + web_contents()->GetController().LoadURL( + stream_->handler_url(), content::Referrer(), + ui::PAGE_TRANSITION_AUTO_TOPLEVEL, std::string()); +@@ -259,6 +264,11 @@ bool MimeHandlerViewGuest::ShouldDestroyOnDetach() const { return true; } -+void MimeHandlerViewGuest::OnGuestAttached( -+ content::WebContentsView* parent_view) { ++void MimeHandlerViewGuest::WillDestroy() { + if (delegate_) -+ delegate_->OnGuestAttached(parent_view); -+} -+ -+void MimeHandlerViewGuest::OnGuestDetached( -+ content::WebContentsView* parent_view) { -+ if (delegate_) -+ delegate_->OnGuestDetached(parent_view); ++ delegate_->OnGuestDetached(); +} + WebContents* MimeHandlerViewGuest::OpenURLFromTab( WebContents* source, const content::OpenURLParams& params) { diff --git extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h -index 3d0b70d06fe7..a33da99391f6 100644 +index 3d0b70d06fe7..06d5e5d4e9e3 100644 --- extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h +++ extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h -@@ -128,6 +128,10 @@ class MimeHandlerViewGuest +@@ -127,6 +127,7 @@ class MimeHandlerViewGuest + void EmbedderFullscreenToggled(bool entered_fullscreen) final; bool ZoomPropagatesFromEmbedderToGuest() const final; bool ShouldDestroyOnDetach() const final; ++ void WillDestroy() override; -+ // content::BrowserPluginGuestDelegate implementation -+ void OnGuestAttached(content::WebContentsView* parent_view) override; -+ void OnGuestDetached(content::WebContentsView* parent_view) override; -+ // WebContentsDelegate implementation. content::WebContents* OpenURLFromTab( - content::WebContents* source, diff --git extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h -index 98689e261460..c501568b6f70 100644 +index 98689e261460..a1b08274f455 100644 --- extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h +++ extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h @@ -8,9 +8,9 @@ @@ -336,8 +289,8 @@ index 98689e261460..c501568b6f70 100644 + content::WebContents::CreateParams* params) {} + + // Called when a guest is attached or detached. -+ virtual void OnGuestAttached(content::WebContentsView* parent_view) {} -+ virtual void OnGuestDetached(content::WebContentsView* parent_view) {} ++ virtual void OnGuestAttached() {} ++ virtual void OnGuestDetached() {} + // Handles context menu, or returns false if unhandled. virtual bool HandleContextMenu(content::WebContents* web_contents, diff --git a/tests/ceftests/plugin_unittest.cc b/tests/ceftests/plugin_unittest.cc index 276d054b3..c70332cc8 100644 --- a/tests/ceftests/plugin_unittest.cc +++ b/tests/ceftests/plugin_unittest.cc @@ -5,7 +5,6 @@ #include "include/base/cef_bind.h" #include "include/cef_pack_resources.h" #include "include/cef_request_context_handler.h" -#include "include/cef_resource_bundle.h" #include "include/wrapper/cef_closure_task.h" #include "include/wrapper/cef_stream_resource_handler.h" #include "tests/ceftests/routing_test_handler.h" @@ -15,16 +14,6 @@ namespace { -std::string GetDataResourceAsString(int resource_id) { - void* data; - size_t data_size; - if (CefResourceBundle::GetGlobal()->GetDataResource(resource_id, data, - data_size)) { - return std::string(static_cast(data), data_size); - } - return std::string(); -} - // Browser-side app delegate. class PluginBrowserTest : public client::ClientAppBrowser::Delegate { public: @@ -272,38 +261,18 @@ class PluginTestHandler : public RoutingTestHandler, } void WaitForPluginLoad(CefRefPtr frame) { - if (url_ == kPdfHtmlUrl) { - // PDFScriptingAPI does not work with iframes (the LoadCallback will - // never be executed). Use a timeout instead. - if (got_context_menu_dismissed_) { - // After context menu display. Destroy the test. - CefPostDelayedTask(TID_UI, - base::Bind(&PluginTestHandler::DestroyTest, this), - kPdfLoadDelayMs); - } else { - // Trigger the context menu. - CefPostDelayedTask(TID_UI, - base::Bind(&PluginTestHandler::TriggerContextMenu, - this, frame->GetBrowser()), - kPdfLoadDelayMs); - } - return; + if (got_context_menu_dismissed_) { + // After context menu display. Destroy the test. + CefPostDelayedTask(TID_UI, + base::Bind(&PluginTestHandler::DestroyTest, this), + kPdfLoadDelayMs); + } else { + // Trigger the context menu. + CefPostDelayedTask(TID_UI, + base::Bind(&PluginTestHandler::TriggerContextMenu, + this, frame->GetBrowser()), + kPdfLoadDelayMs); } - - // Wait for the PDF file to load. - // See chrome/browser/pdf/pdf_extension_test_util.cc. - const std::string& scripting_api_js = - GetDataResourceAsString(IDR_PDF_PDF_SCRIPTING_API_JS); - EXPECT_TRUE(!scripting_api_js.empty()); - frame->ExecuteJavaScript(scripting_api_js, frame->GetURL(), 0); - - const std::string& code = - "var scriptingAPI = new PDFScriptingAPI(window, " + GetPluginNode() + - ");" - "scriptingAPI.setLoadCallback(function(success) {" - " window.testQuery({request:'plugin_ready'});" - "});"; - frame->ExecuteJavaScript(code, frame->GetURL(), 0); } void EndTest() { @@ -420,19 +389,6 @@ class PluginTestHandler : public RoutingTestHandler, // The plugin placeholder has been hidden. End the test. EndTest(); - } else if (request == "plugin_ready") { - EXPECT_FALSE(got_plugin_ready_); - got_plugin_ready_.yes(); - - // The plugin has loaded the PDF file. - if (got_context_menu_dismissed_) { - // After context menu display. End the test. - EndTest(); - } else { - // Trigger the context menu. - CefPostTask(TID_UI, base::Bind(&PluginTestHandler::TriggerContextMenu, - this, browser)); - } } else { NOTREACHED(); } @@ -448,8 +404,8 @@ class PluginTestHandler : public RoutingTestHandler, mouse_event.y = 100; // Send right-click mouse down and mouse up to tigger context menu. - browser->GetHost()->SendMouseClickEvent(mouse_event, MBT_RIGHT, false, 0); - browser->GetHost()->SendMouseClickEvent(mouse_event, MBT_RIGHT, true, 0); + browser->GetHost()->SendMouseClickEvent(mouse_event, MBT_RIGHT, false, 1); + browser->GetHost()->SendMouseClickEvent(mouse_event, MBT_RIGHT, true, 1); } bool RunContextMenu(CefRefPtr browser, @@ -514,14 +470,8 @@ class PluginTestHandler : public RoutingTestHandler, if (HasContextHide()) { EXPECT_TRUE(got_placeholder_hidden_); - EXPECT_FALSE(got_plugin_ready_); } else { EXPECT_FALSE(got_placeholder_hidden_); - - if (url_ == kPdfDirectUrl) - EXPECT_TRUE(got_plugin_ready_); - else - EXPECT_FALSE(got_plugin_ready_); } if (HasRequestContextHandler()) @@ -587,7 +537,6 @@ class PluginTestHandler : public RoutingTestHandler, TrackCallback got_pdf_plugin_found_; TrackCallback got_pdf_plugin_missing_; TrackCallback got_placeholder_hidden_; - TrackCallback got_plugin_ready_; TrackCallback got_run_context_menu_; TrackCallback got_context_menu_dismissed_;