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).
This commit is contained in:
Marshall Greenblatt 2020-01-23 16:58:01 -05:00
parent f2f6ae4f29
commit a12c2ab3e1
38 changed files with 1030 additions and 917 deletions

View File

@ -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.

View File

@ -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) {

View File

@ -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<int>(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<CefBrowserInfo> 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<PendingNewBrowserInfo> 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<CefDictionaryValueImpl*>(extra_info.get());
auto extra_info_value = extra_info_impl->CopyValue();
extra_info_value->Swap(&params.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<CefDictionaryValueImpl*>(extra_info.get());
auto extra_info_value = extra_info_impl->CopyValue();
extra_info_value->Swap(&params.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);
}
}

View File

@ -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<std::unique_ptr<PendingPopup>>;
PendingPopupList pending_popup_list_;
int next_timeout_id_ = 0;
DISALLOW_COPY_AND_ASSIGN(CefBrowserInfoManager);
};

View File

@ -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;
}

View File

@ -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.

View File

@ -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);

View File

@ -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<CefFileDialogRunner> CreateFileDialogRunner() override;

View File

@ -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 */,

View File

@ -17,22 +17,9 @@
namespace extensions {
namespace {
CefRefPtr<CefBrowserHostImpl> GetOwnerBrowser(
extensions::MimeHandlerViewGuest* guest) {
content::WebContents* owner_web_contents = guest->owner_web_contents();
CefRefPtr<CefBrowserHostImpl> 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<CefBrowserHostImpl> owner_browser = GetOwnerBrowser(guest_);
CefRefPtr<CefBrowserHostImpl> 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<CefBrowserHostImpl> 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<CefBrowserHostImpl> 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<CefBrowserHostImpl> owner_browser =
CefBrowserHostImpl::GetBrowserForContents(owner_web_contents_);
DCHECK(owner_browser);
return owner_browser->HandleContextMenu(web_contents, new_params);
}
} // namespace extensions

View File

@ -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);
};

View File

@ -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

View File

@ -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;
}

View File

@ -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_;

View File

@ -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<content::RenderWidgetHostViewAura*>(
browser_->web_contents()->GetRenderWidgetHostView());
}

View File

@ -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_

View File

@ -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<int>(
ui::KeycodeConverter::NativeKeycodeToDomCode(key_event.native_key_code));
int keysym = ui::XKeysymForWindowsKeyCode(
static_cast<ui::KeyboardCode>(key_event.windows_key_code),
!!(key_event.modifiers & EVENTFLAG_SHIFT_DOWN));
base::char16 ch = ui::GetUnicodeCharacterFromXKeySym(keysym);
result.dom_key = static_cast<int>(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<ui::KeyboardCode>(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());
}

View File

@ -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<CefMenuRunner> 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_;

View File

@ -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<CefFileDialogRunner> 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_;

View File

@ -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<CefFileDialogRunner>
CefBrowserPlatformDelegateNativeMac::CreateFileDialogRunner() {
return base::WrapUnique(new CefFileDialogRunnerMac);
}
std::unique_ptr<CefJavaScriptDialogRunner>
CefBrowserPlatformDelegateNativeMac::CreateJavaScriptDialogRunner() {
return base::WrapUnique(new CefJavaScriptDialogRunnerMac);
}
std::unique_ptr<CefMenuRunner>
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<CefFileDialogRunner>
CefBrowserPlatformDelegateNativeMac::CreateFileDialogRunner() {
return base::WrapUnique(new CefFileDialogRunnerMac);
}
std::unique_ptr<CefJavaScriptDialogRunner>
CefBrowserPlatformDelegateNativeMac::CreateJavaScriptDialogRunner() {
return base::WrapUnique(new CefJavaScriptDialogRunnerMac);
}
std::unique_ptr<CefMenuRunner>
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<content::RenderWidgetHostViewMac*>(
browser_->web_contents()->GetRenderWidgetHostView());
}

View File

@ -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<int>(
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<float>(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<FLOAT>(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<FLOAT>(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<FLOAT>(scrollChars) * scrollbarPixelsPerLine;
ULONG scrollLines = defaultScrollLinesPerWheelDelta;
SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, 0);
scrollDeltaY *= static_cast<FLOAT>(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;

View File

@ -7,11 +7,11 @@
#include <windows.h>
#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<CefFileDialogRunner> 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,

View File

@ -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<blink::WebDragOperationsMask>(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<blink::WebDragOperationsMask>(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<CefDragDataImpl*>(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);

View File

@ -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<CefFileDialogRunner> 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<CefCompositionUnderline>& underlines,

View File

@ -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);

View File

@ -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<CefFileDialogRunner> CreateFileDialogRunner() override;

View File

@ -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";

View File

@ -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[];

View File

@ -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) {

View File

@ -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

View File

@ -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_

View File

@ -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<CefBrowserImpl> 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<CefGuestView>(render_view, params.is_windowless)));

View File

@ -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(),

View File

@ -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) {

View File

@ -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 &registry_; }
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);

View File

@ -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.

View File

@ -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<WebContentsViewGuest*>(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<WebContentsViewGuest*>(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,

View File

@ -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<char*>(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<CefFrame> 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<CefBrowser> 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_;