| OLD | NEW |
| 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 "content/browser/frame_host/cross_process_frame_connector.h" | 23 #include "content/browser/frame_host/cross_process_frame_connector.h" |
| 24 #include "content/browser/frame_host/frame_tree.h" | 24 #include "content/browser/frame_host/frame_tree.h" |
| 25 #include "content/browser/frame_host/navigator.h" | 25 #include "content/browser/frame_host/navigator.h" |
| 26 #include "content/browser/frame_host/render_frame_proxy_host.h" | 26 #include "content/browser/frame_host/render_frame_proxy_host.h" |
| 27 #include "content/browser/frame_host/render_widget_host_view_child_frame.h" | 27 #include "content/browser/frame_host/render_widget_host_view_child_frame.h" |
| 28 #include "content/browser/gpu/compositor_util.h" | 28 #include "content/browser/gpu/compositor_util.h" |
| 29 #include "content/browser/renderer_host/input/synthetic_tap_gesture.h" |
| 29 #include "content/browser/renderer_host/render_view_host_impl.h" | 30 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 30 #include "content/browser/renderer_host/render_widget_host_input_event_router.h" | 31 #include "content/browser/renderer_host/render_widget_host_input_event_router.h" |
| 32 #include "content/browser/renderer_host/render_widget_host_view_aura.h" |
| 31 #include "content/browser/web_contents/web_contents_impl.h" | 33 #include "content/browser/web_contents/web_contents_impl.h" |
| 32 #include "content/common/frame_messages.h" | 34 #include "content/common/frame_messages.h" |
| 35 #include "content/common/input/synthetic_tap_gesture_params.h" |
| 33 #include "content/common/view_messages.h" | 36 #include "content/common/view_messages.h" |
| 34 #include "content/public/browser/notification_observer.h" | 37 #include "content/public/browser/notification_observer.h" |
| 35 #include "content/public/browser/notification_service.h" | 38 #include "content/public/browser/notification_service.h" |
| 36 #include "content/public/browser/notification_types.h" | 39 #include "content/public/browser/notification_types.h" |
| 37 #include "content/public/browser/resource_dispatcher_host.h" | 40 #include "content/public/browser/resource_dispatcher_host.h" |
| 38 #include "content/public/common/browser_side_navigation_policy.h" | 41 #include "content/public/common/browser_side_navigation_policy.h" |
| 39 #include "content/public/common/content_switches.h" | 42 #include "content/public/common/content_switches.h" |
| 40 #include "content/public/test/browser_test_utils.h" | 43 #include "content/public/test/browser_test_utils.h" |
| 41 #include "content/public/test/content_browser_test_utils.h" | 44 #include "content/public/test/content_browser_test_utils.h" |
| 42 #include "content/public/test/test_navigation_observer.h" | 45 #include "content/public/test/test_navigation_observer.h" |
| (...skipping 4524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4567 ui::EventTimeForNow(), 30.f, 30.f, 0.f, 0.f); | 4570 ui::EventTimeForNow(), 30.f, 30.f, 0.f, 0.f); |
| 4568 rwhv->OnTouchEvent(&touch_event); | 4571 rwhv->OnTouchEvent(&touch_event); |
| 4569 | 4572 |
| 4570 // Verify touch handler in subframe was invoked | 4573 // Verify touch handler in subframe was invoked |
| 4571 std::string result; | 4574 std::string result; |
| 4572 EXPECT_TRUE(ExecuteScriptAndExtractString( | 4575 EXPECT_TRUE(ExecuteScriptAndExtractString( |
| 4573 root->child_at(0)->current_frame_host(), | 4576 root->child_at(0)->current_frame_host(), |
| 4574 "window.domAutomationController.send(getLastTouchEvent());", &result)); | 4577 "window.domAutomationController.send(getLastTouchEvent());", &result)); |
| 4575 EXPECT_EQ("touchstart", result); | 4578 EXPECT_EQ("touchstart", result); |
| 4576 } | 4579 } |
| 4580 |
| 4581 namespace { |
| 4582 |
| 4583 // Declared here to be close to the SubframeGestureEventRouting test. |
| 4584 void OnSyntheticGestureCompleted(scoped_refptr<MessageLoopRunner> runner, |
| 4585 SyntheticGesture::Result result) { |
| 4586 EXPECT_EQ(SyntheticGesture::GESTURE_FINISHED, result); |
| 4587 runner->Quit(); |
| 4588 } |
| 4589 |
| 4590 } // namespace anonymous |
| 4591 |
| 4592 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, |
| 4593 SubframeGestureEventRouting) { |
| 4594 GURL main_url(embedded_test_server()->GetURL( |
| 4595 "/frame_tree/page_with_positioned_nested_frames.html")); |
| 4596 EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
| 4597 |
| 4598 WebContentsImpl* web_contents = |
| 4599 static_cast<WebContentsImpl*>(shell()->web_contents()); |
| 4600 FrameTreeNode* root = web_contents->GetFrameTree()->root(); |
| 4601 ASSERT_EQ(1U, root->child_count()); |
| 4602 |
| 4603 GURL frame_url( |
| 4604 embedded_test_server()->GetURL("b.com", "/page_with_click_handler.html")); |
| 4605 NavigateFrameToURL(root->child_at(0), frame_url); |
| 4606 auto child_frame_host = root->child_at(0)->current_frame_host(); |
| 4607 EXPECT_TRUE(WaitForRenderFrameReady(child_frame_host)); |
| 4608 |
| 4609 // Synchronize with the child and parent renderers to guarantee that the |
| 4610 // surface information required for event hit testing is ready. |
| 4611 RenderWidgetHostViewBase* child_rwhv = static_cast<RenderWidgetHostViewBase*>( |
| 4612 child_frame_host->GetView()); |
| 4613 SurfaceHitTestReadyNotifier notifier( |
| 4614 static_cast<RenderWidgetHostViewChildFrame*>(child_rwhv)); |
| 4615 notifier.WaitForSurfaceReady(); |
| 4616 |
| 4617 // There have been no GestureTaps sent yet. |
| 4618 { |
| 4619 std::string result; |
| 4620 EXPECT_TRUE(ExecuteScriptAndExtractString( |
| 4621 child_frame_host, |
| 4622 "window.domAutomationController.send(getClickStatus());", &result)); |
| 4623 EXPECT_EQ("0 clicks received", result); |
| 4624 } |
| 4625 |
| 4626 // Simulate touch sequence to send GestureTap to sub-frame. |
| 4627 SyntheticTapGestureParams params; |
| 4628 params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; |
| 4629 gfx::Point center(150, 150); |
| 4630 params.position = gfx::PointF(center.x(), center.y()); |
| 4631 params.duration_ms = 100; |
| 4632 scoped_ptr<SyntheticTapGesture> gesture(new SyntheticTapGesture(params)); |
| 4633 |
| 4634 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner(); |
| 4635 |
| 4636 RenderWidgetHostImpl* render_widget_host = |
| 4637 root->current_frame_host()->GetRenderWidgetHost(); |
| 4638 // TODO(wjmaclean): Convert the call to base::Bind() to a lambda someday. |
| 4639 render_widget_host->QueueSyntheticGesture( |
| 4640 std::move(gesture), base::Bind(OnSyntheticGestureCompleted, runner)); |
| 4641 |
| 4642 // We need to run the message loop while we wait for the synthetic gesture |
| 4643 // to be processed; the callback registered above will get us out of the |
| 4644 // message loop when that happens. |
| 4645 runner->Run(); |
| 4646 runner = nullptr; |
| 4647 |
| 4648 // Verify click handler in subframe was invoked |
| 4649 { |
| 4650 std::string result; |
| 4651 EXPECT_TRUE(ExecuteScriptAndExtractString( |
| 4652 child_frame_host, |
| 4653 "window.domAutomationController.send(getClickStatus());", &result)); |
| 4654 EXPECT_EQ("1 click received", result); |
| 4655 } |
| 4656 } |
| 4657 |
| 4658 namespace { |
| 4659 |
| 4660 // Defined here to be close to |
| 4661 // SitePerProcessBrowserTest.InputEventRouterGestureTargetQueueTest. |
| 4662 void SendTouchTapWithExpectedTarget( |
| 4663 RenderWidgetHostViewBase* root_view, |
| 4664 const gfx::Point& touch_point, |
| 4665 RenderWidgetHostViewBase*& router_touch_target, |
| 4666 const RenderWidgetHostViewBase* expected_target) { |
| 4667 auto root_view_aura = static_cast<RenderWidgetHostViewAura*>(root_view); |
| 4668 ui::TouchEvent touch_event_pressed(ui::ET_TOUCH_PRESSED, touch_point, 0, |
| 4669 0, ui::EventTimeForNow(), 30.f, 30.f, 0.f, |
| 4670 0.f); |
| 4671 root_view_aura->OnTouchEvent(&touch_event_pressed); |
| 4672 EXPECT_EQ(expected_target, router_touch_target); |
| 4673 ui::TouchEvent touch_event_released(ui::ET_TOUCH_RELEASED, touch_point, |
| 4674 0, 0, ui::EventTimeForNow(), 30.f, 30.f, |
| 4675 0.f, 0.f); |
| 4676 root_view_aura->OnTouchEvent(&touch_event_released); |
| 4677 EXPECT_EQ(nullptr, router_touch_target); |
| 4678 } |
| 4679 |
| 4680 void SendGestureTapSequenceWithExpectedTarget( |
| 4681 RenderWidgetHostViewBase* root_view, |
| 4682 gfx::Point gesture_point, |
| 4683 RenderWidgetHostViewBase*& router_gesture_target, |
| 4684 const RenderWidgetHostViewBase* old_expected_target, |
| 4685 const RenderWidgetHostViewBase* expected_target) { |
| 4686 auto root_view_aura = static_cast<RenderWidgetHostViewAura*>(root_view); |
| 4687 |
| 4688 ui::GestureEvent gesture_begin_event( |
| 4689 gesture_point.x(), gesture_point.y(), 0, ui::EventTimeForNow(), |
| 4690 ui::GestureEventDetails(ui::ET_GESTURE_BEGIN)); |
| 4691 root_view_aura->OnGestureEvent(&gesture_begin_event); |
| 4692 // We expect to still have the old gesture target in place for the |
| 4693 // GestureFlingCancel that will be inserted before GestureTapDown. |
| 4694 // Note: the GestureFlingCancel is inserted by RenderWidgetHostViewAura:: |
| 4695 // OnGestureEvent() when it sees ui::ET_GESTURE_TAP_DOWN, so we don't |
| 4696 // explicitly add it here. |
| 4697 EXPECT_EQ(old_expected_target, router_gesture_target); |
| 4698 |
| 4699 ui::GestureEvent gesture_tap_down_event( |
| 4700 gesture_point.x(), gesture_point.y(), 0, ui::EventTimeForNow(), |
| 4701 ui::GestureEventDetails(ui::ET_GESTURE_TAP_DOWN)); |
| 4702 root_view_aura->OnGestureEvent(&gesture_tap_down_event); |
| 4703 EXPECT_EQ(expected_target, router_gesture_target); |
| 4704 |
| 4705 ui::GestureEvent gesture_show_press_event( |
| 4706 gesture_point.x(), gesture_point.y(), 0, ui::EventTimeForNow(), |
| 4707 ui::GestureEventDetails(ui::ET_GESTURE_SHOW_PRESS)); |
| 4708 root_view_aura->OnGestureEvent(&gesture_show_press_event); |
| 4709 EXPECT_EQ(expected_target, router_gesture_target); |
| 4710 |
| 4711 ui::GestureEventDetails gesture_tap_details(ui::ET_GESTURE_TAP); |
| 4712 gesture_tap_details.set_tap_count(1); |
| 4713 ui::GestureEvent gesture_tap_event( |
| 4714 gesture_point.x(), gesture_point.y(), 0, ui::EventTimeForNow(), |
| 4715 gesture_tap_details); |
| 4716 root_view_aura->OnGestureEvent(&gesture_tap_event); |
| 4717 EXPECT_EQ(expected_target, router_gesture_target); |
| 4718 |
| 4719 ui::GestureEvent gesture_end_event( |
| 4720 gesture_point.x(), gesture_point.y(), 0, ui::EventTimeForNow(), |
| 4721 ui::GestureEventDetails(ui::ET_GESTURE_END)); |
| 4722 root_view_aura->OnGestureEvent(&gesture_end_event); |
| 4723 EXPECT_EQ(expected_target, router_gesture_target); |
| 4724 } |
| 4725 |
| 4726 } // namespace anonymous |
| 4727 |
| 4728 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, |
| 4729 InputEventRouterGestureTargetQueueTest) { |
| 4730 GURL main_url(embedded_test_server()->GetURL( |
| 4731 "/frame_tree/page_with_positioned_nested_frames.html")); |
| 4732 EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
| 4733 |
| 4734 WebContentsImpl* web_contents = |
| 4735 static_cast<WebContentsImpl*>(shell()->web_contents()); |
| 4736 FrameTreeNode* root = web_contents->GetFrameTree()->root(); |
| 4737 ASSERT_EQ(1U, root->child_count()); |
| 4738 |
| 4739 GURL frame_url( |
| 4740 embedded_test_server()->GetURL("b.com", "/page_with_click_handler.html")); |
| 4741 NavigateFrameToURL(root->child_at(0), frame_url); |
| 4742 auto child_frame_host = root->child_at(0)->current_frame_host(); |
| 4743 EXPECT_TRUE(WaitForRenderFrameReady(child_frame_host)); |
| 4744 |
| 4745 // Synchronize with the child and parent renderers to guarantee that the |
| 4746 // surface information required for event hit testing is ready. |
| 4747 auto rwhv_child = |
| 4748 static_cast<RenderWidgetHostViewBase*>(child_frame_host->GetView()); |
| 4749 SurfaceHitTestReadyNotifier notifier( |
| 4750 static_cast<RenderWidgetHostViewChildFrame*>(rwhv_child)); |
| 4751 notifier.WaitForSurfaceReady(); |
| 4752 |
| 4753 // All touches & gestures are sent to the main frame's view, and should be |
| 4754 // routed appropriately from there. |
| 4755 auto rwhv_parent = static_cast<RenderWidgetHostViewBase*>( |
| 4756 web_contents->GetRenderWidgetHostView()); |
| 4757 |
| 4758 RenderWidgetHostInputEventRouter* router = |
| 4759 web_contents->GetInputEventRouter(); |
| 4760 EXPECT_TRUE(router->gesture_target_queue_.empty()); |
| 4761 EXPECT_EQ(nullptr, router->gesture_target_); |
| 4762 |
| 4763 // Send touch sequence to main-frame. |
| 4764 gfx::Point main_frame_point(25, 25); |
| 4765 SendTouchTapWithExpectedTarget(rwhv_parent, main_frame_point, |
| 4766 router->touch_target_, rwhv_parent); |
| 4767 EXPECT_EQ(1LU, router->gesture_target_queue_.size()); |
| 4768 EXPECT_EQ(nullptr, router->gesture_target_); |
| 4769 |
| 4770 |
| 4771 // Send touch sequence to child. |
| 4772 gfx::Point child_center(150, 150); |
| 4773 SendTouchTapWithExpectedTarget(rwhv_parent, child_center, |
| 4774 router->touch_target_, rwhv_child); |
| 4775 EXPECT_EQ(2LU, router->gesture_target_queue_.size()); |
| 4776 EXPECT_EQ(nullptr, router->gesture_target_); |
| 4777 |
| 4778 // Send another touch sequence to main frame. |
| 4779 SendTouchTapWithExpectedTarget(rwhv_parent, main_frame_point, |
| 4780 router->touch_target_, rwhv_parent); |
| 4781 EXPECT_EQ(3LU, router->gesture_target_queue_.size()); |
| 4782 EXPECT_EQ(nullptr, router->gesture_target_); |
| 4783 |
| 4784 // Send Gestures to clear GestureTargetQueue. |
| 4785 |
| 4786 // The first touch sequence should generate a GestureTapDown, sent to the |
| 4787 // main frame. |
| 4788 SendGestureTapSequenceWithExpectedTarget(rwhv_parent, main_frame_point, |
| 4789 router->gesture_target_, nullptr, |
| 4790 rwhv_parent); |
| 4791 EXPECT_EQ(2LU, router->gesture_target_queue_.size()); |
| 4792 // Note: rwhv_parent is the target used for GestureFlingCancel sent by |
| 4793 // RenderWidgetHostViewAura::OnGestureEvent() at the start of the next gesture |
| 4794 // sequence; the sequence itself goes to rwhv_child. |
| 4795 EXPECT_EQ(rwhv_parent, router->gesture_target_); |
| 4796 |
| 4797 // The second touch sequence should generate a GestureTapDown, sent to the |
| 4798 // child frame. |
| 4799 SendGestureTapSequenceWithExpectedTarget(rwhv_parent, child_center, |
| 4800 router->gesture_target_, rwhv_parent, |
| 4801 rwhv_child); |
| 4802 EXPECT_EQ(1LU, router->gesture_target_queue_.size()); |
| 4803 EXPECT_EQ(rwhv_child, router->gesture_target_); |
| 4804 |
| 4805 // The third touch sequence should generate a GestureTapDown, sent to the |
| 4806 // main frame. |
| 4807 SendGestureTapSequenceWithExpectedTarget(rwhv_parent, main_frame_point, |
| 4808 router->gesture_target_, rwhv_child, |
| 4809 rwhv_parent); |
| 4810 EXPECT_EQ(0LU, router->gesture_target_queue_.size()); |
| 4811 EXPECT_EQ(rwhv_parent, router->gesture_target_); |
| 4812 } |
| 4577 #endif // defined(USE_AURA) | 4813 #endif // defined(USE_AURA) |
| 4578 | 4814 |
| 4579 // Ensure that a cross-process subframe can receive keyboard events when in | 4815 // Ensure that a cross-process subframe can receive keyboard events when in |
| 4580 // focus. | 4816 // focus. |
| 4581 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, | 4817 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, |
| 4582 SubframeKeyboardEventRouting) { | 4818 SubframeKeyboardEventRouting) { |
| 4583 GURL main_url(embedded_test_server()->GetURL( | 4819 GURL main_url(embedded_test_server()->GetURL( |
| 4584 "a.com", "/frame_tree/page_with_one_frame.html")); | 4820 "a.com", "/frame_tree/page_with_one_frame.html")); |
| 4585 EXPECT_TRUE(NavigateToURL(shell(), main_url)); | 4821 EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
| 4586 | 4822 |
| (...skipping 907 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5494 | 5730 |
| 5495 // Force the renderer to generate a new frame. | 5731 // Force the renderer to generate a new frame. |
| 5496 EXPECT_TRUE(ExecuteScript(shell()->web_contents(), | 5732 EXPECT_TRUE(ExecuteScript(shell()->web_contents(), |
| 5497 "document.body.style.background = 'black'")); | 5733 "document.body.style.background = 'black'")); |
| 5498 | 5734 |
| 5499 // Waits for the next frame. | 5735 // Waits for the next frame. |
| 5500 observer->Wait(); | 5736 observer->Wait(); |
| 5501 } | 5737 } |
| 5502 | 5738 |
| 5503 } // namespace content | 5739 } // namespace content |
| OLD | NEW |