| 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->Wait()); |
| 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->Wait()); |
| 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->Wait(); |
| 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->Wait()); |
| 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->Wait(); |
| 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->Wait()); |
| 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->Wait()); |
| 273 EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, filter()->last_ack_state()); | |
| 274 } | 221 } |
| 275 | 222 |
| 276 } // namespace content | 223 } // namespace content |
| OLD | NEW |