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

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

Issue 1734403003: Add helper class for tests using browser process hit testing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_aura.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/browser/site_per_process_browsertest.h" 5 #include "content/browser/site_per_process_browsertest.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/location.h" 14 #include "base/location.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/single_thread_task_runner.h" 16 #include "base/single_thread_task_runner.h"
17 #include "base/strings/pattern.h" 17 #include "base/strings/pattern.h"
18 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
19 #include "base/strings/utf_string_conversions.h" 19 #include "base/strings/utf_string_conversions.h"
20 #include "base/test/test_timeouts.h" 20 #include "base/test/test_timeouts.h"
21 #include "base/thread_task_runner_handle.h" 21 #include "base/thread_task_runner_handle.h"
22 #include "build/build_config.h" 22 #include "build/build_config.h"
23 #include "cc/surfaces/surface.h"
24 #include "cc/surfaces/surface_manager.h"
25 #include "content/browser/compositor/delegated_frame_host.h"
26 #include "content/browser/compositor/surface_utils.h"
23 #include "content/browser/frame_host/cross_process_frame_connector.h" 27 #include "content/browser/frame_host/cross_process_frame_connector.h"
24 #include "content/browser/frame_host/frame_tree.h" 28 #include "content/browser/frame_host/frame_tree.h"
25 #include "content/browser/frame_host/navigator.h" 29 #include "content/browser/frame_host/navigator.h"
26 #include "content/browser/frame_host/render_frame_proxy_host.h" 30 #include "content/browser/frame_host/render_frame_proxy_host.h"
27 #include "content/browser/frame_host/render_widget_host_view_child_frame.h" 31 #include "content/browser/frame_host/render_widget_host_view_child_frame.h"
28 #include "content/browser/gpu/compositor_util.h" 32 #include "content/browser/gpu/compositor_util.h"
29 #include "content/browser/renderer_host/render_view_host_impl.h" 33 #include "content/browser/renderer_host/render_view_host_impl.h"
30 #include "content/browser/renderer_host/render_widget_host_input_event_router.h" 34 #include "content/browser/renderer_host/render_widget_host_input_event_router.h"
31 #include "content/browser/web_contents/web_contents_impl.h" 35 #include "content/browser/web_contents/web_contents_impl.h"
32 #include "content/common/frame_messages.h" 36 #include "content/common/frame_messages.h"
(...skipping 11 matching lines...) Expand all
44 #include "content/shell/browser/shell.h" 48 #include "content/shell/browser/shell.h"
45 #include "content/test/content_browser_test_utils_internal.h" 49 #include "content/test/content_browser_test_utils_internal.h"
46 #include "content/test/test_frame_navigation_observer.h" 50 #include "content/test/test_frame_navigation_observer.h"
47 #include "ipc/ipc_security_test_util.h" 51 #include "ipc/ipc_security_test_util.h"
48 #include "net/dns/mock_host_resolver.h" 52 #include "net/dns/mock_host_resolver.h"
49 #include "net/test/embedded_test_server/embedded_test_server.h" 53 #include "net/test/embedded_test_server/embedded_test_server.h"
50 #include "third_party/WebKit/public/web/WebInputEvent.h" 54 #include "third_party/WebKit/public/web/WebInputEvent.h"
51 #include "third_party/WebKit/public/web/WebSandboxFlags.h" 55 #include "third_party/WebKit/public/web/WebSandboxFlags.h"
52 #include "ui/gfx/switches.h" 56 #include "ui/gfx/switches.h"
53 57
58 #if defined(USE_AURA)
59 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
60 #endif
61
54 #if defined(OS_MACOSX) 62 #if defined(OS_MACOSX)
63 #include "content/browser/renderer_host/render_widget_host_view_mac.h"
55 #include "ui/base/test/scoped_preferred_scroller_style_legacy_mac.h" 64 #include "ui/base/test/scoped_preferred_scroller_style_legacy_mac.h"
56 #endif 65 #endif
57 66
58 namespace content { 67 namespace content {
59 68
60 namespace { 69 namespace {
61 70
62 // Helper function to send a postMessage and wait for a reply message. The 71 // Helper function to send a postMessage and wait for a reply message. The
63 // |post_message_script| is executed on the |sender_ftn| frame, and the sender 72 // |post_message_script| is executed on the |sender_ftn| frame, and the sender
64 // frame is expected to post |reply_status| from the DOMAutomationController 73 // frame is expected to post |reply_status| from the DOMAutomationController
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 event_ = event; 163 event_ = event;
155 return false; 164 return false;
156 } 165 }
157 RenderWidgetHost* host_; 166 RenderWidgetHost* host_;
158 bool event_received_; 167 bool event_received_;
159 blink::WebMouseEvent event_; 168 blink::WebMouseEvent event_;
160 169
161 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostMouseEventMonitor); 170 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostMouseEventMonitor);
162 }; 171 };
163 172
173 // Helper class to assist with hit testing surfaces in multiple processes.
174 // WaitForSurfaceReady() will only return after a Surface from |target_view|
175 // has been composited in the top-level frame's Surface. At that point,
176 // browser process hit testing to target_view's Surface can succeed.
177 class SurfaceHitTestReadyNotifier {
nasko 2016/02/26 18:33:51 nit: Shouldn't this be in content_browser_test_uti
kenrb 2016/02/26 21:33:19 Done.
178 public:
179 SurfaceHitTestReadyNotifier(RenderWidgetHostViewChildFrame* target_view)
180 : target_view_(target_view) {
181 surface_manager_ = GetSurfaceManager();
182 }
183 ~SurfaceHitTestReadyNotifier() {}
184
185 void WaitForSurfaceReady() {
186 root_surface_id_ = getRootSurfaceId();
187 if (containsSurfaceId())
188 return;
189
190 while (true) {
191 // TODO(kenrb): Need a better way to do this. If
192 // RenderWidgetHostViewBase lifetime observer lands (see
193 // https://codereview.chromium.org/1711103002/), we can add a callback
194 // from OnSwapCompositorFrame and avoid this busy waiting, which is very
195 // frequent in tests in this file.
196 base::RunLoop run_loop;
197 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
198 FROM_HERE, run_loop.QuitClosure(),
199 base::TimeDelta::FromMilliseconds(10));
nasko 2016/02/26 18:33:51 TestTimeouts::tiny_timeout()?
kenrb 2016/02/26 21:33:19 Done.
200 run_loop.Run();
201 if (containsSurfaceId())
202 break;
203 }
204 }
205
206 private:
207 bool containsSurfaceId() {
nasko 2016/02/26 18:33:51 ContainsSurfaceId
kenrb 2016/02/26 21:33:18 Done.
208 if (root_surface_id_.is_null())
209 return false;
210 for (cc::SurfaceId id : surface_manager_->GetSurfaceForId(root_surface_id_)
211 ->referenced_surfaces()) {
212 if (id == target_view_->SurfaceIdForTesting())
213 return true;
214 }
215 return false;
216 }
217
218 cc::SurfaceId getRootSurfaceId() {
nasko 2016/02/26 18:33:51 GetRootSurfaceId
kenrb 2016/02/26 21:33:19 This method is removed as part of the refactor.
219 #if defined(OS_MACOSX)
220 RenderWidgetHostViewMac* root_view = static_cast<RenderWidgetHostViewMac*>(
221 target_view_->FrameConnectorForTesting()
222 ->GetRootRenderWidgetHostViewForTesting());
223 return root_view->delegated_frame_host_->SurfaceIdForTesting();
224 #elif defined(USE_AURA)
225 RenderWidgetHostViewAura* root_view =
226 static_cast<RenderWidgetHostViewAura*>(
227 target_view_->FrameConnectorForTesting()
228 ->GetRootRenderWidgetHostViewForTesting());
229 return root_view->GetDelegatedFrameHostForTesting()->SurfaceIdForTesting();
230 #else
231 return cc::SurfaceId();
232 #endif
233 }
234
235 cc::SurfaceManager* surface_manager_;
236 cc::SurfaceId root_surface_id_;
237 RenderWidgetHostViewChildFrame* target_view_;
238 base::Closure quit_;
nasko 2016/02/26 18:33:51 Unused?
kenrb 2016/02/26 21:33:18 Done.
239
240 DISALLOW_COPY_AND_ASSIGN(SurfaceHitTestReadyNotifier);
241 };
242
164 // Helper function that performs a surface hittest. 243 // Helper function that performs a surface hittest.
165 void SurfaceHitTestTestHelper( 244 void SurfaceHitTestTestHelper(
166 Shell* shell, 245 Shell* shell,
167 net::test_server::EmbeddedTestServer* embedded_test_server) { 246 net::test_server::EmbeddedTestServer* embedded_test_server) {
168 GURL main_url(embedded_test_server->GetURL( 247 GURL main_url(embedded_test_server->GetURL(
169 "/frame_tree/page_with_positioned_frame.html")); 248 "/frame_tree/page_with_positioned_frame.html"));
170 NavigateToURL(shell, main_url); 249 NavigateToURL(shell, main_url);
171 250
172 // It is safe to obtain the root frame tree node here, as it doesn't change. 251 // It is safe to obtain the root frame tree node here, as it doesn't change.
173 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell->web_contents()) 252 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell->web_contents())
(...skipping 15 matching lines...) Expand all
189 268
190 RenderWidgetHostInputEventRouter* router = 269 RenderWidgetHostInputEventRouter* router =
191 static_cast<WebContentsImpl*>(shell->web_contents()) 270 static_cast<WebContentsImpl*>(shell->web_contents())
192 ->GetInputEventRouter(); 271 ->GetInputEventRouter();
193 272
194 RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>( 273 RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>(
195 root->current_frame_host()->GetRenderWidgetHost()->GetView()); 274 root->current_frame_host()->GetRenderWidgetHost()->GetView());
196 RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>( 275 RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>(
197 child_node->current_frame_host()->GetRenderWidgetHost()->GetView()); 276 child_node->current_frame_host()->GetRenderWidgetHost()->GetView());
198 277
199 // We need to wait for a compositor frame from the child frame, at which
200 // point its surface will be created.
201 while (rwhv_child->RendererFrameNumber() <= 0) {
202 // TODO(lazyboy): Find a better way to avoid sleeping like this. See
203 // http://crbug.com/405282 for details.
204 base::RunLoop run_loop;
205 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
206 FROM_HERE, run_loop.QuitClosure(),
207 base::TimeDelta::FromMilliseconds(10));
208 run_loop.Run();
209 }
210
211 uint32_t cur_render_frame_number = root_view->RendererFrameNumber();
212
213 // Target input event to child frame. 278 // Target input event to child frame.
214 blink::WebMouseEvent child_event; 279 blink::WebMouseEvent child_event;
215 child_event.type = blink::WebInputEvent::MouseDown; 280 child_event.type = blink::WebInputEvent::MouseDown;
216 child_event.button = blink::WebPointerProperties::ButtonLeft; 281 child_event.button = blink::WebPointerProperties::ButtonLeft;
217 child_event.x = 75; 282 child_event.x = 75;
218 child_event.y = 75; 283 child_event.y = 75;
219 child_event.clickCount = 1; 284 child_event.clickCount = 1;
220 main_frame_monitor.ResetEventReceived(); 285 main_frame_monitor.ResetEventReceived();
221 child_frame_monitor.ResetEventReceived(); 286 child_frame_monitor.ResetEventReceived();
222 router->RouteMouseEvent(root_view, &child_event); 287 router->RouteMouseEvent(root_view, &child_event);
223 288
224 while (!child_frame_monitor.EventWasReceived()) { 289 SurfaceHitTestReadyNotifier notifier(
225 // This is working around a big synchronization problem. It is very 290 static_cast<RenderWidgetHostViewChildFrame*>(rwhv_child));
226 // difficult to know if we have received a compositor frame from the 291 notifier.WaitForSurfaceReady();
227 // main frame renderer *after* it received the child frame's surface
228 // ID. Hit testing won't work until this happens. So if the hit test
229 // fails then we wait for another frame to arrive and try again.
230 // TODO(kenrb): We need a better way to do all of this, possibly coming
231 // from http://crbug.com/405282.
232 while (root_view->RendererFrameNumber() <= cur_render_frame_number) {
233 base::RunLoop run_loop;
234 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
235 FROM_HERE, run_loop.QuitClosure(),
236 base::TimeDelta::FromMilliseconds(10));
237 run_loop.Run();
238 }
239 cur_render_frame_number = root_view->RendererFrameNumber();
240 child_event.type = blink::WebInputEvent::MouseDown;
241 child_event.button = blink::WebPointerProperties::ButtonLeft;
242 child_event.x = 75;
243 child_event.y = 75;
244 child_event.clickCount = 1;
245 main_frame_monitor.ResetEventReceived();
246 child_frame_monitor.ResetEventReceived();
247 router->RouteMouseEvent(root_view, &child_event);
248 }
249 292
250 EXPECT_TRUE(child_frame_monitor.EventWasReceived()); 293 EXPECT_TRUE(child_frame_monitor.EventWasReceived());
251 EXPECT_EQ(23, child_frame_monitor.event().x); 294 EXPECT_EQ(23, child_frame_monitor.event().x);
252 EXPECT_EQ(23, child_frame_monitor.event().y); 295 EXPECT_EQ(23, child_frame_monitor.event().y);
253 EXPECT_FALSE(main_frame_monitor.EventWasReceived()); 296 EXPECT_FALSE(main_frame_monitor.EventWasReceived());
254 297
255 child_frame_monitor.ResetEventReceived(); 298 child_frame_monitor.ResetEventReceived();
256 main_frame_monitor.ResetEventReceived(); 299 main_frame_monitor.ResetEventReceived();
257 300
258 // Target input event to main frame. 301 // Target input event to main frame.
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 859
817 RenderWidgetHostInputEventRouter* router = 860 RenderWidgetHostInputEventRouter* router =
818 static_cast<WebContentsImpl*>(shell()->web_contents()) 861 static_cast<WebContentsImpl*>(shell()->web_contents())
819 ->GetInputEventRouter(); 862 ->GetInputEventRouter();
820 863
821 RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>( 864 RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>(
822 root->current_frame_host()->GetRenderWidgetHost()->GetView()); 865 root->current_frame_host()->GetRenderWidgetHost()->GetView());
823 RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>( 866 RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>(
824 child_node->current_frame_host()->GetRenderWidgetHost()->GetView()); 867 child_node->current_frame_host()->GetRenderWidgetHost()->GetView());
825 868
826 // We need to wait for a compositor frame from the child frame, at which 869 SurfaceHitTestReadyNotifier notifier(
827 // point its surface will be created. 870 static_cast<RenderWidgetHostViewChildFrame*>(rwhv_child));
828 while (rwhv_child->RendererFrameNumber() <= 0) { 871 notifier.WaitForSurfaceReady();
829 // TODO(lazyboy): Find a better way to avoid sleeping like this. See
830 // http://crbug.com/405282 for details.
831 base::RunLoop run_loop;
832 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
833 FROM_HERE, run_loop.QuitClosure(),
834 base::TimeDelta::FromMilliseconds(10));
835 run_loop.Run();
836 }
837 872
838 // Target input event to child frame. 873 // Target input event to child frame.
839 blink::WebMouseEvent child_event; 874 blink::WebMouseEvent child_event;
840 child_event.type = blink::WebInputEvent::MouseDown; 875 child_event.type = blink::WebInputEvent::MouseDown;
841 child_event.button = blink::WebPointerProperties::ButtonLeft; 876 child_event.button = blink::WebPointerProperties::ButtonLeft;
842 child_event.x = 75; 877 child_event.x = 75;
843 child_event.y = 75; 878 child_event.y = 75;
844 child_event.clickCount = 1; 879 child_event.clickCount = 1;
845 main_frame_monitor.ResetEventReceived(); 880 main_frame_monitor.ResetEventReceived();
846 child_frame_monitor.ResetEventReceived(); 881 child_frame_monitor.ResetEventReceived();
(...skipping 4403 matching lines...) Expand 10 before | Expand all | Expand 10 after
5250 5285
5251 // Force the renderer to generate a new frame. 5286 // Force the renderer to generate a new frame.
5252 EXPECT_TRUE(ExecuteScript(shell()->web_contents(), 5287 EXPECT_TRUE(ExecuteScript(shell()->web_contents(),
5253 "document.body.style.background = 'black'")); 5288 "document.body.style.background = 'black'"));
5254 5289
5255 // Waits for the next frame. 5290 // Waits for the next frame.
5256 observer->Wait(); 5291 observer->Wait();
5257 } 5292 }
5258 5293
5259 } // namespace content 5294 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_aura.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698