• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "content/renderer/render_widget.h"
6 
7 #include <vector>
8 
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/mock_render_process.h"
13 #include "ipc/ipc_test_sink.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "third_party/WebKit/public/web/WebInputEvent.h"
16 #include "ui/gfx/rect.h"
17 
18 namespace content {
19 
20 class RenderWidgetUnittest : public testing::Test {
21  public:
RenderWidgetUnittest()22   RenderWidgetUnittest() {}
~RenderWidgetUnittest()23   virtual ~RenderWidgetUnittest() {}
24 
25  private:
26   MockRenderProcess render_process_;
27   MockRenderThread render_thread_;
28 
29   DISALLOW_COPY_AND_ASSIGN(RenderWidgetUnittest);
30 };
31 
32 class TouchableRenderWidget : public RenderWidget {
33  public:
TouchableRenderWidget()34   TouchableRenderWidget() : RenderWidget(blink::WebPopupTypeNone,
35                                          blink::WebScreenInfo(),
36                                          false,
37                                          false) {}
38 
SetTouchRegion(const std::vector<gfx::Rect> & rects)39   void SetTouchRegion(const std::vector<gfx::Rect>& rects) {
40     rects_ = rects;
41   }
42 
SendInputEvent(const blink::WebInputEvent & event)43   void SendInputEvent(const blink::WebInputEvent& event) {
44     OnHandleInputEvent(&event, ui::LatencyInfo(), false);
45   }
46 
sink()47   IPC::TestSink* sink() { return &sink_; }
48 
49  protected:
~TouchableRenderWidget()50   virtual ~TouchableRenderWidget() {}
51 
52   // Overridden from RenderWidget:
HasTouchEventHandlersAt(const gfx::Point & point) const53   virtual bool HasTouchEventHandlersAt(const gfx::Point& point) const OVERRIDE {
54     for (std::vector<gfx::Rect>::const_iterator iter = rects_.begin();
55          iter != rects_.end(); ++iter) {
56       if ((*iter).Contains(point))
57         return true;
58     }
59     return false;
60   }
61 
Send(IPC::Message * msg)62   virtual bool Send(IPC::Message* msg) OVERRIDE {
63     sink_.OnMessageReceived(*msg);
64     delete msg;
65     return true;
66   }
67 
68  private:
69   std::vector<gfx::Rect> rects_;
70   IPC::TestSink sink_;
71 
72   DISALLOW_COPY_AND_ASSIGN(TouchableRenderWidget);
73 };
74 
TEST_F(RenderWidgetUnittest,TouchHitTestSinglePoint)75 TEST_F(RenderWidgetUnittest, TouchHitTestSinglePoint) {
76   scoped_refptr<TouchableRenderWidget> widget = new TouchableRenderWidget();
77 
78   blink::WebInputEvent::Type type;
79   InputEventAckState ack_state;
80   ui::LatencyInfo latency;
81 
82   SyntheticWebTouchEvent touch;
83   touch.PressPoint(10, 10);
84 
85   widget->SendInputEvent(touch);
86   ASSERT_EQ(1u, widget->sink()->message_count());
87 
88   // Since there's currently no touch-event handling region, the response should
89   // be 'no consumer exists'.
90   const IPC::Message* message = widget->sink()->GetMessageAt(0);
91   EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
92   InputHostMsg_HandleInputEvent_ACK::Read(message, &type, &ack_state, &latency);
93   EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, ack_state);
94   widget->sink()->ClearMessages();
95 
96   std::vector<gfx::Rect> rects;
97   rects.push_back(gfx::Rect(0, 0, 20, 20));
98   rects.push_back(gfx::Rect(25, 0, 10, 10));
99   widget->SetTouchRegion(rects);
100 
101   widget->SendInputEvent(touch);
102   ASSERT_EQ(1u, widget->sink()->message_count());
103   message = widget->sink()->GetMessageAt(0);
104   EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
105   InputHostMsg_HandleInputEvent_ACK::Read(message, &type, &ack_state, &latency);
106   EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, ack_state);
107   widget->sink()->ClearMessages();
108 }
109 
TEST_F(RenderWidgetUnittest,TouchHitTestMultiplePoints)110 TEST_F(RenderWidgetUnittest, TouchHitTestMultiplePoints) {
111   scoped_refptr<TouchableRenderWidget> widget = new TouchableRenderWidget();
112   std::vector<gfx::Rect> rects;
113   rects.push_back(gfx::Rect(0, 0, 20, 20));
114   rects.push_back(gfx::Rect(25, 0, 10, 10));
115   widget->SetTouchRegion(rects);
116 
117   blink::WebInputEvent::Type type;
118   InputEventAckState ack_state;
119   ui::LatencyInfo latency;
120 
121   SyntheticWebTouchEvent touch;
122   touch.PressPoint(25, 25);
123 
124   widget->SendInputEvent(touch);
125   ASSERT_EQ(1u, widget->sink()->message_count());
126 
127   // Since there's currently no touch-event handling region, the response should
128   // be 'no consumer exists'.
129   const IPC::Message* message = widget->sink()->GetMessageAt(0);
130   EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
131   InputHostMsg_HandleInputEvent_ACK::Read(message, &type, &ack_state, &latency);
132   EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, ack_state);
133   widget->sink()->ClearMessages();
134 
135   // Press a second touch point. This time, on a touch-handling region.
136   touch.PressPoint(10, 10);
137   widget->SendInputEvent(touch);
138   ASSERT_EQ(1u, widget->sink()->message_count());
139   message = widget->sink()->GetMessageAt(0);
140   EXPECT_EQ(InputHostMsg_HandleInputEvent_ACK::ID, message->type());
141   InputHostMsg_HandleInputEvent_ACK::Read(message, &type, &ack_state, &latency);
142   EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, ack_state);
143   widget->sink()->ClearMessages();
144 }
145 
146 }  // namespace content
147