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(
scoped_refptr<Layer> root_layer) {
SetRootLayer(std::move(root_layer));
DCHECK(root_layer_->children().empty());
DCHECK(!root_layer || root_layer_->children().empty());
if (IsUsingLayerLists() && root_layer_)
force_use_property_tree_builder_ = true;
}
......
......@@ -445,7 +445,7 @@ void RenderWidgetInputHandler::HandleInputEvent(
suppress_next_char_events_ = false;
if (processed == WebInputEventResult::kNotHandled &&
widget_->GetWebWidget()) {
if (!widget_->GetWebWidget()->IsPepperWidget() &&
if (delegate_->SupportsBufferedTouchEvents() &&
WebInputEvent::IsTouchEventType(input_event.GetType()))
processed = HandleTouchEvent(coalesced_event);
else
......
......@@ -70,8 +70,11 @@ class CONTENT_EXPORT RenderWidgetInputHandlerDelegate {
// won't be sent to WebKit or trigger DidHandleMouseEvent().
virtual bool WillHandleMouseEvent(const blink::WebMouseEvent& event) = 0;
// Whether buffered touch events should be supported or not.
virtual bool SupportsBufferedTouchEvents() = 0;
protected:
virtual ~RenderWidgetInputHandlerDelegate() {}
virtual ~RenderWidgetInputHandlerDelegate() = default;
};
} // namespace content
......
......@@ -1543,6 +1543,11 @@ bool RenderWidget::WillHandleMouseEvent(const blink::WebMouseEvent& event) {
return mouse_lock_dispatcher()->WillHandleMouseEvent(event);
}
bool RenderWidget::SupportsBufferedTouchEvents() {
// Buffered touch events aren't supported for pepper.
return !pepper_fullscreen_;
}
void RenderWidget::ResizeWebWidget() {
// In auto resize mode, blink controls sizes and RenderWidget should not be
// passing values back in.
......
......@@ -351,6 +351,7 @@ class CONTENT_EXPORT RenderWidget
void ClearTextInputState() override;
bool WillHandleGestureEvent(const blink::WebGestureEvent& event) override;
bool WillHandleMouseEvent(const blink::WebMouseEvent& event) override;
bool SupportsBufferedTouchEvents() override;
// RenderWidgetScreenMetricsEmulatorDelegate
void SetScreenMetricsEmulationParameters(
......
......@@ -14,7 +14,8 @@
#include "content/renderer/pepper/fullscreen_container.h"
#include "content/renderer/render_widget.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"
namespace cc {
......@@ -24,6 +25,7 @@ class Layer;
namespace content {
class CompositorDependencies;
class PepperPluginInstanceImpl;
class PepperExternalWidgetClient;
// A RenderWidget that hosts a fullscreen pepper plugin. This provides a
// FullscreenContainer that the plugin instance can callback into to e.g.
......@@ -62,7 +64,8 @@ class RenderWidgetFullscreenPepper : public RenderWidget,
int32_t routing_id,
CompositorDependencies* compositor_deps,
PepperPluginInstanceImpl* plugin,
mojo::PendingReceiver<mojom::Widget> widget_receiver);
mojo::PendingReceiver<mojom::Widget> widget_receiver,
blink::WebURL main_frame_url);
~RenderWidgetFullscreenPepper() override;
// RenderWidget API.
......@@ -71,7 +74,12 @@ class RenderWidgetFullscreenPepper : public RenderWidget,
void AfterUpdateVisualProperties() override;
private:
friend class PepperExternalWidgetClient;
void UpdateLayerBounds();
void DidResize(const gfx::Size& size);
blink::WebInputEventResult ProcessInputEvent(
const blink::WebCoalescedInputEvent& event);
// The plugin instance this widget wraps.
PepperPluginInstanceImpl* plugin_;
......@@ -79,6 +87,8 @@ class RenderWidgetFullscreenPepper : public RenderWidget,
cc::Layer* layer_ = nullptr;
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);
};
......
......@@ -41,7 +41,8 @@
#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/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/events/base_event_utils.h"
#include "ui/events/blink/web_input_event_traits.h"
......@@ -150,15 +151,12 @@ class MockHandledEventCallback {
DISALLOW_COPY_AND_ASSIGN(MockHandledEventCallback);
};
class MockWebWidget : public blink::WebWidget {
class MockWebExternalWidgetClient : public blink::WebExternalWidgetClient {
public:
// WebWidget implementation.
void SetCompositorHosts(cc::LayerTreeHost*, cc::AnimationHost*) override {}
blink::WebURL GetURLForDebugTrace() override { return {}; }
blink::WebHitTestResult HitTestResultAt(const gfx::Point&) override {
return {};
}
MockWebExternalWidgetClient() = default;
// WebExternalWidgetClient implementation.
MOCK_METHOD1(DidResize, void(const gfx::Size& size));
MOCK_METHOD0(DispatchBufferedTouchEvents, blink::WebInputEventResult());
MOCK_METHOD1(
HandleInputEvent,
......@@ -177,8 +175,10 @@ class InteractiveRenderWidget : public RenderWidget {
/*is_hidden=*/false,
/*never_composited=*/false,
mojo::NullReceiver()),
always_overscroll_(false) {
Initialize(base::NullCallback(), &mock_webwidget_, screen_info);
external_web_widget_(
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>();
......@@ -203,12 +203,18 @@ class InteractiveRenderWidget : public RenderWidget {
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() {
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 {
return local_surface_id_allocation_from_parent_;
......@@ -240,8 +246,9 @@ class InteractiveRenderWidget : public RenderWidget {
private:
IPC::TestSink sink_;
bool always_overscroll_;
MockWebWidget mock_webwidget_;
bool always_overscroll_ = false;
MockWebExternalWidgetClient mock_web_external_widget_client_;
std::unique_ptr<blink::WebExternalWidget> external_web_widget_;
std::unique_ptr<MockWidgetInputHandlerHost> mock_input_handler_host_;
static int next_routing_id_;
......@@ -298,7 +305,7 @@ TEST_F(RenderWidgetUnittest, CursorChange) {
widget()->DidChangeCursor(cursor_info);
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));
widget()->SendInputEvent(SyntheticWebMouseEventBuilder::Build(
blink::WebInputEvent::Type::kMouseLeave),
......@@ -314,7 +321,7 @@ TEST_F(RenderWidgetUnittest, CursorChange) {
TEST_F(RenderWidgetUnittest, EventOverscroll) {
widget()->set_always_overscroll(true);
EXPECT_CALL(*widget()->mock_webwidget(), HandleInputEvent(_))
EXPECT_CALL(*widget()->mock_web_external_widget_client(), HandleInputEvent(_))
.WillRepeatedly(
::testing::Return(blink::WebInputEventResult::kNotHandled));
......@@ -345,12 +352,13 @@ TEST_F(RenderWidgetUnittest, RenderWidgetInputEventUmaMetrics) {
touch.PressPoint(10, 10);
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)
.WillRepeatedly(
::testing::Return(blink::WebInputEventResult::kNotHandled));
EXPECT_CALL(*widget()->mock_webwidget(), DispatchBufferedTouchEvents())
EXPECT_CALL(*widget()->mock_web_external_widget_client(),
DispatchBufferedTouchEvents())
.Times(5)
.WillRepeatedly(
::testing::Return(blink::WebInputEventResult::kNotHandled));
......@@ -387,9 +395,10 @@ TEST_F(RenderWidgetUnittest, RenderWidgetInputEventUmaMetrics) {
EVENT_LISTENER_RESULT_HISTOGRAM,
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));
EXPECT_CALL(*widget()->mock_webwidget(), DispatchBufferedTouchEvents())
EXPECT_CALL(*widget()->mock_web_external_widget_client(),
DispatchBufferedTouchEvents())
.WillOnce(
::testing::Return(blink::WebInputEventResult::kHandledSuppressed));
touch.dispatch_type = blink::WebInputEvent::DispatchType::kBlocking;
......@@ -397,9 +406,10 @@ TEST_F(RenderWidgetUnittest, RenderWidgetInputEventUmaMetrics) {
histogram_tester().ExpectBucketCount(EVENT_LISTENER_RESULT_HISTOGRAM,
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));
EXPECT_CALL(*widget()->mock_webwidget(), DispatchBufferedTouchEvents())
EXPECT_CALL(*widget()->mock_web_external_widget_client(),
DispatchBufferedTouchEvents())
.WillOnce(
::testing::Return(blink::WebInputEventResult::kHandledApplication));
touch.dispatch_type = blink::WebInputEvent::DispatchType::kBlocking;
......
......@@ -321,6 +321,8 @@ source_set("blink_headers") {
"web/web_embedded_worker_start_data.h",
"web/web_external_popup_menu.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_element.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 {
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
// return call to didAcquirePointerLock() or didNotAcquirePointerLock().
virtual void DidAcquirePointerLock() {}
......
......@@ -53,6 +53,7 @@ include_rules = [
"+cc/paint/paint_flags.h",
"+cc/paint/paint_worklet_input.h",
"+cc/trees/browser_controls_params.h",
"+cc/trees/layer_tree_host.h",
"+cc/trees/paint_holding_commit_trigger.h",
"+cc/trees/layer_tree_host.h",
"+components/performance_manager/public/mojom/coordination_unit.mojom-blink.h",
......
......@@ -24,6 +24,8 @@ blink_core_sources("exported") {
"web_dom_message_event.cc",
"web_element.cc",
"web_element_collection.cc",
"web_external_widget_impl.cc",
"web_external_widget_impl.h",
"web_form_control_element.cc",
"web_form_element.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