Commit f56bb0f1 authored by Dave Tapuska's avatar Dave Tapuska Committed by Commit Bot

Implement a WebExternalWidget

This change makes all WebWidgets be created by blink. Since all
WebWidgets are created by blink they have a common base member
WidgetBase which will eventually create and own
the compositing, input and emulation infrastructure.

Change-Id: I306658e8d3b941bcbb93f864e503112387dbd169
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2042510Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatardanakj <danakj@chromium.org>
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
Cr-Commit-Position: refs/heads/master@{#746841}
parent 3923b9b7
...@@ -1111,7 +1111,7 @@ void LayerTreeHost::SetNonBlinkManagedRootLayer( ...@@ -1111,7 +1111,7 @@ void LayerTreeHost::SetNonBlinkManagedRootLayer(
scoped_refptr<Layer> root_layer) { scoped_refptr<Layer> root_layer) {
SetRootLayer(std::move(root_layer)); SetRootLayer(std::move(root_layer));
DCHECK(root_layer_->children().empty()); DCHECK(!root_layer || root_layer_->children().empty());
if (IsUsingLayerLists() && root_layer_) if (IsUsingLayerLists() && root_layer_)
force_use_property_tree_builder_ = true; force_use_property_tree_builder_ = true;
} }
......
...@@ -445,7 +445,7 @@ void RenderWidgetInputHandler::HandleInputEvent( ...@@ -445,7 +445,7 @@ void RenderWidgetInputHandler::HandleInputEvent(
suppress_next_char_events_ = false; suppress_next_char_events_ = false;
if (processed == WebInputEventResult::kNotHandled && if (processed == WebInputEventResult::kNotHandled &&
widget_->GetWebWidget()) { widget_->GetWebWidget()) {
if (!widget_->GetWebWidget()->IsPepperWidget() && if (delegate_->SupportsBufferedTouchEvents() &&
WebInputEvent::IsTouchEventType(input_event.GetType())) WebInputEvent::IsTouchEventType(input_event.GetType()))
processed = HandleTouchEvent(coalesced_event); processed = HandleTouchEvent(coalesced_event);
else else
......
...@@ -70,8 +70,11 @@ class CONTENT_EXPORT RenderWidgetInputHandlerDelegate { ...@@ -70,8 +70,11 @@ class CONTENT_EXPORT RenderWidgetInputHandlerDelegate {
// won't be sent to WebKit or trigger DidHandleMouseEvent(). // won't be sent to WebKit or trigger DidHandleMouseEvent().
virtual bool WillHandleMouseEvent(const blink::WebMouseEvent& event) = 0; virtual bool WillHandleMouseEvent(const blink::WebMouseEvent& event) = 0;
// Whether buffered touch events should be supported or not.
virtual bool SupportsBufferedTouchEvents() = 0;
protected: protected:
virtual ~RenderWidgetInputHandlerDelegate() {} virtual ~RenderWidgetInputHandlerDelegate() = default;
}; };
} // namespace content } // namespace content
......
...@@ -1543,6 +1543,11 @@ bool RenderWidget::WillHandleMouseEvent(const blink::WebMouseEvent& event) { ...@@ -1543,6 +1543,11 @@ bool RenderWidget::WillHandleMouseEvent(const blink::WebMouseEvent& event) {
return mouse_lock_dispatcher()->WillHandleMouseEvent(event); return mouse_lock_dispatcher()->WillHandleMouseEvent(event);
} }
bool RenderWidget::SupportsBufferedTouchEvents() {
// Buffered touch events aren't supported for pepper.
return !pepper_fullscreen_;
}
void RenderWidget::ResizeWebWidget() { void RenderWidget::ResizeWebWidget() {
// In auto resize mode, blink controls sizes and RenderWidget should not be // In auto resize mode, blink controls sizes and RenderWidget should not be
// passing values back in. // passing values back in.
......
...@@ -351,6 +351,7 @@ class CONTENT_EXPORT RenderWidget ...@@ -351,6 +351,7 @@ class CONTENT_EXPORT RenderWidget
void ClearTextInputState() override; void ClearTextInputState() override;
bool WillHandleGestureEvent(const blink::WebGestureEvent& event) override; bool WillHandleGestureEvent(const blink::WebGestureEvent& event) override;
bool WillHandleMouseEvent(const blink::WebMouseEvent& event) override; bool WillHandleMouseEvent(const blink::WebMouseEvent& event) override;
bool SupportsBufferedTouchEvents() override;
// RenderWidgetScreenMetricsEmulatorDelegate // RenderWidgetScreenMetricsEmulatorDelegate
void SetScreenMetricsEmulationParameters( void SetScreenMetricsEmulationParameters(
......
...@@ -41,7 +41,6 @@ using blink::WebSize; ...@@ -41,7 +41,6 @@ using blink::WebSize;
using blink::WebString; using blink::WebString;
using blink::WebTextInputType; using blink::WebTextInputType;
using blink::WebVector; using blink::WebVector;
using blink::WebWidget;
namespace content { namespace content {
...@@ -126,142 +125,34 @@ void FullscreenMouseLockDispatcher::SendUnlockMouseRequest() { ...@@ -126,142 +125,34 @@ void FullscreenMouseLockDispatcher::SendUnlockMouseRequest() {
widget_->Send(new WidgetHostMsg_UnlockMouse(widget_->routing_id())); widget_->Send(new WidgetHostMsg_UnlockMouse(widget_->routing_id()));
} }
// WebWidget that simply wraps the pepper plugin. } // anonymous namespace
// TODO(piman): figure out IME and implement setComposition and friends if
// necessary.
class PepperWidget : public WebWidget {
public:
explicit PepperWidget(RenderWidgetFullscreenPepper* widget,
const blink::WebURL& local_main_frame_url)
: widget_(widget), local_main_frame_url_(local_main_frame_url) {}
virtual ~PepperWidget() = default;
// WebWidget API
void SetCompositorHosts(cc::LayerTreeHost*, cc::AnimationHost*) override {
// These pointers are not stored as they aren't needed.
}
void Close() override { delete this; }
WebSize Size() override { return size_; }
bool IsPepperWidget() const override { return true; }
void Resize(const WebSize& size) override {
if (!widget_->plugin() || size_ == size)
return;
size_ = size;
WebRect plugin_rect(0, 0, size_.width, size_.height);
widget_->plugin()->ViewChanged(plugin_rect, plugin_rect, plugin_rect);
}
void ThemeChanged() override { NOTIMPLEMENTED(); }
blink::WebHitTestResult HitTestResultAt(const gfx::Point&) override { // We place the WebExternalWidgetClient interface on a separate class because
NOTIMPLEMENTED(); // RenderWidget implements blink::WebWidgetClient, which is not used for
return {}; // WebExternalWidgets, but may have similar method definitions as this
// interface.
class PepperExternalWidgetClient : public blink::WebExternalWidgetClient {
public:
explicit PepperExternalWidgetClient(RenderWidgetFullscreenPepper* widget)
: widget_(widget) {}
~PepperExternalWidgetClient() override = default;
// blink::WebExternalWidgetClient overrides:
blink::WebInputEventResult HandleInputEvent(
const blink::WebCoalescedInputEvent& event) override {
return widget_->ProcessInputEvent(event);
} }
WebInputEventResult HandleInputEvent( blink::WebInputEventResult DispatchBufferedTouchEvents() override {
const WebCoalescedInputEvent& coalesced_event) override { return WebInputEventResult::kNotHandled;
if (!widget_->plugin())
return WebInputEventResult::kNotHandled;
const WebInputEvent& event = coalesced_event.Event();
// This cursor info is ignored, we always set the cursor directly from
// RenderWidgetFullscreenPepper::DidChangeCursor.
WebCursorInfo cursor;
// Pepper plugins do not accept gesture events. So do not send the gesture
// events directly to the plugin. Instead, try to convert them to equivalent
// mouse events, and then send to the plugin.
if (WebInputEvent::IsGestureEventType(event.GetType())) {
bool result = false;
const WebGestureEvent* gesture_event =
static_cast<const WebGestureEvent*>(&event);
switch (event.GetType()) {
case WebInputEvent::kGestureTap: {
WebMouseEvent mouse(WebInputEvent::kMouseMove,
gesture_event->GetModifiers(),
gesture_event->TimeStamp());
mouse.SetPositionInWidget(gesture_event->PositionInWidget());
mouse.SetPositionInScreen(gesture_event->PositionInScreen());
mouse.movement_x = 0;
mouse.movement_y = 0;
result |= widget_->plugin()->HandleInputEvent(mouse, &cursor);
mouse.SetType(WebInputEvent::kMouseDown);
mouse.button = WebMouseEvent::Button::kLeft;
mouse.click_count = gesture_event->data.tap.tap_count;
result |= widget_->plugin()->HandleInputEvent(mouse, &cursor);
mouse.SetType(WebInputEvent::kMouseUp);
result |= widget_->plugin()->HandleInputEvent(mouse, &cursor);
break;
}
default: {
WebMouseEvent mouse = WebMouseEventFromGestureEvent(*gesture_event);
if (mouse.GetType() != WebInputEvent::kUndefined)
result |= widget_->plugin()->HandleInputEvent(mouse, &cursor);
break;
}
}
return result ? WebInputEventResult::kHandledApplication
: WebInputEventResult::kNotHandled;
}
bool result = widget_->plugin()->HandleInputEvent(event, &cursor);
// For normal web pages, WebViewImpl does input event translations and
// generates context menu events. Since we don't have a WebView, we need to
// do the necessary translation ourselves.
if (WebInputEvent::IsMouseEventType(event.GetType())) {
const WebMouseEvent& mouse_event =
reinterpret_cast<const WebMouseEvent&>(event);
bool send_context_menu_event = false;
// On Mac/Linux, we handle it on mouse down.
// On Windows, we handle it on mouse up.
#if defined(OS_WIN)
send_context_menu_event =
mouse_event.GetType() == WebInputEvent::kMouseUp &&
mouse_event.button == WebMouseEvent::Button::kRight;
#elif defined(OS_MACOSX)
send_context_menu_event =
mouse_event.GetType() == WebInputEvent::kMouseDown &&
(mouse_event.button == WebMouseEvent::Button::kRight ||
(mouse_event.button == WebMouseEvent::Button::kLeft &&
mouse_event.GetModifiers() & WebMouseEvent::kControlKey));
#else
send_context_menu_event =
mouse_event.GetType() == WebInputEvent::kMouseDown &&
mouse_event.button == WebMouseEvent::Button::kRight;
#endif
if (send_context_menu_event) {
WebMouseEvent context_menu_event(mouse_event);
context_menu_event.SetType(WebInputEvent::kContextMenu);
widget_->plugin()->HandleInputEvent(context_menu_event, &cursor);
}
}
return result ? WebInputEventResult::kHandledApplication
: WebInputEventResult::kNotHandled;
} }
blink::WebURL GetURLForDebugTrace() override { return local_main_frame_url_; } void DidResize(const gfx::Size& size) override { widget_->DidResize(size); }
private: private:
RenderWidgetFullscreenPepper* widget_; RenderWidgetFullscreenPepper* widget_;
WebSize size_;
blink::WebURL local_main_frame_url_;
DISALLOW_COPY_AND_ASSIGN(PepperWidget);
}; };
} // anonymous namespace
// static // static
RenderWidgetFullscreenPepper* RenderWidgetFullscreenPepper::Create( RenderWidgetFullscreenPepper* RenderWidgetFullscreenPepper::Create(
int32_t routing_id, int32_t routing_id,
...@@ -273,19 +164,22 @@ RenderWidgetFullscreenPepper* RenderWidgetFullscreenPepper::Create( ...@@ -273,19 +164,22 @@ RenderWidgetFullscreenPepper* RenderWidgetFullscreenPepper::Create(
mojo::PendingReceiver<mojom::Widget> widget_receiver) { mojo::PendingReceiver<mojom::Widget> widget_receiver) {
DCHECK_NE(MSG_ROUTING_NONE, routing_id); DCHECK_NE(MSG_ROUTING_NONE, routing_id);
DCHECK(show_callback); DCHECK(show_callback);
RenderWidgetFullscreenPepper* widget = new RenderWidgetFullscreenPepper( RenderWidgetFullscreenPepper* render_widget =
routing_id, compositor_deps, plugin, std::move(widget_receiver)); new RenderWidgetFullscreenPepper(routing_id, compositor_deps, plugin,
widget->InitForPepperFullscreen( std::move(widget_receiver),
std::move(show_callback), new PepperWidget(widget, local_main_frame_url), local_main_frame_url);
screen_info); render_widget->InitForPepperFullscreen(std::move(show_callback),
return widget; render_widget->blink_widget_.get(),
screen_info);
return render_widget;
} }
RenderWidgetFullscreenPepper::RenderWidgetFullscreenPepper( RenderWidgetFullscreenPepper::RenderWidgetFullscreenPepper(
int32_t routing_id, int32_t routing_id,
CompositorDependencies* compositor_deps, CompositorDependencies* compositor_deps,
PepperPluginInstanceImpl* plugin, PepperPluginInstanceImpl* plugin,
mojo::PendingReceiver<mojom::Widget> widget_receiver) mojo::PendingReceiver<mojom::Widget> widget_receiver,
blink::WebURL main_frame_url)
: RenderWidget(routing_id, : RenderWidget(routing_id,
compositor_deps, compositor_deps,
/*display_mode=*/blink::mojom::DisplayMode::kUndefined, /*display_mode=*/blink::mojom::DisplayMode::kUndefined,
...@@ -294,11 +188,14 @@ RenderWidgetFullscreenPepper::RenderWidgetFullscreenPepper( ...@@ -294,11 +188,14 @@ RenderWidgetFullscreenPepper::RenderWidgetFullscreenPepper(
std::move(widget_receiver)), std::move(widget_receiver)),
plugin_(plugin), plugin_(plugin),
mouse_lock_dispatcher_( mouse_lock_dispatcher_(
std::make_unique<FullscreenMouseLockDispatcher>(this)) {} std::make_unique<FullscreenMouseLockDispatcher>(this)),
widget_client_(std::make_unique<PepperExternalWidgetClient>(this)) {
RenderWidgetFullscreenPepper::~RenderWidgetFullscreenPepper() { blink_widget_ =
blink::WebExternalWidget::Create(widget_client_.get(), main_frame_url);
} }
RenderWidgetFullscreenPepper::~RenderWidgetFullscreenPepper() = default;
void RenderWidgetFullscreenPepper::Destroy() { void RenderWidgetFullscreenPepper::Destroy() {
// The plugin instance is going away reset any lock target that is set // The plugin instance is going away reset any lock target that is set
// on the dispatcher since this object can still live and receive IPC // on the dispatcher since this object can still live and receive IPC
...@@ -327,13 +224,13 @@ void RenderWidgetFullscreenPepper::PepperDidChangeCursor( ...@@ -327,13 +224,13 @@ void RenderWidgetFullscreenPepper::PepperDidChangeCursor(
void RenderWidgetFullscreenPepper::SetLayer(scoped_refptr<cc::Layer> layer) { void RenderWidgetFullscreenPepper::SetLayer(scoped_refptr<cc::Layer> layer) {
layer_ = layer.get(); layer_ = layer.get();
if (!layer_) { if (!layer_) {
layer_tree_host()->SetRootLayer(nullptr); blink_widget_->SetRootLayer(nullptr);
return; return;
} }
UpdateLayerBounds(); UpdateLayerBounds();
layer_->SetIsDrawable(true); layer_->SetIsDrawable(true);
layer_->SetHitTestable(true); layer_->SetHitTestable(true);
layer_tree_host()->SetNonBlinkManagedRootLayer(std::move(layer)); blink_widget_->SetRootLayer(std::move(layer));
} }
bool RenderWidgetFullscreenPepper::OnMessageReceived(const IPC::Message& msg) { bool RenderWidgetFullscreenPepper::OnMessageReceived(const IPC::Message& msg) {
...@@ -388,4 +285,97 @@ void RenderWidgetFullscreenPepper::UpdateLayerBounds() { ...@@ -388,4 +285,97 @@ void RenderWidgetFullscreenPepper::UpdateLayerBounds() {
layer_->SetBounds(layer_size); layer_->SetBounds(layer_size);
} }
WebInputEventResult RenderWidgetFullscreenPepper::ProcessInputEvent(
const WebCoalescedInputEvent& coalesced_event) {
if (!plugin())
return WebInputEventResult::kNotHandled;
const WebInputEvent& event = coalesced_event.Event();
// This cursor info is ignored, we always set the cursor directly from
// RenderWidgetFullscreenPepper::DidChangeCursor.
blink::WebCursorInfo cursor;
// Pepper plugins do not accept gesture events. So do not send the gesture
// events directly to the plugin. Instead, try to convert them to equivalent
// mouse events, and then send to the plugin.
if (blink::WebInputEvent::IsGestureEventType(event.GetType())) {
bool result = false;
const WebGestureEvent* gesture_event =
static_cast<const WebGestureEvent*>(&event);
switch (event.GetType()) {
case WebInputEvent::kGestureTap: {
WebMouseEvent mouse(WebInputEvent::kMouseMove,
gesture_event->GetModifiers(),
gesture_event->TimeStamp());
mouse.SetPositionInWidget(gesture_event->PositionInWidget());
mouse.SetPositionInScreen(gesture_event->PositionInScreen());
mouse.movement_x = 0;
mouse.movement_y = 0;
result |= plugin()->HandleInputEvent(mouse, &cursor);
mouse.SetType(WebInputEvent::kMouseDown);
mouse.button = WebMouseEvent::Button::kLeft;
mouse.click_count = gesture_event->data.tap.tap_count;
result |= plugin()->HandleInputEvent(mouse, &cursor);
mouse.SetType(WebInputEvent::kMouseUp);
result |= plugin()->HandleInputEvent(mouse, &cursor);
break;
}
default: {
WebMouseEvent mouse = WebMouseEventFromGestureEvent(*gesture_event);
if (mouse.GetType() != WebInputEvent::kUndefined)
result |= plugin()->HandleInputEvent(mouse, &cursor);
break;
}
}
return result ? WebInputEventResult::kHandledApplication
: WebInputEventResult::kNotHandled;
}
bool result = plugin()->HandleInputEvent(event, &cursor);
// For normal web pages, WebViewImpl does input event translations and
// generates context menu events. Since we don't have a WebView, we need to
// do the necessary translation ourselves.
if (WebInputEvent::IsMouseEventType(event.GetType())) {
const WebMouseEvent& mouse_event =
reinterpret_cast<const WebMouseEvent&>(event);
bool send_context_menu_event = false;
// On Mac/Linux, we handle it on mouse down.
// On Windows, we handle it on mouse up.
#if defined(OS_WIN)
send_context_menu_event =
mouse_event.GetType() == WebInputEvent::kMouseUp &&
mouse_event.button == WebMouseEvent::Button::kRight;
#elif defined(OS_MACOSX)
send_context_menu_event =
mouse_event.GetType() == WebInputEvent::kMouseDown &&
(mouse_event.button == WebMouseEvent::Button::kRight ||
(mouse_event.button == WebMouseEvent::Button::kLeft &&
mouse_event.GetModifiers() & WebMouseEvent::kControlKey));
#else
send_context_menu_event =
mouse_event.GetType() == WebInputEvent::kMouseDown &&
mouse_event.button == WebMouseEvent::Button::kRight;
#endif
if (send_context_menu_event) {
WebMouseEvent context_menu_event(mouse_event);
context_menu_event.SetType(WebInputEvent::kContextMenu);
plugin()->HandleInputEvent(context_menu_event, &cursor);
}
}
return result ? WebInputEventResult::kHandledApplication
: WebInputEventResult::kNotHandled;
}
void RenderWidgetFullscreenPepper::DidResize(const gfx::Size& size) {
if (!plugin())
return;
gfx::Rect plugin_rect(size);
plugin()->ViewChanged(plugin_rect, plugin_rect, plugin_rect);
}
} // namespace content } // namespace content
...@@ -14,7 +14,8 @@ ...@@ -14,7 +14,8 @@
#include "content/renderer/pepper/fullscreen_container.h" #include "content/renderer/pepper/fullscreen_container.h"
#include "content/renderer/render_widget.h" #include "content/renderer/render_widget.h"
#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_receiver.h"
#include "third_party/blink/public/web/web_widget.h" #include "third_party/blink/public/web/web_external_widget.h"
#include "third_party/blink/public/web/web_external_widget_client.h"
#include "url/gurl.h" #include "url/gurl.h"
namespace cc { namespace cc {
...@@ -24,6 +25,7 @@ class Layer; ...@@ -24,6 +25,7 @@ class Layer;
namespace content { namespace content {
class CompositorDependencies; class CompositorDependencies;
class PepperPluginInstanceImpl; class PepperPluginInstanceImpl;
class PepperExternalWidgetClient;
// A RenderWidget that hosts a fullscreen pepper plugin. This provides a // A RenderWidget that hosts a fullscreen pepper plugin. This provides a
// FullscreenContainer that the plugin instance can callback into to e.g. // FullscreenContainer that the plugin instance can callback into to e.g.
...@@ -62,7 +64,8 @@ class RenderWidgetFullscreenPepper : public RenderWidget, ...@@ -62,7 +64,8 @@ class RenderWidgetFullscreenPepper : public RenderWidget,
int32_t routing_id, int32_t routing_id,
CompositorDependencies* compositor_deps, CompositorDependencies* compositor_deps,
PepperPluginInstanceImpl* plugin, PepperPluginInstanceImpl* plugin,
mojo::PendingReceiver<mojom::Widget> widget_receiver); mojo::PendingReceiver<mojom::Widget> widget_receiver,
blink::WebURL main_frame_url);
~RenderWidgetFullscreenPepper() override; ~RenderWidgetFullscreenPepper() override;
// RenderWidget API. // RenderWidget API.
...@@ -71,7 +74,12 @@ class RenderWidgetFullscreenPepper : public RenderWidget, ...@@ -71,7 +74,12 @@ class RenderWidgetFullscreenPepper : public RenderWidget,
void AfterUpdateVisualProperties() override; void AfterUpdateVisualProperties() override;
private: private:
friend class PepperExternalWidgetClient;
void UpdateLayerBounds(); void UpdateLayerBounds();
void DidResize(const gfx::Size& size);
blink::WebInputEventResult ProcessInputEvent(
const blink::WebCoalescedInputEvent& event);
// The plugin instance this widget wraps. // The plugin instance this widget wraps.
PepperPluginInstanceImpl* plugin_; PepperPluginInstanceImpl* plugin_;
...@@ -79,6 +87,8 @@ class RenderWidgetFullscreenPepper : public RenderWidget, ...@@ -79,6 +87,8 @@ class RenderWidgetFullscreenPepper : public RenderWidget,
cc::Layer* layer_ = nullptr; cc::Layer* layer_ = nullptr;
std::unique_ptr<MouseLockDispatcher> mouse_lock_dispatcher_; std::unique_ptr<MouseLockDispatcher> mouse_lock_dispatcher_;
std::unique_ptr<PepperExternalWidgetClient> widget_client_;
std::unique_ptr<blink::WebExternalWidget> blink_widget_;
DISALLOW_COPY_AND_ASSIGN(RenderWidgetFullscreenPepper); DISALLOW_COPY_AND_ASSIGN(RenderWidgetFullscreenPepper);
}; };
......
...@@ -41,7 +41,8 @@ ...@@ -41,7 +41,8 @@
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/public/platform/web_coalesced_input_event.h" #include "third_party/blink/public/platform/web_coalesced_input_event.h"
#include "third_party/blink/public/web/web_device_emulation_params.h" #include "third_party/blink/public/web/web_device_emulation_params.h"
#include "third_party/blink/public/web/web_widget.h" #include "third_party/blink/public/web/web_external_widget.h"
#include "third_party/blink/public/web/web_external_widget_client.h"
#include "ui/base/mojom/cursor_type.mojom-shared.h" #include "ui/base/mojom/cursor_type.mojom-shared.h"
#include "ui/events/base_event_utils.h" #include "ui/events/base_event_utils.h"
#include "ui/events/blink/web_input_event_traits.h" #include "ui/events/blink/web_input_event_traits.h"
...@@ -150,15 +151,12 @@ class MockHandledEventCallback { ...@@ -150,15 +151,12 @@ class MockHandledEventCallback {
DISALLOW_COPY_AND_ASSIGN(MockHandledEventCallback); DISALLOW_COPY_AND_ASSIGN(MockHandledEventCallback);
}; };
class MockWebWidget : public blink::WebWidget { class MockWebExternalWidgetClient : public blink::WebExternalWidgetClient {
public: public:
// WebWidget implementation. MockWebExternalWidgetClient() = default;
void SetCompositorHosts(cc::LayerTreeHost*, cc::AnimationHost*) override {}
blink::WebURL GetURLForDebugTrace() override { return {}; }
blink::WebHitTestResult HitTestResultAt(const gfx::Point&) override {
return {};
}
// WebExternalWidgetClient implementation.
MOCK_METHOD1(DidResize, void(const gfx::Size& size));
MOCK_METHOD0(DispatchBufferedTouchEvents, blink::WebInputEventResult()); MOCK_METHOD0(DispatchBufferedTouchEvents, blink::WebInputEventResult());
MOCK_METHOD1( MOCK_METHOD1(
HandleInputEvent, HandleInputEvent,
...@@ -177,8 +175,10 @@ class InteractiveRenderWidget : public RenderWidget { ...@@ -177,8 +175,10 @@ class InteractiveRenderWidget : public RenderWidget {
/*is_hidden=*/false, /*is_hidden=*/false,
/*never_composited=*/false, /*never_composited=*/false,
mojo::NullReceiver()), mojo::NullReceiver()),
always_overscroll_(false) { external_web_widget_(
Initialize(base::NullCallback(), &mock_webwidget_, screen_info); blink::WebExternalWidget::Create(&mock_web_external_widget_client_,
blink::WebURL())) {
Initialize(base::NullCallback(), external_web_widget_.get(), screen_info);
mock_input_handler_host_ = std::make_unique<MockWidgetInputHandlerHost>(); mock_input_handler_host_ = std::make_unique<MockWidgetInputHandlerHost>();
...@@ -203,12 +203,18 @@ class InteractiveRenderWidget : public RenderWidget { ...@@ -203,12 +203,18 @@ class InteractiveRenderWidget : public RenderWidget {
IPC::TestSink* sink() { return &sink_; } IPC::TestSink* sink() { return &sink_; }
MockWebWidget* mock_webwidget() { return &mock_webwidget_; } MockWebExternalWidgetClient* mock_web_external_widget_client() {
return &mock_web_external_widget_client_;
}
MockWidgetInputHandlerHost* mock_input_handler_host() { MockWidgetInputHandlerHost* mock_input_handler_host() {
return mock_input_handler_host_.get(); return mock_input_handler_host_.get();
} }
blink::WebExternalWidget* external_web_widget() {
return external_web_widget_.get();
}
const viz::LocalSurfaceIdAllocation& local_surface_id_allocation_from_parent() const viz::LocalSurfaceIdAllocation& local_surface_id_allocation_from_parent()
const { const {
return local_surface_id_allocation_from_parent_; return local_surface_id_allocation_from_parent_;
...@@ -240,8 +246,9 @@ class InteractiveRenderWidget : public RenderWidget { ...@@ -240,8 +246,9 @@ class InteractiveRenderWidget : public RenderWidget {
private: private:
IPC::TestSink sink_; IPC::TestSink sink_;
bool always_overscroll_; bool always_overscroll_ = false;
MockWebWidget mock_webwidget_; MockWebExternalWidgetClient mock_web_external_widget_client_;
std::unique_ptr<blink::WebExternalWidget> external_web_widget_;
std::unique_ptr<MockWidgetInputHandlerHost> mock_input_handler_host_; std::unique_ptr<MockWidgetInputHandlerHost> mock_input_handler_host_;
static int next_routing_id_; static int next_routing_id_;
...@@ -298,7 +305,7 @@ TEST_F(RenderWidgetUnittest, CursorChange) { ...@@ -298,7 +305,7 @@ TEST_F(RenderWidgetUnittest, CursorChange) {
widget()->DidChangeCursor(cursor_info); widget()->DidChangeCursor(cursor_info);
EXPECT_EQ(widget()->sink()->message_count(), 0U); EXPECT_EQ(widget()->sink()->message_count(), 0U);
EXPECT_CALL(*widget()->mock_webwidget(), HandleInputEvent(_)) EXPECT_CALL(*widget()->mock_web_external_widget_client(), HandleInputEvent(_))
.WillOnce(::testing::Return(blink::WebInputEventResult::kNotHandled)); .WillOnce(::testing::Return(blink::WebInputEventResult::kNotHandled));
widget()->SendInputEvent(SyntheticWebMouseEventBuilder::Build( widget()->SendInputEvent(SyntheticWebMouseEventBuilder::Build(
blink::WebInputEvent::Type::kMouseLeave), blink::WebInputEvent::Type::kMouseLeave),
...@@ -314,7 +321,7 @@ TEST_F(RenderWidgetUnittest, CursorChange) { ...@@ -314,7 +321,7 @@ TEST_F(RenderWidgetUnittest, CursorChange) {
TEST_F(RenderWidgetUnittest, EventOverscroll) { TEST_F(RenderWidgetUnittest, EventOverscroll) {
widget()->set_always_overscroll(true); widget()->set_always_overscroll(true);
EXPECT_CALL(*widget()->mock_webwidget(), HandleInputEvent(_)) EXPECT_CALL(*widget()->mock_web_external_widget_client(), HandleInputEvent(_))
.WillRepeatedly( .WillRepeatedly(
::testing::Return(blink::WebInputEventResult::kNotHandled)); ::testing::Return(blink::WebInputEventResult::kNotHandled));
...@@ -345,12 +352,13 @@ TEST_F(RenderWidgetUnittest, RenderWidgetInputEventUmaMetrics) { ...@@ -345,12 +352,13 @@ TEST_F(RenderWidgetUnittest, RenderWidgetInputEventUmaMetrics) {
touch.PressPoint(10, 10); touch.PressPoint(10, 10);
touch.touch_start_or_first_touch_move = true; touch.touch_start_or_first_touch_move = true;
EXPECT_CALL(*widget()->mock_webwidget(), HandleInputEvent(_)) EXPECT_CALL(*widget()->mock_web_external_widget_client(), HandleInputEvent(_))
.Times(5) .Times(5)
.WillRepeatedly( .WillRepeatedly(
::testing::Return(blink::WebInputEventResult::kNotHandled)); ::testing::Return(blink::WebInputEventResult::kNotHandled));
EXPECT_CALL(*widget()->mock_webwidget(), DispatchBufferedTouchEvents()) EXPECT_CALL(*widget()->mock_web_external_widget_client(),
DispatchBufferedTouchEvents())
.Times(5) .Times(5)
.WillRepeatedly( .WillRepeatedly(
::testing::Return(blink::WebInputEventResult::kNotHandled)); ::testing::Return(blink::WebInputEventResult::kNotHandled));
...@@ -387,9 +395,10 @@ TEST_F(RenderWidgetUnittest, RenderWidgetInputEventUmaMetrics) { ...@@ -387,9 +395,10 @@ TEST_F(RenderWidgetUnittest, RenderWidgetInputEventUmaMetrics) {
EVENT_LISTENER_RESULT_HISTOGRAM, EVENT_LISTENER_RESULT_HISTOGRAM,
PASSIVE_LISTENER_UMA_ENUM_FORCED_NON_BLOCKING_DUE_TO_FLING, 2); PASSIVE_LISTENER_UMA_ENUM_FORCED_NON_BLOCKING_DUE_TO_FLING, 2);
EXPECT_CALL(*widget()->mock_webwidget(), HandleInputEvent(_)) EXPECT_CALL(*widget()->mock_web_external_widget_client(), HandleInputEvent(_))
.WillOnce(::testing::Return(blink::WebInputEventResult::kNotHandled)); .WillOnce(::testing::Return(blink::WebInputEventResult::kNotHandled));
EXPECT_CALL(*widget()->mock_webwidget(), DispatchBufferedTouchEvents()) EXPECT_CALL(*widget()->mock_web_external_widget_client(),
DispatchBufferedTouchEvents())
.WillOnce( .WillOnce(
::testing::Return(blink::WebInputEventResult::kHandledSuppressed)); ::testing::Return(blink::WebInputEventResult::kHandledSuppressed));
touch.dispatch_type = blink::WebInputEvent::DispatchType::kBlocking; touch.dispatch_type = blink::WebInputEvent::DispatchType::kBlocking;
...@@ -397,9 +406,10 @@ TEST_F(RenderWidgetUnittest, RenderWidgetInputEventUmaMetrics) { ...@@ -397,9 +406,10 @@ TEST_F(RenderWidgetUnittest, RenderWidgetInputEventUmaMetrics) {
histogram_tester().ExpectBucketCount(EVENT_LISTENER_RESULT_HISTOGRAM, histogram_tester().ExpectBucketCount(EVENT_LISTENER_RESULT_HISTOGRAM,
PASSIVE_LISTENER_UMA_ENUM_SUPPRESSED, 1); PASSIVE_LISTENER_UMA_ENUM_SUPPRESSED, 1);
EXPECT_CALL(*widget()->mock_webwidget(), HandleInputEvent(_)) EXPECT_CALL(*widget()->mock_web_external_widget_client(), HandleInputEvent(_))
.WillOnce(::testing::Return(blink::WebInputEventResult::kNotHandled)); .WillOnce(::testing::Return(blink::WebInputEventResult::kNotHandled));
EXPECT_CALL(*widget()->mock_webwidget(), DispatchBufferedTouchEvents()) EXPECT_CALL(*widget()->mock_web_external_widget_client(),
DispatchBufferedTouchEvents())
.WillOnce( .WillOnce(
::testing::Return(blink::WebInputEventResult::kHandledApplication)); ::testing::Return(blink::WebInputEventResult::kHandledApplication));
touch.dispatch_type = blink::WebInputEvent::DispatchType::kBlocking; touch.dispatch_type = blink::WebInputEvent::DispatchType::kBlocking;
......
...@@ -321,6 +321,8 @@ source_set("blink_headers") { ...@@ -321,6 +321,8 @@ source_set("blink_headers") {
"web/web_embedded_worker_start_data.h", "web/web_embedded_worker_start_data.h",
"web/web_external_popup_menu.h", "web/web_external_popup_menu.h",
"web/web_external_popup_menu_client.h", "web/web_external_popup_menu_client.h",
"web/web_external_widget.h",
"web/web_external_widget_client.h",
"web/web_form_control_element.h", "web/web_form_control_element.h",
"web/web_form_element.h", "web/web_form_element.h",
"web/web_frame.h", "web/web_frame.h",
......
// Copyright 2020 The Chromium 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 THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_EXTERNAL_WIDGET_H_
#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_EXTERNAL_WIDGET_H_
#include "cc/layers/layer.h"
#include "third_party/blink/public/web/web_external_widget_client.h"
#include "third_party/blink/public/web/web_widget.h"
namespace blink {
// This is a type of Widget which is partially implemented outside of blink,
// such as fullscreen pepper widgets. This interface provides methods for the
// external implementation to access common Widget behaviour implemented inside
// blink, in addition to the WebWidget methods. The blink Widget uses
// WebExternalWidgetClient to communicate back to the external implementation.
class WebExternalWidget : public WebWidget {
public:
// Create a new concrete instance of this class.
// |client| should be non-null.
// |debug_url| provides the return value for WebWidget::GetURLForDebugTrace.
BLINK_EXPORT static std::unique_ptr<WebExternalWidget> Create(
WebExternalWidgetClient* client,
const WebURL& debug_url);
virtual ~WebExternalWidget() = default;
// Provides an externally-created Layer to display as the widget's content, or
// a null pointer to remove any existing Layer which will cause the widget to
// display nothing.
virtual void SetRootLayer(scoped_refptr<cc::Layer>) = 0;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_EXTERNAL_WIDGET_H_
// Copyright 2020 The Chromium 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 THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_EXTERNAL_WIDGET_CLIENT_H_
#define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_EXTERNAL_WIDGET_CLIENT_H_
#include "third_party/blink/public/platform/web_input_event_result.h"
#include "ui/gfx/geometry/size.h"
namespace blink {
class WebCoalescedInputEvent;
// The interface from blink to Widgets with implementations outside of blink.
class WebExternalWidgetClient {
public:
virtual ~WebExternalWidgetClient() = default;
// Called when the associated WebExternalWidget receives input and
// needs the implementation to handle it.
virtual WebInputEventResult HandleInputEvent(
const WebCoalescedInputEvent&) = 0;
// Called when the associated WebExternalWidget wishes to dispatch
// any pending buffered touch events. The implementation may choose to buffer
// individual pointer events (received via HandleInputEvent) and dispatch
// a single touch event indicating the changes since the last touch event.
// This method is typically invoked once per frame whereas HandleInputEvent
// may be invoked many times per frame (i.e. multiple fingers on the touch
// surface).
virtual WebInputEventResult DispatchBufferedTouchEvents() = 0;
// Called when the associated WebExternalWidget has adjusted its size.
virtual void DidResize(const gfx::Size& size) = 0;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_EXTERNAL_WIDGET_CLIENT_H_
...@@ -206,9 +206,6 @@ class WebWidget { ...@@ -206,9 +206,6 @@ class WebWidget {
return false; return false;
} }
// Returns true if the WebWidget created is of type PepperWidget.
virtual bool IsPepperWidget() const { return false; }
// Calling WebWidgetClient::requestPointerLock() will result in one // Calling WebWidgetClient::requestPointerLock() will result in one
// return call to didAcquirePointerLock() or didNotAcquirePointerLock(). // return call to didAcquirePointerLock() or didNotAcquirePointerLock().
virtual void DidAcquirePointerLock() {} virtual void DidAcquirePointerLock() {}
......
...@@ -53,6 +53,7 @@ include_rules = [ ...@@ -53,6 +53,7 @@ include_rules = [
"+cc/paint/paint_flags.h", "+cc/paint/paint_flags.h",
"+cc/paint/paint_worklet_input.h", "+cc/paint/paint_worklet_input.h",
"+cc/trees/browser_controls_params.h", "+cc/trees/browser_controls_params.h",
"+cc/trees/layer_tree_host.h",
"+cc/trees/paint_holding_commit_trigger.h", "+cc/trees/paint_holding_commit_trigger.h",
"+cc/trees/layer_tree_host.h", "+cc/trees/layer_tree_host.h",
"+components/performance_manager/public/mojom/coordination_unit.mojom-blink.h", "+components/performance_manager/public/mojom/coordination_unit.mojom-blink.h",
......
...@@ -24,6 +24,8 @@ blink_core_sources("exported") { ...@@ -24,6 +24,8 @@ blink_core_sources("exported") {
"web_dom_message_event.cc", "web_dom_message_event.cc",
"web_element.cc", "web_element.cc",
"web_element_collection.cc", "web_element_collection.cc",
"web_external_widget_impl.cc",
"web_external_widget_impl.h",
"web_form_control_element.cc", "web_form_control_element.cc",
"web_form_element.cc", "web_form_element.cc",
"web_form_element_observer_impl.cc", "web_form_element_observer_impl.cc",
......
// Copyright 2020 The Chromium 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 "third_party/blink/renderer/core/exported/web_external_widget_impl.h"
#include "cc/trees/layer_tree_host.h"
namespace blink {
std::unique_ptr<WebExternalWidget> WebExternalWidget::Create(
WebExternalWidgetClient* client,
const blink::WebURL& debug_url) {
return std::make_unique<WebExternalWidgetImpl>(client, debug_url);
}
WebExternalWidgetImpl::WebExternalWidgetImpl(WebExternalWidgetClient* client,
const WebURL& debug_url)
: client_(client), debug_url_(debug_url) {
DCHECK(client_);
}
WebExternalWidgetImpl::~WebExternalWidgetImpl() = default;
void WebExternalWidgetImpl::SetCompositorHosts(
cc::LayerTreeHost* layer_tree_host,
cc::AnimationHost* animation_host) {
widget_base_.SetCompositorHosts(layer_tree_host, animation_host);
}
WebHitTestResult WebExternalWidgetImpl::HitTestResultAt(const gfx::Point&) {
NOTIMPLEMENTED();
return {};
}
WebURL WebExternalWidgetImpl::GetURLForDebugTrace() {
return debug_url_;
}
WebSize WebExternalWidgetImpl::Size() {
return size_;
}
void WebExternalWidgetImpl::Resize(const WebSize& size) {
if (size_ == size)
return;
size_ = size;
client_->DidResize(gfx::Size(size));
}
WebInputEventResult WebExternalWidgetImpl::HandleInputEvent(
const WebCoalescedInputEvent& coalesced_event) {
return client_->HandleInputEvent(coalesced_event);
}
WebInputEventResult WebExternalWidgetImpl::DispatchBufferedTouchEvents() {
return client_->DispatchBufferedTouchEvents();
}
void WebExternalWidgetImpl::SetRootLayer(scoped_refptr<cc::Layer> layer) {
widget_base_.LayerTreeHost()->SetNonBlinkManagedRootLayer(layer);
}
} // namespace blink
// Copyright 2020 The Chromium 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 THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_EXTERNAL_WIDGET_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_EXTERNAL_WIDGET_IMPL_H_
#include "third_party/blink/public/web/web_external_widget.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/renderer/platform/widget/widget_base.h"
namespace blink {
class WebExternalWidgetImpl : public WebExternalWidget {
public:
WebExternalWidgetImpl(WebExternalWidgetClient* client,
const WebURL& debug_url);
~WebExternalWidgetImpl() override;
// WebWidget overrides:
void SetCompositorHosts(cc::LayerTreeHost*, cc::AnimationHost*) override;
WebHitTestResult HitTestResultAt(const gfx::Point&) override;
WebURL GetURLForDebugTrace() override;
WebSize Size() override;
void Resize(const WebSize& size) override;
WebInputEventResult HandleInputEvent(
const WebCoalescedInputEvent& coalesced_event) override;
WebInputEventResult DispatchBufferedTouchEvents() override;
// WebExternalWidget overrides:
void SetRootLayer(scoped_refptr<cc::Layer>) override;
private:
WebExternalWidgetClient* const client_;
const WebURL debug_url_;
WebSize size_;
WidgetBase widget_base_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_EXTERNAL_WIDGET_IMPL_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment