lfg | 84763c9 | 2017-02-16 18:55:15 | [diff] [blame] | 1 | // Copyright 2017 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/browser/pointer_lock_browsertest.h" |
| 6 | |
| 7 | #include "content/browser/frame_host/frame_tree.h" |
| 8 | #include "content/browser/renderer_host/render_widget_host_impl.h" |
| 9 | #include "content/browser/renderer_host/render_widget_host_input_event_router.h" |
| 10 | #include "content/browser/web_contents/web_contents_impl.h" |
| 11 | #include "content/public/browser/web_contents_delegate.h" |
| 12 | #include "content/public/test/browser_test_utils.h" |
| 13 | #include "content/public/test/content_browser_test.h" |
| 14 | #include "content/public/test/content_browser_test_utils.h" |
| 15 | #include "content/public/test/test_utils.h" |
| 16 | #include "content/shell/browser/shell.h" |
| 17 | #include "content/test/content_browser_test_utils_internal.h" |
| 18 | #include "net/dns/mock_host_resolver.h" |
| 19 | #include "net/test/embedded_test_server/embedded_test_server.h" |
| 20 | |
| 21 | #ifdef USE_AURA |
| 22 | #include "content/browser/renderer_host/render_widget_host_view_aura.h" |
| 23 | #include "content/browser/web_contents/web_contents_view_aura.h" |
| 24 | #endif // USE_AURA |
| 25 | |
| 26 | namespace content { |
| 27 | |
| 28 | namespace { |
| 29 | |
| 30 | #ifdef USE_AURA |
| 31 | class MockRenderWidgetHostView : public RenderWidgetHostViewAura { |
| 32 | public: |
| 33 | MockRenderWidgetHostView(RenderWidgetHost* host, bool is_guest_view_hack) |
Fady Samuel | 04b4124 | 2017-09-27 09:25:00 | [diff] [blame] | 34 | : RenderWidgetHostViewAura(host, |
| 35 | is_guest_view_hack, |
Scott Violet | c884c7fd | 2017-11-03 23:51:01 | [diff] [blame] | 36 | false /* is_mus_browser_plugin_guest */), |
lfg | 84763c9 | 2017-02-16 18:55:15 | [diff] [blame] | 37 | host_(RenderWidgetHostImpl::From(host)) {} |
| 38 | ~MockRenderWidgetHostView() override { |
| 39 | if (mouse_locked_) |
| 40 | UnlockMouse(); |
| 41 | } |
| 42 | |
| 43 | bool LockMouse() override { |
| 44 | mouse_locked_ = true; |
| 45 | return true; |
| 46 | } |
| 47 | |
| 48 | void UnlockMouse() override { |
| 49 | host_->LostMouseLock(); |
| 50 | mouse_locked_ = false; |
| 51 | } |
| 52 | |
| 53 | bool IsMouseLocked() override { return mouse_locked_; } |
| 54 | |
| 55 | bool HasFocus() const override { return true; } |
| 56 | |
| 57 | void OnWindowFocused(aura::Window* gained_focus, |
| 58 | aura::Window* lost_focus) override { |
| 59 | // Ignore window focus events. |
| 60 | } |
| 61 | |
| 62 | RenderWidgetHostImpl* host_; |
| 63 | }; |
| 64 | #endif // USE_AURA |
| 65 | |
| 66 | } // namespace |
| 67 | |
| 68 | class MockPointerLockWebContentsDelegate : public WebContentsDelegate { |
| 69 | public: |
| 70 | MockPointerLockWebContentsDelegate() {} |
| 71 | ~MockPointerLockWebContentsDelegate() override {} |
| 72 | |
| 73 | void RequestToLockMouse(WebContents* web_contents, |
| 74 | bool user_gesture, |
| 75 | bool last_unlocked_by_target) override { |
| 76 | web_contents->GotResponseToLockMouseRequest(true); |
| 77 | } |
| 78 | |
| 79 | void LostMouseLock() override {} |
| 80 | }; |
| 81 | |
| 82 | #ifdef USE_AURA |
| 83 | void InstallCreateHooksForPointerLockBrowserTests() { |
| 84 | WebContentsViewAura::InstallCreateHookForTests( |
| 85 | [](RenderWidgetHost* host, |
| 86 | bool is_guest_view_hack) -> RenderWidgetHostViewAura* { |
| 87 | return new MockRenderWidgetHostView(host, is_guest_view_hack); |
| 88 | }); |
| 89 | } |
| 90 | #endif // USE_AURA |
| 91 | |
| 92 | class PointerLockBrowserTest : public ContentBrowserTest { |
| 93 | public: |
| 94 | PointerLockBrowserTest() {} |
| 95 | |
| 96 | protected: |
| 97 | void SetUpCommandLine(base::CommandLine* command_line) override { |
| 98 | IsolateAllSitesForTesting(command_line); |
| 99 | } |
| 100 | |
| 101 | void SetUp() override { |
| 102 | InstallCreateHooksForPointerLockBrowserTests(); |
| 103 | ContentBrowserTest::SetUp(); |
| 104 | } |
| 105 | |
| 106 | void SetUpOnMainThread() override { |
| 107 | host_resolver()->AddRule("*", "127.0.0.1"); |
| 108 | SetupCrossSiteRedirector(embedded_test_server()); |
| 109 | ASSERT_TRUE(embedded_test_server()->Start()); |
| 110 | |
| 111 | web_contents()->SetDelegate(&web_contents_delegate_); |
| 112 | } |
| 113 | |
| 114 | WebContentsImpl* web_contents() const { |
| 115 | return static_cast<WebContentsImpl*>(shell()->web_contents()); |
| 116 | } |
| 117 | |
| 118 | private: |
| 119 | MockPointerLockWebContentsDelegate web_contents_delegate_; |
| 120 | }; |
| 121 | |
| 122 | IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLock) { |
| 123 | GURL main_url(embedded_test_server()->GetURL( |
| 124 | "a.com", "/cross_site_iframe_factory.html?a(b)")); |
| 125 | EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
| 126 | |
| 127 | FrameTreeNode* root = web_contents()->GetFrameTree()->root(); |
| 128 | FrameTreeNode* child = root->child_at(0); |
| 129 | |
| 130 | // Request a pointer lock on the root frame's body. |
| 131 | EXPECT_TRUE(ExecuteScript(root, "document.body.requestPointerLock()")); |
| 132 | |
| 133 | // Root frame should have been granted pointer lock. |
| 134 | bool locked = false; |
| 135 | EXPECT_TRUE(ExecuteScriptAndExtractBool(root, |
| 136 | "window.domAutomationController.send(" |
| 137 | "document.pointerLockElement == " |
| 138 | "document.body);", |
| 139 | &locked)); |
| 140 | EXPECT_TRUE(locked); |
| 141 | |
| 142 | // Request a pointer lock on the child frame's body. |
| 143 | EXPECT_TRUE(ExecuteScript(child, "document.body.requestPointerLock()")); |
| 144 | |
| 145 | // Child frame should not be granted pointer lock since the root frame has it. |
| 146 | EXPECT_TRUE(ExecuteScriptAndExtractBool(child, |
| 147 | "window.domAutomationController.send(" |
| 148 | "document.pointerLockElement == " |
| 149 | "document.body);", |
| 150 | &locked)); |
| 151 | EXPECT_FALSE(locked); |
| 152 | |
| 153 | // Release pointer lock on root frame. |
| 154 | EXPECT_TRUE(ExecuteScript(root, "document.exitPointerLock()")); |
| 155 | |
| 156 | // Request a pointer lock on the child frame's body. |
| 157 | EXPECT_TRUE(ExecuteScript(child, "document.body.requestPointerLock()")); |
| 158 | |
| 159 | // Child frame should have been granted pointer lock. |
| 160 | EXPECT_TRUE(ExecuteScriptAndExtractBool(child, |
| 161 | "window.domAutomationController.send(" |
| 162 | "document.pointerLockElement == " |
| 163 | "document.body);", |
| 164 | &locked)); |
| 165 | EXPECT_TRUE(locked); |
| 166 | } |
| 167 | |
| 168 | IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockEventRouting) { |
| 169 | GURL main_url(embedded_test_server()->GetURL( |
| 170 | "a.com", "/cross_site_iframe_factory.html?a(b)")); |
| 171 | EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
| 172 | |
| 173 | FrameTreeNode* root = web_contents()->GetFrameTree()->root(); |
| 174 | FrameTreeNode* child = root->child_at(0); |
| 175 | RenderWidgetHostInputEventRouter* router = |
| 176 | web_contents()->GetInputEventRouter(); |
| 177 | RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>( |
| 178 | root->current_frame_host()->GetView()); |
| 179 | RenderWidgetHostViewBase* child_view = static_cast<RenderWidgetHostViewBase*>( |
| 180 | child->current_frame_host()->GetView()); |
| 181 | |
Ken Buchanan | 8a319fb | 2017-11-15 18:37:12 | [diff] [blame] | 182 | WaitForChildFrameSurfaceReady(child->current_frame_host()); |
| 183 | |
lfg | 84763c9 | 2017-02-16 18:55:15 | [diff] [blame] | 184 | // Request a pointer lock on the root frame's body. |
| 185 | EXPECT_TRUE(ExecuteScript(root, "document.body.requestPointerLock()")); |
| 186 | |
| 187 | // Root frame should have been granted pointer lock. |
| 188 | bool locked = false; |
| 189 | EXPECT_TRUE(ExecuteScriptAndExtractBool(root, |
| 190 | "window.domAutomationController.send(" |
| 191 | "document.pointerLockElement == " |
| 192 | "document.body);", |
| 193 | &locked)); |
| 194 | EXPECT_TRUE(locked); |
| 195 | |
| 196 | // Add a mouse move event listener to the root frame. |
| 197 | EXPECT_TRUE(ExecuteScript( |
| 198 | root, |
| 199 | "var x; var y; var mX; var mY; document.addEventListener('mousemove', " |
| 200 | "function(e) {x = e.x; y = e.y; mX = e.movementX; mY = e.movementY;});")); |
| 201 | |
Daniel Cheng | 93c80a9 | 2018-02-14 19:02:43 | [diff] [blame] | 202 | blink::WebMouseEvent mouse_event( |
| 203 | blink::WebInputEvent::kMouseMove, blink::WebInputEvent::kNoModifiers, |
| 204 | blink::WebInputEvent::GetStaticTimeStampForTests()); |
Blink Reformat | 1c4d759e | 2017-04-09 16:34:54 | [diff] [blame] | 205 | mouse_event.SetPositionInWidget(10, 11); |
| 206 | mouse_event.movement_x = 12; |
| 207 | mouse_event.movement_y = 13; |
lfg | 84763c9 | 2017-02-16 18:55:15 | [diff] [blame] | 208 | router->RouteMouseEvent(root_view, &mouse_event, ui::LatencyInfo()); |
| 209 | |
| 210 | // Make sure that the renderer handled the input event. |
| 211 | MainThreadFrameObserver root_observer(root_view->GetRenderWidgetHost()); |
| 212 | root_observer.Wait(); |
| 213 | |
| 214 | int x, y, movementX, movementY; |
| 215 | EXPECT_TRUE(ExecuteScriptAndExtractInt( |
| 216 | root, "window.domAutomationController.send(x);", &x)); |
| 217 | EXPECT_TRUE(ExecuteScriptAndExtractInt( |
| 218 | root, "window.domAutomationController.send(y);", &y)); |
| 219 | EXPECT_TRUE(ExecuteScriptAndExtractInt( |
| 220 | root, "window.domAutomationController.send(mX);", &movementX)); |
| 221 | EXPECT_TRUE(ExecuteScriptAndExtractInt( |
| 222 | root, "window.domAutomationController.send(mY);", &movementY)); |
| 223 | EXPECT_EQ(10, x); |
| 224 | EXPECT_EQ(11, y); |
| 225 | EXPECT_EQ(12, movementX); |
| 226 | EXPECT_EQ(13, movementY); |
| 227 | |
| 228 | // Release pointer lock on root frame. |
| 229 | EXPECT_TRUE(ExecuteScript(root, "document.exitPointerLock()")); |
| 230 | |
| 231 | // Request a pointer lock on the child frame's body. |
| 232 | EXPECT_TRUE(ExecuteScript(child, "document.body.requestPointerLock()")); |
| 233 | |
| 234 | // Child frame should have been granted pointer lock. |
| 235 | EXPECT_TRUE(ExecuteScriptAndExtractBool(child, |
| 236 | "window.domAutomationController.send(" |
| 237 | "document.pointerLockElement == " |
| 238 | "document.body);", |
| 239 | &locked)); |
| 240 | EXPECT_TRUE(locked); |
| 241 | |
| 242 | // Add a mouse move event listener to the child frame. |
| 243 | EXPECT_TRUE(ExecuteScript( |
| 244 | child, |
| 245 | "var x; var y; var mX; var mY; document.addEventListener('mousemove', " |
| 246 | "function(e) {x = e.x; y = e.y; mX = e.movementX; mY = e.movementY;});")); |
| 247 | |
Ella Ge | 43cccf17 | 2017-10-19 15:44:16 | [diff] [blame] | 248 | gfx::PointF transformed_point; |
| 249 | root_view->TransformPointToCoordSpaceForView(gfx::PointF(0, 0), child_view, |
lfg | 84763c9 | 2017-02-16 18:55:15 | [diff] [blame] | 250 | &transformed_point); |
| 251 | |
Blink Reformat | 1c4d759e | 2017-04-09 16:34:54 | [diff] [blame] | 252 | mouse_event.SetPositionInWidget(-transformed_point.x() + 14, |
mustaq | c51f3aab | 2017-04-05 15:43:11 | [diff] [blame] | 253 | -transformed_point.y() + 15); |
Blink Reformat | 1c4d759e | 2017-04-09 16:34:54 | [diff] [blame] | 254 | mouse_event.movement_x = 16; |
| 255 | mouse_event.movement_y = 17; |
lfg | 84763c9 | 2017-02-16 18:55:15 | [diff] [blame] | 256 | // We use root_view intentionally as the RenderWidgetHostInputEventRouter is |
| 257 | // responsible for correctly routing the event to the child frame. |
| 258 | router->RouteMouseEvent(root_view, &mouse_event, ui::LatencyInfo()); |
| 259 | |
| 260 | // Make sure that the renderer handled the input event. |
| 261 | MainThreadFrameObserver child_observer(child_view->GetRenderWidgetHost()); |
| 262 | child_observer.Wait(); |
| 263 | |
| 264 | EXPECT_TRUE(ExecuteScriptAndExtractInt( |
| 265 | child, "window.domAutomationController.send(x);", &x)); |
| 266 | EXPECT_TRUE(ExecuteScriptAndExtractInt( |
| 267 | child, "window.domAutomationController.send(y);", &y)); |
| 268 | EXPECT_TRUE(ExecuteScriptAndExtractInt( |
| 269 | child, "window.domAutomationController.send(mX);", &movementX)); |
| 270 | EXPECT_TRUE(ExecuteScriptAndExtractInt( |
| 271 | child, "window.domAutomationController.send(mY);", &movementY)); |
| 272 | EXPECT_EQ(14, x); |
| 273 | EXPECT_EQ(15, y); |
| 274 | EXPECT_EQ(16, movementX); |
| 275 | EXPECT_EQ(17, movementY); |
| 276 | } |
| 277 | |
lfg | 7d4caad | 2017-03-22 09:01:45 | [diff] [blame] | 278 | // Tests that the browser will not unlock the pointer if a RenderWidgetHostView |
| 279 | // that doesn't hold the pointer lock is destroyed. |
lfg | de6f0d1f | 2017-03-24 15:29:51 | [diff] [blame] | 280 | IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockChildFrameDetached) { |
lfg | 7d4caad | 2017-03-22 09:01:45 | [diff] [blame] | 281 | GURL main_url(embedded_test_server()->GetURL( |
| 282 | "a.com", "/cross_site_iframe_factory.html?a(b)")); |
| 283 | EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
| 284 | |
| 285 | FrameTreeNode* root = web_contents()->GetFrameTree()->root(); |
| 286 | |
| 287 | // Request a pointer lock on the root frame's body. |
| 288 | EXPECT_TRUE(ExecuteScript(root, "document.body.requestPointerLock()")); |
| 289 | |
| 290 | // Root frame should have been granted pointer lock. |
| 291 | bool locked = false; |
| 292 | EXPECT_TRUE(ExecuteScriptAndExtractBool(root, |
| 293 | "window.domAutomationController.send(" |
| 294 | "document.pointerLockElement == " |
| 295 | "document.body);", |
| 296 | &locked)); |
| 297 | EXPECT_TRUE(locked); |
| 298 | |
| 299 | // Root (platform) RenderWidgetHostView should have the pointer locked. |
| 300 | EXPECT_TRUE(root->current_frame_host()->GetView()->IsMouseLocked()); |
| 301 | EXPECT_EQ(root->current_frame_host()->GetRenderWidgetHost(), |
| 302 | web_contents()->GetMouseLockWidget()); |
| 303 | |
| 304 | // Detach the child frame. |
| 305 | EXPECT_TRUE(ExecuteScript(root, "document.querySelector('iframe').remove()")); |
| 306 | |
| 307 | // Root (platform) RenderWidgetHostView should still have the pointer locked. |
| 308 | EXPECT_TRUE(root->current_frame_host()->GetView()->IsMouseLocked()); |
| 309 | EXPECT_EQ(root->current_frame_host()->GetRenderWidgetHost(), |
| 310 | web_contents()->GetMouseLockWidget()); |
| 311 | } |
| 312 | |
lfg | 9a467e1 | 2017-03-23 21:14:36 | [diff] [blame] | 313 | IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockWheelEventRouting) { |
| 314 | GURL main_url(embedded_test_server()->GetURL( |
| 315 | "a.com", "/cross_site_iframe_factory.html?a(b)")); |
| 316 | EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
| 317 | |
| 318 | FrameTreeNode* root = web_contents()->GetFrameTree()->root(); |
| 319 | FrameTreeNode* child = root->child_at(0); |
| 320 | RenderWidgetHostInputEventRouter* router = |
| 321 | web_contents()->GetInputEventRouter(); |
| 322 | RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>( |
| 323 | root->current_frame_host()->GetView()); |
| 324 | RenderWidgetHostViewBase* child_view = static_cast<RenderWidgetHostViewBase*>( |
| 325 | child->current_frame_host()->GetView()); |
| 326 | |
Ken Buchanan | 8a319fb | 2017-11-15 18:37:12 | [diff] [blame] | 327 | WaitForChildFrameSurfaceReady(child->current_frame_host()); |
| 328 | |
lfg | 9a467e1 | 2017-03-23 21:14:36 | [diff] [blame] | 329 | // Request a pointer lock on the root frame's body. |
| 330 | EXPECT_TRUE(ExecuteScript(root, "document.body.requestPointerLock()")); |
| 331 | |
| 332 | // Root frame should have been granted pointer lock. |
| 333 | bool locked = false; |
| 334 | EXPECT_TRUE(ExecuteScriptAndExtractBool(root, |
| 335 | "window.domAutomationController.send(" |
| 336 | "document.pointerLockElement == " |
| 337 | "document.body);", |
| 338 | &locked)); |
| 339 | EXPECT_TRUE(locked); |
| 340 | |
| 341 | // Add a mouse move wheel event listener to the root frame. |
| 342 | EXPECT_TRUE(ExecuteScript( |
| 343 | root, |
| 344 | "var x; var y; var mX; var mY; document.addEventListener('mousewheel', " |
| 345 | "function(e) {x = e.x; y = e.y; dX = e.deltaX; dY = e.deltaY;});")); |
| 346 | MainThreadFrameObserver root_observer(root_view->GetRenderWidgetHost()); |
| 347 | root_observer.Wait(); |
| 348 | |
| 349 | blink::WebMouseWheelEvent wheel_event( |
Blink Reformat | 1c4d759e | 2017-04-09 16:34:54 | [diff] [blame] | 350 | blink::WebInputEvent::kMouseWheel, blink::WebInputEvent::kNoModifiers, |
Daniel Cheng | 93c80a9 | 2018-02-14 19:02:43 | [diff] [blame] | 351 | blink::WebInputEvent::GetStaticTimeStampForTests()); |
Blink Reformat | 1c4d759e | 2017-04-09 16:34:54 | [diff] [blame] | 352 | wheel_event.SetPositionInWidget(10, 11); |
| 353 | wheel_event.delta_x = -12; |
| 354 | wheel_event.delta_y = -13; |
sahel | 4194246 | 2017-07-06 14:14:37 | [diff] [blame] | 355 | wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan; |
lfg | 9a467e1 | 2017-03-23 21:14:36 | [diff] [blame] | 356 | router->RouteMouseWheelEvent(root_view, &wheel_event, ui::LatencyInfo()); |
| 357 | |
| 358 | // Make sure that the renderer handled the input event. |
| 359 | root_observer.Wait(); |
| 360 | |
sahel | 955c329 | 2017-08-17 14:56:44 | [diff] [blame] | 361 | if (root_view->wheel_scroll_latching_enabled()) { |
| 362 | // When wheel scroll latching is enabled all wheel events during a scroll |
| 363 | // sequence will be sent to a single target. Send a wheel end event to the |
| 364 | // current target before sending wheel events to a new target. |
| 365 | wheel_event.delta_x = 0; |
| 366 | wheel_event.delta_y = 0; |
| 367 | wheel_event.phase = blink::WebMouseWheelEvent::kPhaseEnded; |
| 368 | router->RouteMouseWheelEvent(root_view, &wheel_event, ui::LatencyInfo()); |
| 369 | |
| 370 | // Make sure that the renderer handled the input event. |
| 371 | root_observer.Wait(); |
| 372 | } |
| 373 | |
lfg | 9a467e1 | 2017-03-23 21:14:36 | [diff] [blame] | 374 | int x, y, deltaX, deltaY; |
| 375 | EXPECT_TRUE(ExecuteScriptAndExtractInt( |
| 376 | root, "window.domAutomationController.send(x);", &x)); |
| 377 | EXPECT_TRUE(ExecuteScriptAndExtractInt( |
| 378 | root, "window.domAutomationController.send(y);", &y)); |
| 379 | EXPECT_TRUE(ExecuteScriptAndExtractInt( |
| 380 | root, "window.domAutomationController.send(dX);", &deltaX)); |
| 381 | EXPECT_TRUE(ExecuteScriptAndExtractInt( |
| 382 | root, "window.domAutomationController.send(dY);", &deltaY)); |
| 383 | EXPECT_EQ(10, x); |
| 384 | EXPECT_EQ(11, y); |
| 385 | EXPECT_EQ(12, deltaX); |
| 386 | EXPECT_EQ(13, deltaY); |
| 387 | |
| 388 | // Release pointer lock on root frame. |
| 389 | EXPECT_TRUE(ExecuteScript(root, "document.exitPointerLock()")); |
| 390 | |
| 391 | // Request a pointer lock on the child frame's body. |
| 392 | EXPECT_TRUE(ExecuteScript(child, "document.body.requestPointerLock()")); |
| 393 | |
| 394 | // Child frame should have been granted pointer lock. |
| 395 | EXPECT_TRUE(ExecuteScriptAndExtractBool(child, |
| 396 | "window.domAutomationController.send(" |
| 397 | "document.pointerLockElement == " |
| 398 | "document.body);", |
| 399 | &locked)); |
| 400 | EXPECT_TRUE(locked); |
| 401 | |
| 402 | // Add a mouse move event listener to the child frame. |
| 403 | EXPECT_TRUE(ExecuteScript( |
| 404 | child, |
| 405 | "var x; var y; var mX; var mY; document.addEventListener('mousewheel', " |
| 406 | "function(e) {x = e.x; y = e.y; dX = e.deltaX; dY = e.deltaY;});")); |
| 407 | MainThreadFrameObserver child_observer(child_view->GetRenderWidgetHost()); |
| 408 | child_observer.Wait(); |
| 409 | |
Ella Ge | 43cccf17 | 2017-10-19 15:44:16 | [diff] [blame] | 410 | gfx::PointF transformed_point; |
| 411 | root_view->TransformPointToCoordSpaceForView(gfx::PointF(0, 0), child_view, |
lfg | 9a467e1 | 2017-03-23 21:14:36 | [diff] [blame] | 412 | &transformed_point); |
| 413 | |
Blink Reformat | 1c4d759e | 2017-04-09 16:34:54 | [diff] [blame] | 414 | wheel_event.SetPositionInWidget(-transformed_point.x() + 14, |
mustaq | c51f3aab | 2017-04-05 15:43:11 | [diff] [blame] | 415 | -transformed_point.y() + 15); |
Blink Reformat | 1c4d759e | 2017-04-09 16:34:54 | [diff] [blame] | 416 | wheel_event.delta_x = -16; |
| 417 | wheel_event.delta_y = -17; |
sahel | 955c329 | 2017-08-17 14:56:44 | [diff] [blame] | 418 | if (root_view->wheel_scroll_latching_enabled()) |
| 419 | wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan; |
lfg | 9a467e1 | 2017-03-23 21:14:36 | [diff] [blame] | 420 | // We use root_view intentionally as the RenderWidgetHostInputEventRouter is |
| 421 | // responsible for correctly routing the event to the child frame. |
| 422 | router->RouteMouseWheelEvent(root_view, &wheel_event, ui::LatencyInfo()); |
| 423 | |
| 424 | // Make sure that the renderer handled the input event. |
| 425 | child_observer.Wait(); |
| 426 | |
| 427 | EXPECT_TRUE(ExecuteScriptAndExtractInt( |
| 428 | child, "window.domAutomationController.send(x);", &x)); |
| 429 | EXPECT_TRUE(ExecuteScriptAndExtractInt( |
| 430 | child, "window.domAutomationController.send(y);", &y)); |
| 431 | EXPECT_TRUE(ExecuteScriptAndExtractInt( |
| 432 | child, "window.domAutomationController.send(dX);", &deltaX)); |
| 433 | EXPECT_TRUE(ExecuteScriptAndExtractInt( |
| 434 | child, "window.domAutomationController.send(dY);", &deltaY)); |
| 435 | EXPECT_EQ(14, x); |
| 436 | EXPECT_EQ(15, y); |
| 437 | EXPECT_EQ(16, deltaX); |
| 438 | EXPECT_EQ(17, deltaY); |
| 439 | } |
| 440 | |
lfg | 84763c9 | 2017-02-16 18:55:15 | [diff] [blame] | 441 | } // namespace content |