DevTools: cut host and port from webSocketDebuggerUrl in addition to ws:// prefix
[chromium-blink-merge.git] / content / browser / renderer_host / input / touch_input_browsertest.cc
blob9c9bcefdb44a91ed9eef474c231fe62fa39443bc
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/location.h"
8 #include "base/run_loop.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "content/browser/gpu/compositor_util.h"
12 #include "content/browser/renderer_host/render_widget_host_impl.h"
13 #include "content/browser/web_contents/web_contents_impl.h"
14 #include "content/common/input/synthetic_web_input_event_builders.h"
15 #include "content/common/input_messages.h"
16 #include "content/public/browser/browser_message_filter.h"
17 #include "content/public/browser/render_view_host.h"
18 #include "content/public/browser/render_widget_host_view.h"
19 #include "content/public/common/content_switches.h"
20 #include "content/public/test/content_browser_test.h"
21 #include "content/public/test/content_browser_test_utils.h"
22 #include "content/shell/browser/shell.h"
23 #include "third_party/WebKit/public/web/WebInputEvent.h"
24 #include "ui/events/event_switches.h"
25 #include "ui/events/latency_info.h"
27 using blink::WebInputEvent;
29 namespace {
31 void GiveItSomeTime() {
32 base::RunLoop run_loop;
33 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
34 FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromMilliseconds(10));
35 run_loop.Run();
38 const char kTouchEventDataURL[] =
39 "data:text/html;charset=utf-8,"
40 #if defined(OS_ANDROID)
41 "<head>"
42 "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"
43 "</head>"
44 #endif
45 "<body onload='setup();'>"
46 "<div id='first'></div><div id='second'></div><div id='third'></div>"
47 "<style>"
48 " #first {"
49 " position: absolute;"
50 " width: 100px;"
51 " height: 100px;"
52 " top: 0px;"
53 " left: 0px;"
54 " background-color: green;"
55 " -webkit-transform: translate3d(0, 0, 0);"
56 " }"
57 " #second {"
58 " position: absolute;"
59 " width: 100px;"
60 " height: 100px;"
61 " top: 0px;"
62 " left: 110px;"
63 " background-color: blue;"
64 " -webkit-transform: translate3d(0, 0, 0);"
65 " }"
66 " #third {"
67 " position: absolute;"
68 " width: 100px;"
69 " height: 100px;"
70 " top: 110px;"
71 " left: 0px;"
72 " background-color: yellow;"
73 " -webkit-transform: translate3d(0, 0, 0);"
74 " }"
75 "</style>"
76 "<script>"
77 " function setup() {"
78 " second.ontouchstart = function() {};"
79 " third.ontouchstart = function(e) {"
80 " e.preventDefault();"
81 " };"
82 " }"
83 "</script>";
85 } // namespace
87 namespace content {
89 class InputEventMessageFilter : public BrowserMessageFilter {
90 public:
91 InputEventMessageFilter()
92 : BrowserMessageFilter(InputMsgStart),
93 type_(WebInputEvent::Undefined),
94 state_(INPUT_EVENT_ACK_STATE_UNKNOWN) {}
96 void WaitForAck(WebInputEvent::Type type) {
97 base::RunLoop run_loop;
98 base::AutoReset<base::Closure> reset_quit(&quit_, run_loop.QuitClosure());
99 base::AutoReset<WebInputEvent::Type> reset_type(&type_, type);
100 run_loop.Run();
103 InputEventAckState last_ack_state() const { return state_; }
105 protected:
106 ~InputEventMessageFilter() override {}
108 private:
109 void ReceivedEventAck(WebInputEvent::Type type, InputEventAckState state) {
110 if (type_ == type) {
111 state_ = state;
112 quit_.Run();
116 // BrowserMessageFilter:
117 bool OnMessageReceived(const IPC::Message& message) override {
118 if (message.type() == InputHostMsg_HandleInputEvent_ACK::ID) {
119 InputHostMsg_HandleInputEvent_ACK::Param params;
120 InputHostMsg_HandleInputEvent_ACK::Read(&message, &params);
121 WebInputEvent::Type type = base::get<0>(params).type;
122 InputEventAckState ack = base::get<0>(params).state;
123 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
124 base::Bind(&InputEventMessageFilter::ReceivedEventAck,
125 this, type, ack));
127 return false;
130 base::Closure quit_;
131 WebInputEvent::Type type_;
132 InputEventAckState state_;
134 DISALLOW_COPY_AND_ASSIGN(InputEventMessageFilter);
137 class TouchInputBrowserTest : public ContentBrowserTest {
138 public:
139 TouchInputBrowserTest() {}
140 ~TouchInputBrowserTest() override {}
142 RenderWidgetHostImpl* GetWidgetHost() {
143 return RenderWidgetHostImpl::From(shell()->web_contents()->
144 GetRenderViewHost());
147 InputEventMessageFilter* filter() { return filter_.get(); }
149 protected:
150 void LoadURLAndAddFilter() {
151 const GURL data_url(kTouchEventDataURL);
152 NavigateToURL(shell(), data_url);
154 WebContentsImpl* web_contents =
155 static_cast<WebContentsImpl*>(shell()->web_contents());
156 RenderWidgetHostImpl* host =
157 RenderWidgetHostImpl::From(web_contents->GetRenderViewHost());
158 host->GetView()->SetSize(gfx::Size(400, 400));
160 // The page is loaded in the renderer, wait for a new frame to arrive.
161 while (!host->ScheduleComposite())
162 GiveItSomeTime();
164 filter_ = new InputEventMessageFilter();
165 host->GetProcess()->AddFilter(filter_.get());
168 void SetUpCommandLine(base::CommandLine* cmd) override {
169 cmd->AppendSwitchASCII(switches::kTouchEvents,
170 switches::kTouchEventsEnabled);
173 scoped_refptr<InputEventMessageFilter> filter_;
176 #if defined(OS_MACOSX)
177 // TODO(ccameron): Failing on mac: crbug.com/346363
178 #define MAYBE_TouchNoHandler DISABLED_TouchNoHandler
179 #else
180 #define MAYBE_TouchNoHandler TouchNoHandler
181 #endif
182 IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, MAYBE_TouchNoHandler) {
183 LoadURLAndAddFilter();
184 SyntheticWebTouchEvent touch;
186 // A press on |first| should be acked with NO_CONSUMER_EXISTS since there is
187 // no touch-handler on it.
188 touch.PressPoint(25, 25);
189 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
190 filter()->WaitForAck(WebInputEvent::TouchStart);
192 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS,
193 filter()->last_ack_state());
195 // If a touch-press is acked with NO_CONSUMER_EXISTS, then subsequent
196 // touch-points don't need to be dispatched until the touch point is released.
197 touch.ReleasePoint(0);
198 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
199 touch.ResetPoints();
202 IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, TouchHandlerNoConsume) {
203 LoadURLAndAddFilter();
204 SyntheticWebTouchEvent touch;
206 // Press on |second| should be acked with NOT_CONSUMED since there is a
207 // touch-handler on |second|, but it doesn't consume the event.
208 touch.PressPoint(125, 25);
209 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
210 filter()->WaitForAck(WebInputEvent::TouchStart);
211 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, filter()->last_ack_state());
213 touch.ReleasePoint(0);
214 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
215 filter()->WaitForAck(WebInputEvent::TouchEnd);
216 touch.ResetPoints();
219 IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, TouchHandlerConsume) {
220 LoadURLAndAddFilter();
221 SyntheticWebTouchEvent touch;
223 // Press on |third| should be acked with CONSUMED since the touch-handler on
224 // |third| consimes the event.
225 touch.PressPoint(25, 125);
226 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
227 filter()->WaitForAck(WebInputEvent::TouchStart);
228 EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, filter()->last_ack_state());
230 touch.ReleasePoint(0);
231 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
232 filter()->WaitForAck(WebInputEvent::TouchEnd);
235 #if defined(OS_MACOSX)
236 // TODO(ccameron): Failing on mac: crbug.com/346363
237 #define MAYBE_MultiPointTouchPress DISABLED_MultiPointTouchPress
238 #else
239 #define MAYBE_MultiPointTouchPress MultiPointTouchPress
240 #endif
241 IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, MAYBE_MultiPointTouchPress) {
242 LoadURLAndAddFilter();
243 SyntheticWebTouchEvent touch;
245 // Press on |first|, which sould be acked with NO_CONSUMER_EXISTS. Then press
246 // on |third|. That point should be acked with CONSUMED.
247 touch.PressPoint(25, 25);
248 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
249 filter()->WaitForAck(WebInputEvent::TouchStart);
250 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS,
251 filter()->last_ack_state());
253 touch.PressPoint(25, 125);
254 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo());
255 filter()->WaitForAck(WebInputEvent::TouchStart);
256 EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, filter()->last_ack_state());
259 } // namespace content