IndexedDBFactory now ForceCloses databases.
[chromium-blink-merge.git] / content / browser / renderer_host / input / touch_input_browsertest.cc
blob859e1a4af45b74ac7a92a0b992b70d9c1ec6b79f
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 "base/auto_reset.h"
6 #include "base/command_line.h"
7 #include "base/run_loop.h"
8 #include "content/browser/renderer_host/render_widget_host_impl.h"
9 #include "content/browser/web_contents/web_contents_impl.h"
10 #include "content/common/input/synthetic_web_input_event_builders.h"
11 #include "content/common/input_messages.h"
12 #include "content/public/browser/browser_message_filter.h"
13 #include "content/public/browser/render_view_host.h"
14 #include "content/public/browser/render_widget_host_view.h"
15 #include "content/public/common/content_switches.h"
16 #include "content/shell/browser/shell.h"
17 #include "content/test/content_browser_test.h"
18 #include "content/test/content_browser_test_utils.h"
19 #include "third_party/WebKit/public/web/WebInputEvent.h"
20 #include "ui/events/event_switches.h"
21 #include "ui/events/latency_info.h"
23 using blink::WebInputEvent;
25 namespace {
27 void GiveItSomeTime() {
28 base::RunLoop run_loop;
29 base::MessageLoop::current()->PostDelayedTask(
30 FROM_HERE,
31 run_loop.QuitClosure(),
32 base::TimeDelta::FromMilliseconds(10));
33 run_loop.Run();
36 const char kTouchEventDataURL[] =
37 "data:text/html;charset=utf-8,"
38 "<body onload='setup();'>"
39 "<div id='first'></div><div id='second'></div><div id='third'></div>"
40 "<style>"
41 " #first {"
42 " position: absolute;"
43 " width: 100px;"
44 " height: 100px;"
45 " top: 0px;"
46 " left: 0px;"
47 " background-color: green;"
48 " -webkit-transform: translate3d(0, 0, 0);"
49 " }"
50 " #second {"
51 " position: absolute;"
52 " width: 100px;"
53 " height: 100px;"
54 " top: 0px;"
55 " left: 110px;"
56 " background-color: blue;"
57 " -webkit-transform: translate3d(0, 0, 0);"
58 " }"
59 " #third {"
60 " position: absolute;"
61 " width: 100px;"
62 " height: 100px;"
63 " top: 110px;"
64 " left: 0px;"
65 " background-color: yellow;"
66 " -webkit-transform: translate3d(0, 0, 0);"
67 " }"
68 "</style>"
69 "<script>"
70 " function setup() {"
71 " second.ontouchstart = function() {};"
72 " third.ontouchstart = function(e) {"
73 " e.preventDefault();"
74 " };"
75 " }"
76 "</script>";
78 } // namespace
80 namespace content {
82 class InputEventMessageFilter : public BrowserMessageFilter {
83 public:
84 InputEventMessageFilter()
85 : type_(WebInputEvent::Undefined),
86 state_(INPUT_EVENT_ACK_STATE_UNKNOWN) {}
88 void WaitForAck(WebInputEvent::Type type) {
89 base::RunLoop run_loop;
90 base::AutoReset<base::Closure> reset_quit(&quit_, run_loop.QuitClosure());
91 base::AutoReset<WebInputEvent::Type> reset_type(&type_, type);
92 run_loop.Run();
95 InputEventAckState last_ack_state() const { return state_; }
97 protected:
98 virtual ~InputEventMessageFilter() {}
100 private:
101 void ReceivedEventAck(WebInputEvent::Type type, InputEventAckState state) {
102 if (type_ == type) {
103 state_ = state;
104 quit_.Run();
108 // BrowserMessageFilter:
109 virtual bool OnMessageReceived(const IPC::Message& message,
110 bool* message_was_ok) OVERRIDE {
111 if (message.type() == InputHostMsg_HandleInputEvent_ACK::ID) {
112 ui::LatencyInfo latency;
113 WebInputEvent::Type type = WebInputEvent::Undefined;
114 InputEventAckState ack = INPUT_EVENT_ACK_STATE_UNKNOWN;
115 InputHostMsg_HandleInputEvent_ACK::Read(&message, &type, &ack, &latency);
116 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
117 base::Bind(&InputEventMessageFilter::ReceivedEventAck,
118 this, type, ack));
120 return false;
123 base::Closure quit_;
124 WebInputEvent::Type type_;
125 InputEventAckState state_;
127 DISALLOW_COPY_AND_ASSIGN(InputEventMessageFilter);
130 class TouchInputBrowserTest : public ContentBrowserTest,
131 public testing::WithParamInterface<std::string> {
132 public:
133 TouchInputBrowserTest() {}
134 virtual ~TouchInputBrowserTest() {}
136 RenderWidgetHostImpl* GetWidgetHost() {
137 return RenderWidgetHostImpl::From(shell()->web_contents()->
138 GetRenderViewHost());
141 InputEventMessageFilter* filter() { return filter_.get(); }
143 protected:
144 void LoadURLAndAddFilter() {
145 const GURL data_url(kTouchEventDataURL);
146 NavigateToURL(shell(), data_url);
148 WebContentsImpl* web_contents =
149 static_cast<WebContentsImpl*>(shell()->web_contents());
150 RenderWidgetHostImpl* host =
151 RenderWidgetHostImpl::From(web_contents->GetRenderViewHost());
152 host->GetView()->SetSize(gfx::Size(400, 400));
154 // The page is loaded in the renderer, wait for a new frame to arrive.
155 while (!host->ScheduleComposite())
156 GiveItSomeTime();
158 filter_ = new InputEventMessageFilter();
159 host->GetProcess()->AddFilter(filter_);
162 // ContentBrowserTest:
163 virtual void SetUp() OVERRIDE {
164 // We expect real pixel output for these tests.
165 UseRealGLContexts();
167 // On legacy windows, these tests need real GL bindings to pass.
168 #if defined(OS_WIN) && !defined(USE_AURA)
169 UseRealGLBindings();
170 #endif
172 ContentBrowserTest::SetUp();
175 virtual void SetUpCommandLine(CommandLine* cmd) OVERRIDE {
176 cmd->AppendSwitchASCII(switches::kTouchEvents,
177 switches::kTouchEventsEnabled);
178 cmd->AppendSwitch(GetParam());
181 scoped_refptr<InputEventMessageFilter> filter_;
184 // Touch input event tests don't work on Mac with the legacy software renderer.
185 // These can be enabled when software compositing is enabled.
186 // http://crbug.com/268038
187 #if defined(OS_MACOSX)
188 #define MAYBE_TouchNoHandler DISABLED_TouchNoHandler
189 #else
190 #define MAYBE_TouchNoHandler TouchNoHandler
191 #endif
192 IN_PROC_BROWSER_TEST_P(TouchInputBrowserTest, MAYBE_TouchNoHandler) {
193 LoadURLAndAddFilter();
194 SyntheticWebTouchEvent touch;
196 // A press on |first| should be acked with NO_CONSUMER_EXISTS since there is
197 // no touch-handler on it.
198 touch.PressPoint(25, 25);
199 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
200 filter()->WaitForAck(WebInputEvent::TouchStart);
202 if (GetParam() == std::string(switches::kEnableThreadedCompositing)) {
203 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS,
204 filter()->last_ack_state());
205 } else {
206 // http://crbug.com/326232: This should be NO_CONSUMER_EXISTS once
207 // WebViewImpl::hasTouchEventHandlersAt() is implemented.
208 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, filter()->last_ack_state());
211 // If a touch-press is acked with NO_CONSUMER_EXISTS, then subsequent
212 // touch-points don't need to be dispatched until the touch point is released.
213 touch.ReleasePoint(0);
214 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
215 touch.ResetPoints();
218 // Touch input event tests don't work on Mac with the legacy software renderer.
219 // These can be enabled when software compositing is enabled.
220 // http://crbug.com/268038
221 #if defined(OS_MACOSX)
222 #define MAYBE_TouchHandlerNoConsume DISABLED_TouchHandlerNoConsume
223 #else
224 #define MAYBE_TouchHandlerNoConsume TouchHandlerNoConsume
225 #endif
226 IN_PROC_BROWSER_TEST_P(TouchInputBrowserTest, MAYBE_TouchHandlerNoConsume) {
227 LoadURLAndAddFilter();
228 SyntheticWebTouchEvent touch;
230 // Press on |second| should be acked with NOT_CONSUMED since there is a
231 // touch-handler on |second|, but it doesn't consume the event.
232 touch.PressPoint(125, 25);
233 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
234 filter()->WaitForAck(WebInputEvent::TouchStart);
235 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, filter()->last_ack_state());
237 touch.ReleasePoint(0);
238 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
239 filter()->WaitForAck(WebInputEvent::TouchEnd);
240 touch.ResetPoints();
243 // Touch input event tests don't work on Mac with the legacy software renderer.
244 // These can be enabled when software compositing is enabled.
245 // http://crbug.com/268038
246 #if defined(OS_MACOSX)
247 #define MAYBE_TouchHandlerConsume DISABLED_TouchHandlerConsume
248 #else
249 #define MAYBE_TouchHandlerConsume TouchHandlerConsume
250 #endif
251 IN_PROC_BROWSER_TEST_P(TouchInputBrowserTest, MAYBE_TouchHandlerConsume) {
252 LoadURLAndAddFilter();
253 SyntheticWebTouchEvent touch;
255 // Press on |third| should be acked with CONSUMED since the touch-handler on
256 // |third| consimes the event.
257 touch.PressPoint(25, 125);
258 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
259 filter()->WaitForAck(WebInputEvent::TouchStart);
260 EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, filter()->last_ack_state());
262 touch.ReleasePoint(0);
263 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
264 filter()->WaitForAck(WebInputEvent::TouchEnd);
267 // Touch input event tests don't work on Mac with the legacy software renderer.
268 // These can be enabled when software compositing is enabled.
269 // http://crbug.com/268038
270 #if defined(OS_MACOSX)
271 #define MAYBE_MultiPointTouchPress DISABLED_MultiPointTouchPress
272 #else
273 #define MAYBE_MultiPointTouchPress MultiPointTouchPress
274 #endif
275 IN_PROC_BROWSER_TEST_P(TouchInputBrowserTest, MAYBE_MultiPointTouchPress) {
276 LoadURLAndAddFilter();
277 SyntheticWebTouchEvent touch;
279 // Press on |first|, which sould be acked with NO_CONSUMER_EXISTS. Then press
280 // on |third|. That point should be acked with CONSUMED.
281 touch.PressPoint(25, 25);
282 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
283 filter()->WaitForAck(WebInputEvent::TouchStart);
284 if (GetParam() == std::string(switches::kEnableThreadedCompositing)) {
285 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS,
286 filter()->last_ack_state());
287 } else {
288 // http://crbug.com/326232: This should be NO_CONSUMER_EXISTS once
289 // WebViewImpl::hasTouchEventHandlersAt() is implemented.
290 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, filter()->last_ack_state());
293 touch.PressPoint(25, 125);
294 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
295 filter()->WaitForAck(WebInputEvent::TouchStart);
296 EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, filter()->last_ack_state());
299 INSTANTIATE_TEST_CASE_P(WithoutInputHandlerProxy, TouchInputBrowserTest,
300 ::testing::Values(std::string(switches::kDisableThreadedCompositing)));
302 #if !defined(OS_MACOSX)
303 INSTANTIATE_TEST_CASE_P(WithInputHandlerProxy, TouchInputBrowserTest,
304 ::testing::Values(std::string(switches::kEnableThreadedCompositing)));
305 #endif
307 } // namespace content