Chromium Code Reviews| Index: content/browser/site_per_process_browsertest.cc |
| diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc |
| index c8fa716929efe53b4a79d82206f6b7027f69d236..754a60e119883a5c6494cf9cc7bf06f90442cb4b 100644 |
| --- a/content/browser/site_per_process_browsertest.cc |
| +++ b/content/browser/site_per_process_browsertest.cc |
| @@ -20,6 +20,10 @@ |
| #include "base/test/test_timeouts.h" |
| #include "base/thread_task_runner_handle.h" |
| #include "build/build_config.h" |
| +#include "cc/surfaces/surface.h" |
| +#include "cc/surfaces/surface_manager.h" |
| +#include "content/browser/compositor/delegated_frame_host.h" |
| +#include "content/browser/compositor/surface_utils.h" |
| #include "content/browser/frame_host/cross_process_frame_connector.h" |
| #include "content/browser/frame_host/frame_tree.h" |
| #include "content/browser/frame_host/navigator.h" |
| @@ -51,7 +55,12 @@ |
| #include "third_party/WebKit/public/web/WebSandboxFlags.h" |
| #include "ui/gfx/switches.h" |
| +#if defined(USE_AURA) |
| +#include "content/browser/renderer_host/render_widget_host_view_aura.h" |
| +#endif |
| + |
| #if defined(OS_MACOSX) |
| +#include "content/browser/renderer_host/render_widget_host_view_mac.h" |
| #include "ui/base/test/scoped_preferred_scroller_style_legacy_mac.h" |
| #endif |
| @@ -161,6 +170,76 @@ class RenderWidgetHostMouseEventMonitor { |
| DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostMouseEventMonitor); |
| }; |
| +// Helper class to assist with hit testing surfaces in multiple processes. |
| +// WaitForSurfaceReady() will only return after a Surface from |target_view| |
| +// has been composited in the top-level frame's Surface. At that point, |
| +// browser process hit testing to target_view's Surface can succeed. |
| +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.
|
| + public: |
| + SurfaceHitTestReadyNotifier(RenderWidgetHostViewChildFrame* target_view) |
| + : target_view_(target_view) { |
| + surface_manager_ = GetSurfaceManager(); |
| + } |
| + ~SurfaceHitTestReadyNotifier() {} |
| + |
| + void WaitForSurfaceReady() { |
| + root_surface_id_ = getRootSurfaceId(); |
| + if (containsSurfaceId()) |
| + return; |
| + |
| + while (true) { |
| + // TODO(kenrb): Need a better way to do this. If |
| + // RenderWidgetHostViewBase lifetime observer lands (see |
| + // https://codereview.chromium.org/1711103002/), we can add a callback |
| + // from OnSwapCompositorFrame and avoid this busy waiting, which is very |
| + // frequent in tests in this file. |
| + base::RunLoop run_loop; |
| + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| + FROM_HERE, run_loop.QuitClosure(), |
| + base::TimeDelta::FromMilliseconds(10)); |
|
nasko
2016/02/26 18:33:51
TestTimeouts::tiny_timeout()?
kenrb
2016/02/26 21:33:19
Done.
|
| + run_loop.Run(); |
| + if (containsSurfaceId()) |
| + break; |
| + } |
| + } |
| + |
| + private: |
| + bool containsSurfaceId() { |
|
nasko
2016/02/26 18:33:51
ContainsSurfaceId
kenrb
2016/02/26 21:33:18
Done.
|
| + if (root_surface_id_.is_null()) |
| + return false; |
| + for (cc::SurfaceId id : surface_manager_->GetSurfaceForId(root_surface_id_) |
| + ->referenced_surfaces()) { |
| + if (id == target_view_->SurfaceIdForTesting()) |
| + return true; |
| + } |
| + return false; |
| + } |
| + |
| + 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.
|
| +#if defined(OS_MACOSX) |
| + RenderWidgetHostViewMac* root_view = static_cast<RenderWidgetHostViewMac*>( |
| + target_view_->FrameConnectorForTesting() |
| + ->GetRootRenderWidgetHostViewForTesting()); |
| + return root_view->delegated_frame_host_->SurfaceIdForTesting(); |
| +#elif defined(USE_AURA) |
| + RenderWidgetHostViewAura* root_view = |
| + static_cast<RenderWidgetHostViewAura*>( |
| + target_view_->FrameConnectorForTesting() |
| + ->GetRootRenderWidgetHostViewForTesting()); |
| + return root_view->GetDelegatedFrameHostForTesting()->SurfaceIdForTesting(); |
| +#else |
| + return cc::SurfaceId(); |
| +#endif |
| + } |
| + |
| + cc::SurfaceManager* surface_manager_; |
| + cc::SurfaceId root_surface_id_; |
| + RenderWidgetHostViewChildFrame* target_view_; |
| + base::Closure quit_; |
|
nasko
2016/02/26 18:33:51
Unused?
kenrb
2016/02/26 21:33:18
Done.
|
| + |
| + DISALLOW_COPY_AND_ASSIGN(SurfaceHitTestReadyNotifier); |
| +}; |
| + |
| // Helper function that performs a surface hittest. |
| void SurfaceHitTestTestHelper( |
| Shell* shell, |
| @@ -196,20 +275,6 @@ void SurfaceHitTestTestHelper( |
| RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>( |
| child_node->current_frame_host()->GetRenderWidgetHost()->GetView()); |
| - // We need to wait for a compositor frame from the child frame, at which |
| - // point its surface will be created. |
| - while (rwhv_child->RendererFrameNumber() <= 0) { |
| - // TODO(lazyboy): Find a better way to avoid sleeping like this. See |
| - // http://crbug.com/405282 for details. |
| - base::RunLoop run_loop; |
| - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| - FROM_HERE, run_loop.QuitClosure(), |
| - base::TimeDelta::FromMilliseconds(10)); |
| - run_loop.Run(); |
| - } |
| - |
| - uint32_t cur_render_frame_number = root_view->RendererFrameNumber(); |
| - |
| // Target input event to child frame. |
| blink::WebMouseEvent child_event; |
| child_event.type = blink::WebInputEvent::MouseDown; |
| @@ -221,31 +286,9 @@ void SurfaceHitTestTestHelper( |
| child_frame_monitor.ResetEventReceived(); |
| router->RouteMouseEvent(root_view, &child_event); |
| - while (!child_frame_monitor.EventWasReceived()) { |
| - // This is working around a big synchronization problem. It is very |
| - // difficult to know if we have received a compositor frame from the |
| - // main frame renderer *after* it received the child frame's surface |
| - // ID. Hit testing won't work until this happens. So if the hit test |
| - // fails then we wait for another frame to arrive and try again. |
| - // TODO(kenrb): We need a better way to do all of this, possibly coming |
| - // from http://crbug.com/405282. |
| - while (root_view->RendererFrameNumber() <= cur_render_frame_number) { |
| - base::RunLoop run_loop; |
| - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| - FROM_HERE, run_loop.QuitClosure(), |
| - base::TimeDelta::FromMilliseconds(10)); |
| - run_loop.Run(); |
| - } |
| - cur_render_frame_number = root_view->RendererFrameNumber(); |
| - child_event.type = blink::WebInputEvent::MouseDown; |
| - child_event.button = blink::WebPointerProperties::ButtonLeft; |
| - child_event.x = 75; |
| - child_event.y = 75; |
| - child_event.clickCount = 1; |
| - main_frame_monitor.ResetEventReceived(); |
| - child_frame_monitor.ResetEventReceived(); |
| - router->RouteMouseEvent(root_view, &child_event); |
| - } |
| + SurfaceHitTestReadyNotifier notifier( |
| + static_cast<RenderWidgetHostViewChildFrame*>(rwhv_child)); |
| + notifier.WaitForSurfaceReady(); |
| EXPECT_TRUE(child_frame_monitor.EventWasReceived()); |
| EXPECT_EQ(23, child_frame_monitor.event().x); |
| @@ -823,17 +866,9 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, |
| RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>( |
| child_node->current_frame_host()->GetRenderWidgetHost()->GetView()); |
| - // We need to wait for a compositor frame from the child frame, at which |
| - // point its surface will be created. |
| - while (rwhv_child->RendererFrameNumber() <= 0) { |
| - // TODO(lazyboy): Find a better way to avoid sleeping like this. See |
| - // http://crbug.com/405282 for details. |
| - base::RunLoop run_loop; |
| - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| - FROM_HERE, run_loop.QuitClosure(), |
| - base::TimeDelta::FromMilliseconds(10)); |
| - run_loop.Run(); |
| - } |
| + SurfaceHitTestReadyNotifier notifier( |
| + static_cast<RenderWidgetHostViewChildFrame*>(rwhv_child)); |
| + notifier.WaitForSurfaceReady(); |
| // Target input event to child frame. |
| blink::WebMouseEvent child_event; |