Upstreaming browser/ui/uikit_ui_util from iOS.
[chromium-blink-merge.git] / content / renderer / render_widget_unittest.cc
blob9211acac8199e10ff50b97e7323c1d4b3d922ccd
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/renderer/render_widget.h"
7 #include <vector>
9 #include "content/common/input/synthetic_web_input_event_builders.h"
10 #include "content/common/input_messages.h"
11 #include "content/public/test/mock_render_thread.h"
12 #include "content/test/fake_compositor_dependencies.h"
13 #include "content/test/mock_render_process.h"
14 #include "ipc/ipc_test_sink.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/WebKit/public/web/WebInputEvent.h"
17 #include "ui/gfx/geometry/rect.h"
19 namespace content {
21 class InteractiveRenderWidget : public RenderWidget {
22 public:
23 explicit InteractiveRenderWidget(CompositorDependencies* compositor_deps)
24 : RenderWidget(compositor_deps,
25 blink::WebPopupTypeNone,
26 blink::WebScreenInfo(),
27 false,
28 false,
29 false),
30 always_overscroll_(false) {}
32 void SetTouchRegion(const std::vector<gfx::Rect>& rects) {
33 rects_ = rects;
36 void SendInputEvent(const blink::WebInputEvent& event) {
37 OnHandleInputEvent(&event, ui::LatencyInfo(), false);
40 void set_always_overscroll(bool overscroll) {
41 always_overscroll_ = overscroll;
44 IPC::TestSink* sink() { return &sink_; }
46 protected:
47 ~InteractiveRenderWidget() override {}
49 // Overridden from RenderWidget:
50 bool HasTouchEventHandlersAt(const gfx::Point& point) const override {
51 for (std::vector<gfx::Rect>::const_iterator iter = rects_.begin();
52 iter != rects_.end(); ++iter) {
53 if ((*iter).Contains(point))
54 return true;
56 return false;
59 bool WillHandleGestureEvent(const blink::WebGestureEvent& event) override {
60 if (always_overscroll_ &&
61 event.type == blink::WebInputEvent::GestureScrollUpdate) {
62 didOverscroll(blink::WebFloatSize(event.data.scrollUpdate.deltaX,
63 event.data.scrollUpdate.deltaY),
64 blink::WebFloatSize(event.data.scrollUpdate.deltaX,
65 event.data.scrollUpdate.deltaY),
66 blink::WebFloatPoint(event.x, event.y),
67 blink::WebFloatSize(event.data.scrollUpdate.velocityX,
68 event.data.scrollUpdate.velocityY));
69 return true;
72 return false;
75 bool Send(IPC::Message* msg) override {
76 sink_.OnMessageReceived(*msg);
77 delete msg;
78 return true;
81 private:
82 std::vector<gfx::Rect> rects_;
83 IPC::TestSink sink_;
84 bool always_overscroll_;
86 DISALLOW_COPY_AND_ASSIGN(InteractiveRenderWidget);
89 class RenderWidgetUnittest : public testing::Test {
90 public:
91 RenderWidgetUnittest()
92 : widget_(new InteractiveRenderWidget(&compositor_deps_)) {}
93 ~RenderWidgetUnittest() override {}
95 InteractiveRenderWidget* widget() const { return widget_.get(); }
97 private:
98 MockRenderProcess render_process_;
99 MockRenderThread render_thread_;
100 FakeCompositorDependencies compositor_deps_;
101 scoped_refptr<InteractiveRenderWidget> widget_;
103 DISALLOW_COPY_AND_ASSIGN(RenderWidgetUnittest);
106 TEST_F(RenderWidgetUnittest, TouchHitTestSinglePoint) {
107 SyntheticWebTouchEvent touch;
108 touch.PressPoint(10, 10);
110 widget()->SendInputEvent(touch);
111 ASSERT_EQ(1u, widget()->sink()->message_count());
113 // Since there's currently no touch-event handling region, the response should
114 // be 'no consumer exists'.
115 const IPC::Message* message = widget()->sink()->GetMessageAt(0);
116 EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
117 InputHostMsg_HandleInputEvent_ACK::Param params;
118 InputHostMsg_HandleInputEvent_ACK::Read(message, &params);
119 InputEventAckState ack_state = base::get<0>(params).state;
120 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, ack_state);
121 widget()->sink()->ClearMessages();
123 std::vector<gfx::Rect> rects;
124 rects.push_back(gfx::Rect(0, 0, 20, 20));
125 rects.push_back(gfx::Rect(25, 0, 10, 10));
126 widget()->SetTouchRegion(rects);
128 widget()->SendInputEvent(touch);
129 ASSERT_EQ(1u, widget()->sink()->message_count());
130 message = widget()->sink()->GetMessageAt(0);
131 EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
132 InputHostMsg_HandleInputEvent_ACK::Read(message, &params);
133 ack_state = base::get<0>(params).state;
134 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, ack_state);
135 widget()->sink()->ClearMessages();
138 TEST_F(RenderWidgetUnittest, TouchHitTestMultiplePoints) {
139 std::vector<gfx::Rect> rects;
140 rects.push_back(gfx::Rect(0, 0, 20, 20));
141 rects.push_back(gfx::Rect(25, 0, 10, 10));
142 widget()->SetTouchRegion(rects);
144 SyntheticWebTouchEvent touch;
145 touch.PressPoint(25, 25);
147 widget()->SendInputEvent(touch);
148 ASSERT_EQ(1u, widget()->sink()->message_count());
150 // Since there's currently no touch-event handling region, the response should
151 // be 'no consumer exists'.
152 const IPC::Message* message = widget()->sink()->GetMessageAt(0);
153 EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
154 InputHostMsg_HandleInputEvent_ACK::Param params;
155 InputHostMsg_HandleInputEvent_ACK::Read(message, &params);
156 InputEventAckState ack_state = base::get<0>(params).state;
157 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, ack_state);
158 widget()->sink()->ClearMessages();
160 // Press a second touch point. This time, on a touch-handling region.
161 touch.PressPoint(10, 10);
162 widget()->SendInputEvent(touch);
163 ASSERT_EQ(1u, widget()->sink()->message_count());
164 message = widget()->sink()->GetMessageAt(0);
165 EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
166 InputHostMsg_HandleInputEvent_ACK::Read(message, &params);
167 ack_state = base::get<0>(params).state;
168 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, ack_state);
169 widget()->sink()->ClearMessages();
172 TEST_F(RenderWidgetUnittest, EventOverscroll) {
173 widget()->set_always_overscroll(true);
175 blink::WebGestureEvent scroll;
176 scroll.type = blink::WebInputEvent::GestureScrollUpdate;
177 scroll.x = -10;
178 scroll.data.scrollUpdate.deltaY = 10;
179 widget()->SendInputEvent(scroll);
181 // Overscroll notifications received while handling an input event should
182 // be bundled with the event ack IPC.
183 ASSERT_EQ(1u, widget()->sink()->message_count());
184 const IPC::Message* message = widget()->sink()->GetMessageAt(0);
185 ASSERT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
186 InputHostMsg_HandleInputEvent_ACK::Param params;
187 InputHostMsg_HandleInputEvent_ACK::Read(message, &params);
188 const InputEventAck& ack = base::get<0>(params);
189 ASSERT_EQ(ack.type, scroll.type);
190 ASSERT_TRUE(ack.overscroll);
191 EXPECT_EQ(gfx::Vector2dF(0, 10), ack.overscroll->accumulated_overscroll);
192 EXPECT_EQ(gfx::Vector2dF(0, 10), ack.overscroll->latest_overscroll_delta);
193 EXPECT_EQ(gfx::Vector2dF(), ack.overscroll->current_fling_velocity);
194 EXPECT_EQ(gfx::PointF(-10, 0), ack.overscroll->causal_event_viewport_point);
195 widget()->sink()->ClearMessages();
198 TEST_F(RenderWidgetUnittest, FlingOverscroll) {
199 // Overscroll notifications received outside of handling an input event should
200 // be sent as a separate IPC.
201 widget()->didOverscroll(blink::WebFloatSize(10, 5), blink::WebFloatSize(5, 5),
202 blink::WebFloatPoint(1, 1),
203 blink::WebFloatSize(10, 5));
204 ASSERT_EQ(1u, widget()->sink()->message_count());
205 const IPC::Message* message = widget()->sink()->GetMessageAt(0);
206 ASSERT_EQ(InputHostMsg_DidOverscroll::ID, message->type());
207 InputHostMsg_DidOverscroll::Param params;
208 InputHostMsg_DidOverscroll::Read(message, &params);
209 const DidOverscrollParams& overscroll = base::get<0>(params);
210 EXPECT_EQ(gfx::Vector2dF(10, 5), overscroll.latest_overscroll_delta);
211 EXPECT_EQ(gfx::Vector2dF(5, 5), overscroll.accumulated_overscroll);
212 EXPECT_EQ(gfx::PointF(1, 1), overscroll.causal_event_viewport_point);
213 EXPECT_EQ(gfx::Vector2dF(-10, -5), overscroll.current_fling_velocity);
214 widget()->sink()->ClearMessages();
217 } // namespace content