OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/auto_reset.h" | 5 #include "base/auto_reset.h" |
6 #include "base/command_line.h" | 6 #include "base/command_line.h" |
7 #include "base/location.h" | 7 #include "base/location.h" |
8 #include "base/macros.h" | 8 #include "base/macros.h" |
9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
10 #include "base/single_thread_task_runner.h" | 10 #include "base/single_thread_task_runner.h" |
11 #include "base/thread_task_runner_handle.h" | 11 #include "base/thread_task_runner_handle.h" |
12 #include "build/build_config.h" | 12 #include "build/build_config.h" |
13 #include "content/browser/gpu/compositor_util.h" | 13 #include "content/browser/gpu/compositor_util.h" |
14 #include "content/browser/renderer_host/render_widget_host_impl.h" | 14 #include "content/browser/renderer_host/render_widget_host_impl.h" |
15 #include "content/browser/web_contents/web_contents_impl.h" | 15 #include "content/browser/web_contents/web_contents_impl.h" |
16 #include "content/common/input/synthetic_web_input_event_builders.h" | 16 #include "content/common/input/synthetic_web_input_event_builders.h" |
17 #include "content/common/input_messages.h" | 17 #include "content/common/input_messages.h" |
18 #include "content/public/browser/browser_message_filter.h" | 18 #include "content/public/browser/browser_message_filter.h" |
19 #include "content/public/browser/render_view_host.h" | 19 #include "content/public/browser/render_view_host.h" |
20 #include "content/public/browser/render_widget_host_view.h" | 20 #include "content/public/browser/render_widget_host_view.h" |
21 #include "content/public/common/content_switches.h" | 21 #include "content/public/common/content_switches.h" |
| 22 #include "content/public/test/browser_test_utils.h" |
22 #include "content/public/test/content_browser_test.h" | 23 #include "content/public/test/content_browser_test.h" |
23 #include "content/public/test/content_browser_test_utils.h" | 24 #include "content/public/test/content_browser_test_utils.h" |
24 #include "content/shell/browser/shell.h" | 25 #include "content/shell/browser/shell.h" |
25 #include "third_party/WebKit/public/web/WebInputEvent.h" | 26 #include "third_party/WebKit/public/web/WebInputEvent.h" |
26 #include "ui/events/event_switches.h" | 27 #include "ui/events/event_switches.h" |
27 #include "ui/events/latency_info.h" | 28 #include "ui/events/latency_info.h" |
28 | 29 |
29 using blink::WebInputEvent; | 30 using blink::WebInputEvent; |
30 | 31 |
31 namespace { | 32 namespace { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 " third.ontouchstart = function(e) {" | 82 " third.ontouchstart = function(e) {" |
82 " e.preventDefault();" | 83 " e.preventDefault();" |
83 " };" | 84 " };" |
84 " }" | 85 " }" |
85 "</script>"; | 86 "</script>"; |
86 | 87 |
87 } // namespace | 88 } // namespace |
88 | 89 |
89 namespace content { | 90 namespace content { |
90 | 91 |
91 class InputEventMessageFilter : public BrowserMessageFilter { | |
92 public: | |
93 InputEventMessageFilter() | |
94 : BrowserMessageFilter(InputMsgStart), | |
95 type_(WebInputEvent::Undefined), | |
96 state_(INPUT_EVENT_ACK_STATE_UNKNOWN) {} | |
97 | |
98 void WaitForAck(WebInputEvent::Type type) { | |
99 base::RunLoop run_loop; | |
100 base::AutoReset<base::Closure> reset_quit(&quit_, run_loop.QuitClosure()); | |
101 base::AutoReset<WebInputEvent::Type> reset_type(&type_, type); | |
102 run_loop.Run(); | |
103 } | |
104 | |
105 InputEventAckState last_ack_state() const { return state_; } | |
106 | |
107 protected: | |
108 ~InputEventMessageFilter() override {} | |
109 | |
110 private: | |
111 void ReceivedEventAck(WebInputEvent::Type type, InputEventAckState state) { | |
112 if (type_ == type) { | |
113 state_ = state; | |
114 quit_.Run(); | |
115 } | |
116 } | |
117 | |
118 // BrowserMessageFilter: | |
119 bool OnMessageReceived(const IPC::Message& message) override { | |
120 if (message.type() == InputHostMsg_HandleInputEvent_ACK::ID) { | |
121 InputHostMsg_HandleInputEvent_ACK::Param params; | |
122 InputHostMsg_HandleInputEvent_ACK::Read(&message, ¶ms); | |
123 WebInputEvent::Type type = base::get<0>(params).type; | |
124 InputEventAckState ack = base::get<0>(params).state; | |
125 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
126 base::Bind(&InputEventMessageFilter::ReceivedEventAck, | |
127 this, type, ack)); | |
128 } | |
129 return false; | |
130 } | |
131 | |
132 base::Closure quit_; | |
133 WebInputEvent::Type type_; | |
134 InputEventAckState state_; | |
135 | |
136 DISALLOW_COPY_AND_ASSIGN(InputEventMessageFilter); | |
137 }; | |
138 | |
139 class TouchInputBrowserTest : public ContentBrowserTest { | 92 class TouchInputBrowserTest : public ContentBrowserTest { |
140 public: | 93 public: |
141 TouchInputBrowserTest() {} | 94 TouchInputBrowserTest() {} |
142 ~TouchInputBrowserTest() override {} | 95 ~TouchInputBrowserTest() override {} |
143 | 96 |
144 RenderWidgetHostImpl* GetWidgetHost() { | 97 RenderWidgetHostImpl* GetWidgetHost() { |
145 return RenderWidgetHostImpl::From( | 98 return RenderWidgetHostImpl::From( |
146 shell()->web_contents()->GetRenderViewHost()->GetWidget()); | 99 shell()->web_contents()->GetRenderViewHost()->GetWidget()); |
147 } | 100 } |
148 | 101 |
149 InputEventMessageFilter* filter() { return filter_.get(); } | 102 scoped_refptr<InputMsgWatcher> AddFilter(blink::WebInputEvent::Type type) { |
| 103 return new InputMsgWatcher(GetWidgetHost(), type); |
| 104 } |
150 | 105 |
151 protected: | 106 protected: |
152 void LoadURLAndAddFilter() { | 107 void LoadURL() { |
153 const GURL data_url(kTouchEventDataURL); | 108 const GURL data_url(kTouchEventDataURL); |
154 NavigateToURL(shell(), data_url); | 109 NavigateToURL(shell(), data_url); |
155 | 110 |
156 WebContentsImpl* web_contents = | 111 RenderWidgetHostImpl* host = GetWidgetHost(); |
157 static_cast<WebContentsImpl*>(shell()->web_contents()); | |
158 RenderWidgetHostImpl* host = RenderWidgetHostImpl::From( | |
159 web_contents->GetRenderViewHost()->GetWidget()); | |
160 host->GetView()->SetSize(gfx::Size(400, 400)); | 112 host->GetView()->SetSize(gfx::Size(400, 400)); |
161 | 113 |
162 // The page is loaded in the renderer, wait for a new frame to arrive. | 114 // The page is loaded in the renderer, wait for a new frame to arrive. |
163 while (!host->ScheduleComposite()) | 115 while (!host->ScheduleComposite()) |
164 GiveItSomeTime(); | 116 GiveItSomeTime(); |
165 | |
166 filter_ = new InputEventMessageFilter(); | |
167 host->GetProcess()->AddFilter(filter_.get()); | |
168 } | 117 } |
169 | 118 |
170 void SetUpCommandLine(base::CommandLine* cmd) override { | 119 void SetUpCommandLine(base::CommandLine* cmd) override { |
171 cmd->AppendSwitchASCII(switches::kTouchEvents, | 120 cmd->AppendSwitchASCII(switches::kTouchEvents, |
172 switches::kTouchEventsEnabled); | 121 switches::kTouchEventsEnabled); |
173 } | 122 } |
174 | |
175 scoped_refptr<InputEventMessageFilter> filter_; | |
176 }; | 123 }; |
177 | 124 |
178 #if defined(OS_MACOSX) | 125 #if defined(OS_MACOSX) |
179 // TODO(ccameron): Failing on mac: crbug.com/346363 | 126 // TODO(ccameron): Failing on mac: crbug.com/346363 |
180 #define MAYBE_TouchNoHandler DISABLED_TouchNoHandler | 127 #define MAYBE_TouchNoHandler DISABLED_TouchNoHandler |
181 #else | 128 #else |
182 #define MAYBE_TouchNoHandler TouchNoHandler | 129 #define MAYBE_TouchNoHandler TouchNoHandler |
183 #endif | 130 #endif |
184 IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, MAYBE_TouchNoHandler) { | 131 IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, MAYBE_TouchNoHandler) { |
185 LoadURLAndAddFilter(); | 132 LoadURL(); |
186 SyntheticWebTouchEvent touch; | 133 SyntheticWebTouchEvent touch; |
187 | 134 |
188 // A press on |first| should be acked with NO_CONSUMER_EXISTS since there is | 135 // A press on |first| should be acked with NO_CONSUMER_EXISTS since there is |
189 // no touch-handler on it. | 136 // no touch-handler on it. |
190 touch.PressPoint(25, 25); | 137 touch.PressPoint(25, 25); |
| 138 scoped_refptr<InputMsgWatcher> filter = AddFilter(WebInputEvent::TouchStart); |
191 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); | 139 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); |
192 filter()->WaitForAck(WebInputEvent::TouchStart); | |
193 | 140 |
194 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, | 141 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, filter->WaitForAck()); |
195 filter()->last_ack_state()); | |
196 | 142 |
197 // If a touch-press is acked with NO_CONSUMER_EXISTS, then subsequent | 143 // If a touch-press is acked with NO_CONSUMER_EXISTS, then subsequent |
198 // touch-points don't need to be dispatched until the touch point is released. | 144 // touch-points don't need to be dispatched until the touch point is released. |
199 touch.ReleasePoint(0); | 145 touch.ReleasePoint(0); |
200 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); | 146 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); |
201 touch.ResetPoints(); | 147 touch.ResetPoints(); |
202 } | 148 } |
203 | 149 |
204 #if defined(OS_CHROMEOS) | 150 #if defined(OS_CHROMEOS) |
205 // crbug.com/514456 | 151 // crbug.com/514456 |
206 #define MAYBE_TouchHandlerNoConsume DISABLED_TouchHandlerNoConsume | 152 #define MAYBE_TouchHandlerNoConsume DISABLED_TouchHandlerNoConsume |
207 #else | 153 #else |
208 #define MAYBE_TouchHandlerNoConsume TouchHandlerNoConsume | 154 #define MAYBE_TouchHandlerNoConsume TouchHandlerNoConsume |
209 #endif | 155 #endif |
210 IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, MAYBE_TouchHandlerNoConsume) { | 156 IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, MAYBE_TouchHandlerNoConsume) { |
211 LoadURLAndAddFilter(); | 157 LoadURL(); |
212 SyntheticWebTouchEvent touch; | 158 SyntheticWebTouchEvent touch; |
213 | 159 |
214 // Press on |second| should be acked with NOT_CONSUMED since there is a | 160 // Press on |second| should be acked with NOT_CONSUMED since there is a |
215 // touch-handler on |second|, but it doesn't consume the event. | 161 // touch-handler on |second|, but it doesn't consume the event. |
216 touch.PressPoint(125, 25); | 162 touch.PressPoint(125, 25); |
| 163 scoped_refptr<InputMsgWatcher> filter = AddFilter(WebInputEvent::TouchStart); |
217 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); | 164 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); |
218 filter()->WaitForAck(WebInputEvent::TouchStart); | 165 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, filter->WaitForAck()); |
219 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, filter()->last_ack_state()); | |
220 | 166 |
| 167 filter = AddFilter(WebInputEvent::TouchEnd); |
221 touch.ReleasePoint(0); | 168 touch.ReleasePoint(0); |
222 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); | 169 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); |
223 filter()->WaitForAck(WebInputEvent::TouchEnd); | |
224 touch.ResetPoints(); | 170 touch.ResetPoints(); |
| 171 filter->WaitForAck(); |
225 } | 172 } |
226 | 173 |
227 #if defined(OS_CHROMEOS) | 174 #if defined(OS_CHROMEOS) |
228 // crbug.com/514456 | 175 // crbug.com/514456 |
229 #define MAYBE_TouchHandlerConsume DISABLED_TouchHandlerConsume | 176 #define MAYBE_TouchHandlerConsume DISABLED_TouchHandlerConsume |
230 #else | 177 #else |
231 #define MAYBE_TouchHandlerConsume TouchHandlerConsume | 178 #define MAYBE_TouchHandlerConsume TouchHandlerConsume |
232 #endif | 179 #endif |
233 IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, MAYBE_TouchHandlerConsume) { | 180 IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, MAYBE_TouchHandlerConsume) { |
234 LoadURLAndAddFilter(); | 181 LoadURL(); |
235 SyntheticWebTouchEvent touch; | 182 SyntheticWebTouchEvent touch; |
236 | 183 |
237 // Press on |third| should be acked with CONSUMED since the touch-handler on | 184 // Press on |third| should be acked with CONSUMED since the touch-handler on |
238 // |third| consimes the event. | 185 // |third| consimes the event. |
239 touch.PressPoint(25, 125); | 186 touch.PressPoint(25, 125); |
| 187 scoped_refptr<InputMsgWatcher> filter = AddFilter(WebInputEvent::TouchStart); |
240 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); | 188 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); |
241 filter()->WaitForAck(WebInputEvent::TouchStart); | 189 EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, filter->WaitForAck()); |
242 EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, filter()->last_ack_state()); | |
243 | 190 |
244 touch.ReleasePoint(0); | 191 touch.ReleasePoint(0); |
| 192 filter = AddFilter(WebInputEvent::TouchEnd); |
245 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); | 193 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); |
246 filter()->WaitForAck(WebInputEvent::TouchEnd); | 194 filter->WaitForAck(); |
247 } | 195 } |
248 | 196 |
249 #if defined(OS_CHROMEOS) | 197 #if defined(OS_CHROMEOS) |
250 // crbug.com/514456 | 198 // crbug.com/514456 |
251 #define MAYBE_MultiPointTouchPress DISABLED_MultiPointTouchPress | 199 #define MAYBE_MultiPointTouchPress DISABLED_MultiPointTouchPress |
252 #elif defined(OS_MACOSX) | 200 #elif defined(OS_MACOSX) |
253 // TODO(ccameron): Failing on mac: crbug.com/346363 | 201 // TODO(ccameron): Failing on mac: crbug.com/346363 |
254 #define MAYBE_MultiPointTouchPress DISABLED_MultiPointTouchPress | 202 #define MAYBE_MultiPointTouchPress DISABLED_MultiPointTouchPress |
255 #else | 203 #else |
256 #define MAYBE_MultiPointTouchPress MultiPointTouchPress | 204 #define MAYBE_MultiPointTouchPress MultiPointTouchPress |
257 #endif | 205 #endif |
258 IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, MAYBE_MultiPointTouchPress) { | 206 IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, MAYBE_MultiPointTouchPress) { |
259 LoadURLAndAddFilter(); | 207 LoadURL(); |
260 SyntheticWebTouchEvent touch; | 208 SyntheticWebTouchEvent touch; |
261 | 209 |
262 // Press on |first|, which sould be acked with NO_CONSUMER_EXISTS. Then press | 210 // Press on |first|, which sould be acked with NO_CONSUMER_EXISTS. Then press |
263 // on |third|. That point should be acked with CONSUMED. | 211 // on |third|. That point should be acked with CONSUMED. |
264 touch.PressPoint(25, 25); | 212 touch.PressPoint(25, 25); |
| 213 scoped_refptr<InputMsgWatcher> filter = AddFilter(WebInputEvent::TouchStart); |
265 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); | 214 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); |
266 filter()->WaitForAck(WebInputEvent::TouchStart); | 215 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, filter->WaitForAck()); |
267 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, | |
268 filter()->last_ack_state()); | |
269 | 216 |
270 touch.PressPoint(25, 125); | 217 touch.PressPoint(25, 125); |
| 218 filter = AddFilter(WebInputEvent::TouchStart); |
271 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); | 219 GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); |
272 filter()->WaitForAck(WebInputEvent::TouchStart); | 220 EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, filter->WaitForAck()); |
273 EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, filter()->last_ack_state()); | |
274 } | 221 } |
275 | 222 |
276 } // namespace content | 223 } // namespace content |
OLD | NEW |