Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(738)

Side by Side Diff: content/browser/pointer_lock_browsertest.cc

Issue 2592243002: Perform direct routing of mouse events when the pointer is locked. (Closed)
Patch Set: addressing comments Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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)
34 : RenderWidgetHostViewAura(host, is_guest_view_hack),
35 host_(RenderWidgetHostImpl::From(host)) {}
36 ~MockRenderWidgetHostView() override {
37 if (mouse_locked_)
38 UnlockMouse();
39 }
40
41 bool LockMouse() override {
42 mouse_locked_ = true;
43 return true;
44 }
45
46 void UnlockMouse() override {
47 host_->LostMouseLock();
48 mouse_locked_ = false;
49 }
50
51 bool IsMouseLocked() override { return mouse_locked_; }
52
53 bool HasFocus() const override { return true; }
54
55 void OnWindowFocused(aura::Window* gained_focus,
56 aura::Window* lost_focus) override {
57 // Ignore window focus events.
58 }
59
60 RenderWidgetHostImpl* host_;
61 };
62 #endif // USE_AURA
63
64 } // namespace
65
66 class MockPointerLockWebContentsDelegate : public WebContentsDelegate {
67 public:
68 MockPointerLockWebContentsDelegate() {}
69 ~MockPointerLockWebContentsDelegate() override {}
70
71 void RequestToLockMouse(WebContents* web_contents,
72 bool user_gesture,
73 bool last_unlocked_by_target) override {
74 web_contents->GotResponseToLockMouseRequest(true);
75 }
76
77 void LostMouseLock() override {}
78 };
79
80 #ifdef USE_AURA
81 void InstallCreateHooksForPointerLockBrowserTests() {
82 WebContentsViewAura::InstallCreateHookForTests(
83 [](RenderWidgetHost* host,
84 bool is_guest_view_hack) -> RenderWidgetHostViewAura* {
85 return new MockRenderWidgetHostView(host, is_guest_view_hack);
86 });
87 }
88 #endif // USE_AURA
89
90 class PointerLockBrowserTest : public ContentBrowserTest {
91 public:
92 PointerLockBrowserTest() {}
93
94 protected:
95 void SetUpCommandLine(base::CommandLine* command_line) override {
96 IsolateAllSitesForTesting(command_line);
97 }
98
99 void SetUp() override {
100 InstallCreateHooksForPointerLockBrowserTests();
101 ContentBrowserTest::SetUp();
102 }
103
104 void SetUpOnMainThread() override {
105 host_resolver()->AddRule("*", "127.0.0.1");
106 SetupCrossSiteRedirector(embedded_test_server());
107 ASSERT_TRUE(embedded_test_server()->Start());
108
109 web_contents()->SetDelegate(&web_contents_delegate_);
110 }
111
112 WebContentsImpl* web_contents() const {
113 return static_cast<WebContentsImpl*>(shell()->web_contents());
114 }
115
116 private:
117 MockPointerLockWebContentsDelegate web_contents_delegate_;
118 };
119
120 IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLock) {
121 GURL main_url(embedded_test_server()->GetURL(
122 "a.com", "/cross_site_iframe_factory.html?a(b)"));
123 EXPECT_TRUE(NavigateToURL(shell(), main_url));
124
125 FrameTreeNode* root = web_contents()->GetFrameTree()->root();
126 FrameTreeNode* child = root->child_at(0);
127
128 // Request a pointer lock on the root frame's body.
129 EXPECT_TRUE(ExecuteScript(root, "document.body.requestPointerLock()"));
130
131 // Root frame should have been granted pointer lock.
132 bool locked = false;
133 EXPECT_TRUE(ExecuteScriptAndExtractBool(root,
134 "window.domAutomationController.send("
135 "document.pointerLockElement == "
136 "document.body);",
137 &locked));
138 EXPECT_TRUE(locked);
139
140 // Request a pointer lock on the child frame's body.
141 EXPECT_TRUE(ExecuteScript(child, "document.body.requestPointerLock()"));
142
143 // Child frame should not be granted pointer lock since the root frame has it.
144 EXPECT_TRUE(ExecuteScriptAndExtractBool(child,
145 "window.domAutomationController.send("
146 "document.pointerLockElement == "
147 "document.body);",
148 &locked));
149 EXPECT_FALSE(locked);
150
151 // Release pointer lock on root frame.
152 EXPECT_TRUE(ExecuteScript(root, "document.exitPointerLock()"));
153
154 // Request a pointer lock on the child frame's body.
155 EXPECT_TRUE(ExecuteScript(child, "document.body.requestPointerLock()"));
156
157 // Child frame should have been granted pointer lock.
158 EXPECT_TRUE(ExecuteScriptAndExtractBool(child,
159 "window.domAutomationController.send("
160 "document.pointerLockElement == "
161 "document.body);",
162 &locked));
163 EXPECT_TRUE(locked);
164 }
165
166 IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockEventRouting) {
167 GURL main_url(embedded_test_server()->GetURL(
168 "a.com", "/cross_site_iframe_factory.html?a(b)"));
169 EXPECT_TRUE(NavigateToURL(shell(), main_url));
170
171 FrameTreeNode* root = web_contents()->GetFrameTree()->root();
172 FrameTreeNode* child = root->child_at(0);
173 RenderWidgetHostInputEventRouter* router =
174 web_contents()->GetInputEventRouter();
175 RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>(
176 root->current_frame_host()->GetView());
177 RenderWidgetHostViewBase* child_view = static_cast<RenderWidgetHostViewBase*>(
178 child->current_frame_host()->GetView());
179
180 // Request a pointer lock on the root frame's body.
181 EXPECT_TRUE(ExecuteScript(root, "document.body.requestPointerLock()"));
182
183 // Root frame should have been granted pointer lock.
184 bool locked = false;
185 EXPECT_TRUE(ExecuteScriptAndExtractBool(root,
186 "window.domAutomationController.send("
187 "document.pointerLockElement == "
188 "document.body);",
189 &locked));
190 EXPECT_TRUE(locked);
191
192 // Add a mouse move event listener to the root frame.
193 EXPECT_TRUE(ExecuteScript(
194 root,
195 "var x; var y; var mX; var mY; document.addEventListener('mousemove', "
196 "function(e) {x = e.x; y = e.y; mX = e.movementX; mY = e.movementY;});"));
197
198 blink::WebMouseEvent mouse_event(blink::WebInputEvent::MouseMove,
199 blink::WebInputEvent::NoModifiers,
200 blink::WebInputEvent::TimeStampForTesting);
201 mouse_event.x = 10;
202 mouse_event.y = 11;
203 mouse_event.movementX = 12;
204 mouse_event.movementY = 13;
205 router->RouteMouseEvent(root_view, &mouse_event, ui::LatencyInfo());
206
207 // Make sure that the renderer handled the input event.
208 MainThreadFrameObserver root_observer(root_view->GetRenderWidgetHost());
209 root_observer.Wait();
210
211 int x, y, movementX, movementY;
212 EXPECT_TRUE(ExecuteScriptAndExtractInt(
213 root, "window.domAutomationController.send(x);", &x));
214 EXPECT_TRUE(ExecuteScriptAndExtractInt(
215 root, "window.domAutomationController.send(y);", &y));
216 EXPECT_TRUE(ExecuteScriptAndExtractInt(
217 root, "window.domAutomationController.send(mX);", &movementX));
218 EXPECT_TRUE(ExecuteScriptAndExtractInt(
219 root, "window.domAutomationController.send(mY);", &movementY));
220 EXPECT_EQ(10, x);
221 EXPECT_EQ(11, y);
222 EXPECT_EQ(12, movementX);
223 EXPECT_EQ(13, movementY);
224
225 // Release pointer lock on root frame.
226 EXPECT_TRUE(ExecuteScript(root, "document.exitPointerLock()"));
227
228 // Request a pointer lock on the child frame's body.
229 EXPECT_TRUE(ExecuteScript(child, "document.body.requestPointerLock()"));
230
231 // Child frame should have been granted pointer lock.
232 EXPECT_TRUE(ExecuteScriptAndExtractBool(child,
233 "window.domAutomationController.send("
234 "document.pointerLockElement == "
235 "document.body);",
236 &locked));
237 EXPECT_TRUE(locked);
238
239 // Add a mouse move event listener to the child frame.
240 EXPECT_TRUE(ExecuteScript(
241 child,
242 "var x; var y; var mX; var mY; document.addEventListener('mousemove', "
243 "function(e) {x = e.x; y = e.y; mX = e.movementX; mY = e.movementY;});"));
244
245 gfx::Point transformed_point;
246 root_view->TransformPointToCoordSpaceForView(gfx::Point(0, 0), child_view,
247 &transformed_point);
248
249 mouse_event.x = -transformed_point.x() + 14;
250 mouse_event.y = -transformed_point.y() + 15;
251 mouse_event.movementX = 16;
252 mouse_event.movementY = 17;
253 // We use root_view intentionally as the RenderWidgetHostInputEventRouter is
254 // responsible for correctly routing the event to the child frame.
255 router->RouteMouseEvent(root_view, &mouse_event, ui::LatencyInfo());
256
257 // Make sure that the renderer handled the input event.
258 MainThreadFrameObserver child_observer(child_view->GetRenderWidgetHost());
259 child_observer.Wait();
260
261 EXPECT_TRUE(ExecuteScriptAndExtractInt(
262 child, "window.domAutomationController.send(x);", &x));
263 EXPECT_TRUE(ExecuteScriptAndExtractInt(
264 child, "window.domAutomationController.send(y);", &y));
265 EXPECT_TRUE(ExecuteScriptAndExtractInt(
266 child, "window.domAutomationController.send(mX);", &movementX));
267 EXPECT_TRUE(ExecuteScriptAndExtractInt(
268 child, "window.domAutomationController.send(mY);", &movementY));
269 EXPECT_EQ(14, x);
270 EXPECT_EQ(15, y);
271 EXPECT_EQ(16, movementX);
272 EXPECT_EQ(17, movementY);
273 }
274
275 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/pointer_lock_browsertest.h ('k') | content/browser/pointer_lock_browsertest_mac.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698