| 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 dadfadfe816da806aff45e8844aa067de69afaae..70ebdf567d7c9424db1d6048bc0637c47cf0287c 100644
|
| --- a/content/browser/site_per_process_browsertest.cc
|
| +++ b/content/browser/site_per_process_browsertest.cc
|
| @@ -5429,12 +5429,156 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, OpenerSetLocation) {
|
| EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), cross_url);
|
| }
|
|
|
| -// Ensure that a cross-process subframe with a touch-handler can receive touch
|
| -// events.
|
| #if defined(USE_AURA)
|
| -// Browser process hit testing is not implemented on Android, and this test
|
| -// requires Aura for RenderWidgetHostViewAura::OnTouchEvent().
|
| +// Browser process hit testing is not implemented on Android, and these tests
|
| +// require Aura for RenderWidgetHostViewAura::OnTouchEvent().
|
| // https://crbug.com/491334
|
| +
|
| +// Ensure that scroll events can be cancelled with a wheel handler.
|
| +// https://crbug.com/698195
|
| +
|
| +class SitePerProcessMouseWheelBrowserTest : public SitePerProcessBrowserTest {
|
| + public:
|
| + SitePerProcessMouseWheelBrowserTest() : rwhv_root_(nullptr) {}
|
| +
|
| + void SetupWheelAndScrollHandlers(content::RenderFrameHostImpl* rfh) {
|
| + // Set up event handlers. The wheel event handler calls prevent default on
|
| + // alternate events, so only every other wheel generates a scroll. The fact
|
| + // that any scroll events fire is dependent on the event going to the main
|
| + // thread, which requires the nonFastScrollableRegion be set correctly
|
| + // on the compositor.
|
| + std::string script =
|
| + "wheel_count = 0;"
|
| + "function wheel_handler(e) {"
|
| + " wheel_count++;"
|
| + " if (wheel_count % 2 == 0)"
|
| + " e.preventDefault();\n"
|
| + " domAutomationController.setAutomationId(0);"
|
| + " domAutomationController.send('wheel: ' + wheel_count);"
|
| + "}"
|
| + "function scroll_handler(e) {"
|
| + " domAutomationController.setAutomationId(0);"
|
| + " domAutomationController.send('scroll: ' + wheel_count);"
|
| + "}"
|
| + "scroll_div = document.getElementById('scrollable_div');"
|
| + "scroll_div.addEventListener('wheel', wheel_handler);"
|
| + "scroll_div.addEventListener('scroll', scroll_handler);"
|
| + "domAutomationController.setAutomationId(0);"
|
| + "domAutomationController.send('wheel handler installed');"
|
| + "document.body.style.background = 'black';";
|
| +
|
| + content::DOMMessageQueue msg_queue;
|
| + std::string reply;
|
| + EXPECT_TRUE(ExecuteScript(rfh, script));
|
| +
|
| + // Wait until renderer's compositor thread is synced. Otherwise the event
|
| + // handler won't be installed when the event arrives.
|
| + {
|
| + MainThreadFrameObserver observer(rfh->GetRenderWidgetHost());
|
| + observer.Wait();
|
| + }
|
| + }
|
| +
|
| + void SendMouseWheel(gfx::Point location) {
|
| + DCHECK(rwhv_root_);
|
| + ui::ScrollEvent scroll_event(ui::ET_SCROLL, location, ui::EventTimeForNow(),
|
| + 0, 0, -ui::MouseWheelEvent::kWheelDelta, 0,
|
| + ui::MouseWheelEvent::kWheelDelta,
|
| + 2); // This must be '2' or it gets silently
|
| + // dropped.
|
| + rwhv_root_->OnScrollEvent(&scroll_event);
|
| + }
|
| +
|
| + void set_rwhv_root(RenderWidgetHostViewAura* rwhv_root) {
|
| + rwhv_root_ = rwhv_root;
|
| + }
|
| +
|
| + void RunTest(gfx::Point pos) {
|
| + content::DOMMessageQueue msg_queue;
|
| + std::string reply;
|
| +
|
| + auto* rwhv_root = static_cast<RenderWidgetHostViewAura*>(
|
| + web_contents()->GetRenderWidgetHostView());
|
| + set_rwhv_root(rwhv_root);
|
| +
|
| + SendMouseWheel(pos);
|
| +
|
| + // Expect both wheel and scroll handlers to fire.
|
| + EXPECT_TRUE(msg_queue.WaitForMessage(&reply));
|
| + EXPECT_EQ("\"wheel: 1\"", reply);
|
| + EXPECT_TRUE(msg_queue.WaitForMessage(&reply));
|
| + EXPECT_EQ("\"scroll: 1\"", reply);
|
| +
|
| + SendMouseWheel(pos);
|
| +
|
| + // This time only the wheel handler fires, since it prevent defaults on
|
| + // even numbered scrolls.
|
| + EXPECT_TRUE(msg_queue.WaitForMessage(&reply));
|
| + EXPECT_EQ("\"wheel: 2\"", reply);
|
| +
|
| + SendMouseWheel(pos);
|
| +
|
| + // Odd number of wheels, expect both wheel and scroll handlers to fire
|
| + // again.
|
| + EXPECT_TRUE(msg_queue.WaitForMessage(&reply));
|
| + EXPECT_EQ("\"wheel: 3\"", reply);
|
| + EXPECT_TRUE(msg_queue.WaitForMessage(&reply));
|
| + EXPECT_EQ("\"scroll: 3\"", reply);
|
| + }
|
| +
|
| + private:
|
| + RenderWidgetHostViewAura* rwhv_root_;
|
| +};
|
| +
|
| +IN_PROC_BROWSER_TEST_F(SitePerProcessMouseWheelBrowserTest,
|
| + SubframeWheelEventsOnMainThread) {
|
| + GURL main_url(embedded_test_server()->GetURL(
|
| + "/frame_tree/page_with_positioned_nested_frames.html"));
|
| + EXPECT_TRUE(NavigateToURL(shell(), main_url));
|
| +
|
| + FrameTreeNode* root = web_contents()->GetFrameTree()->root();
|
| + ASSERT_EQ(1U, root->child_count());
|
| +
|
| + GURL frame_url(embedded_test_server()->GetURL(
|
| + "b.com", "/page_with_scrollable_div.html"));
|
| + NavigateFrameToURL(root->child_at(0), frame_url);
|
| +
|
| + // Synchronize with the child and parent renderers to guarantee that the
|
| + // surface information required for event hit testing is ready.
|
| + RenderWidgetHostViewBase* child_rwhv = static_cast<RenderWidgetHostViewBase*>(
|
| + root->child_at(0)->current_frame_host()->GetView());
|
| + SurfaceHitTestReadyNotifier notifier(
|
| + static_cast<RenderWidgetHostViewChildFrame*>(child_rwhv));
|
| + notifier.WaitForSurfaceReady();
|
| +
|
| + content::RenderFrameHostImpl* child = root->child_at(0)->current_frame_host();
|
| + SetupWheelAndScrollHandlers(child);
|
| +
|
| + gfx::Rect bounds = child_rwhv->GetViewBounds();
|
| + gfx::Point pos(bounds.x() + 10, bounds.y() + 10);
|
| +
|
| + RunTest(pos);
|
| +}
|
| +
|
| +// Verifies that test in SubframeWheelEventsOnMainThread also makes sense for
|
| +// the same page loaded in the mainframe.
|
| +IN_PROC_BROWSER_TEST_F(SitePerProcessMouseWheelBrowserTest,
|
| + MainframeWheelEventsOnMainThread) {
|
| + GURL main_url(
|
| + embedded_test_server()->GetURL("/page_with_scrollable_div.html"));
|
| + EXPECT_TRUE(NavigateToURL(shell(), main_url));
|
| +
|
| + FrameTreeNode* root = web_contents()->GetFrameTree()->root();
|
| + content::RenderFrameHostImpl* rfhi = root->current_frame_host();
|
| + SetupWheelAndScrollHandlers(rfhi);
|
| +
|
| + gfx::Point pos(10, 10);
|
| +
|
| + RunTest(pos);
|
| +}
|
| +
|
| +// Ensure that a cross-process subframe with a touch-handler can receive touch
|
| +// events.
|
| IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
|
| SubframeTouchEventRouting) {
|
| GURL main_url(embedded_test_server()->GetURL(
|
|
|