Index: chrome/browser/apps/guest_view/web_view_browsertest.cc |
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc |
index ea207ce3151d6bdc17d52faa7af2ee1ee66dbd8c..d7b0fc1bff66f2bcfe972704c4ad56ac058423a3 100644 |
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc |
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc |
@@ -38,6 +38,7 @@ |
#include "content/public/browser/interstitial_page_delegate.h" |
#include "content/public/browser/notification_service.h" |
#include "content/public/browser/render_process_host.h" |
+#include "content/public/browser/render_widget_host_view.h" |
#include "content/public/browser/web_contents_delegate.h" |
#include "content/public/common/child_process_host.h" |
#include "content/public/common/content_switches.h" |
@@ -63,6 +64,7 @@ |
#include "ui/compositor/compositor.h" |
#include "ui/compositor/compositor_observer.h" |
#include "ui/events/event_switches.h" |
+#include "ui/events/gesture_detection/gesture_configuration.h" |
#include "ui/gfx/switches.h" |
#include "ui/gl/gl_switches.h" |
#include "ui/views/view.h" |
@@ -2523,6 +2525,188 @@ IN_PROC_BROWSER_TEST_F(WebViewTest, LoadWebviewAccessibleResource) { |
"web_view/load_webview_accessible_resource", NEEDS_TEST_SERVER); |
} |
+class WebViewTouchTest : public WebViewTest { |
+ protected: |
+ void SetUpCommandLine(base::CommandLine* command_line) override { |
+ command_line->AppendSwitchASCII(switches::kTouchEvents, |
+ switches::kTouchEventsEnabled); |
+ |
+ WebViewTest::SetUpCommandLine(command_line); |
+ } |
+}; |
+ |
+namespace { |
+ |
+class ScrollWaiter { |
+ public: |
+ explicit ScrollWaiter(content::RenderWidgetHostView* host_view) |
+ : host_view_(host_view) {} |
+ ~ScrollWaiter() {} |
+ |
+ void WaitForScrollChange(gfx::Vector2dF target_offset) { |
+ while (target_offset != host_view_->GetLastScrollOffset()) |
+ base::MessageLoop::current()->RunUntilIdle(); |
+ } |
+ |
+ private: |
+ content::RenderWidgetHostView* host_view_; |
+}; |
+ |
+} // namespace |
+ |
+// Tests that scrolls bubble from guest to embedder. |
+IN_PROC_BROWSER_TEST_F(WebViewTest, TestGuestWheelScrollsBubble) { |
+ LoadAppWithGuest("web_view/scrollable_embedder_and_guest"); |
+ |
+ content::WebContents* embedder_contents = GetEmbedderWebContents(); |
+ |
+ std::vector<content::WebContents*> guest_web_contents_list; |
+ GetGuestViewManager()->WaitForNumGuestsCreated(1u); |
+ GetGuestViewManager()->GetGuestWebContentsList(&guest_web_contents_list); |
+ ASSERT_EQ(1u, guest_web_contents_list.size()); |
+ |
+ content::WebContents* guest_contents = guest_web_contents_list[0]; |
+ |
+ gfx::Rect embedder_rect = embedder_contents->GetContainerBounds(); |
+ gfx::Rect guest_rect = guest_contents->GetContainerBounds(); |
+ |
+ guest_rect.set_x(guest_rect.x() - embedder_rect.x()); |
+ guest_rect.set_y(guest_rect.y() - embedder_rect.y()); |
+ embedder_rect.set_x(0); |
+ embedder_rect.set_y(0); |
+ |
+ // Send scroll gesture to embedder & verify. |
+ content::RenderWidgetHostView* embedder_host_view = |
+ embedder_contents->GetRenderWidgetHostView(); |
+ EXPECT_EQ(gfx::Vector2dF(), embedder_host_view->GetLastScrollOffset()); |
+ |
+ // Make sure wheel events don't get filtered. |
+ float scroll_magnitude = 15.f; |
+ |
+ { |
+ // Scroll the embedder from a position in the embedder that is not over |
+ // the guest. |
+ gfx::Point embedder_scroll_location( |
+ embedder_rect.x() + embedder_rect.width() / 2, |
+ (embedder_rect.y() + guest_rect.y()) / 2); |
+ |
+ gfx::Vector2dF expected_offset(0.f, scroll_magnitude); |
+ |
+ ScrollWaiter waiter(embedder_host_view); |
+ |
+ content::SimulateMouseEvent(embedder_contents, |
+ blink::WebInputEvent::MouseMove, |
+ embedder_scroll_location); |
+ content::SimulateMouseWheelEvent(embedder_contents, |
+ embedder_scroll_location, |
+ gfx::Vector2d(0, -scroll_magnitude)); |
+ waiter.WaitForScrollChange(expected_offset); |
+ } |
+ |
+ content::RenderWidgetHostView* guest_host_view = |
+ guest_contents->GetRenderWidgetHostView(); |
+ EXPECT_EQ(gfx::Vector2dF(), guest_host_view->GetLastScrollOffset()); |
+ |
+ // Send scroll gesture to guest and verify embedder scrolls. |
+ // Perform a scroll gesture of the same magnitude, but in the opposite |
+ // direction and centered over the GuestView this time. |
+ guest_rect = guest_contents->GetContainerBounds(); |
+ embedder_rect = embedder_contents->GetContainerBounds(); |
+ guest_rect.set_x(guest_rect.x() - embedder_rect.x()); |
+ guest_rect.set_y(guest_rect.y() - embedder_rect.y()); |
+ { |
+ gfx::Point guest_scroll_location(guest_rect.x() + guest_rect.width() / 2, |
+ guest_rect.y()); |
+ ScrollWaiter waiter(embedder_host_view); |
+ |
+ content::SimulateMouseEvent(embedder_contents, |
+ blink::WebInputEvent::MouseMove, |
+ guest_scroll_location); |
+ content::SimulateMouseWheelEvent(embedder_contents, guest_scroll_location, |
+ gfx::Vector2d(0, scroll_magnitude)); |
+ |
+ waiter.WaitForScrollChange(gfx::Vector2dF()); |
+ } |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(WebViewTouchTest, TestGuestGestureScrollsBubble) { |
+ // Just in case we're running ChromeOS tests, we need to make sure the |
+ // debounce interval is set to zero so our back-to-back gesture-scrolls don't |
+ // get munged together. Since the first scroll will be put on the fast |
+ // (compositor) path, while the second one should always be slow-path so it |
+ // gets to BrowserPlugin, having them merged is definitely an error. |
+ ui::GestureConfiguration* gesture_config = |
+ ui::GestureConfiguration::GetInstance(); |
+ gesture_config->set_scroll_debounce_interval_in_ms(0); |
+ |
+ LoadAppWithGuest("web_view/scrollable_embedder_and_guest"); |
+ |
+ content::WebContents* embedder_contents = GetEmbedderWebContents(); |
+ |
+ std::vector<content::WebContents*> guest_web_contents_list; |
+ GetGuestViewManager()->WaitForNumGuestsCreated(1u); |
+ GetGuestViewManager()->GetGuestWebContentsList(&guest_web_contents_list); |
+ ASSERT_EQ(1u, guest_web_contents_list.size()); |
+ |
+ content::WebContents* guest_contents = guest_web_contents_list[0]; |
+ |
+ gfx::Rect embedder_rect = embedder_contents->GetContainerBounds(); |
+ gfx::Rect guest_rect = guest_contents->GetContainerBounds(); |
+ |
+ guest_rect.set_x(guest_rect.x() - embedder_rect.x()); |
+ guest_rect.set_y(guest_rect.y() - embedder_rect.y()); |
+ embedder_rect.set_x(0); |
+ embedder_rect.set_y(0); |
+ |
+ // Send scroll gesture to embedder & verify. |
+ content::RenderWidgetHostView* embedder_host_view = |
+ embedder_contents->GetRenderWidgetHostView(); |
+ EXPECT_EQ(gfx::Vector2dF(), embedder_host_view->GetLastScrollOffset()); |
+ |
+ float gesture_distance = 15.f; |
+ { |
+ // Scroll the embedder from a position in the embedder that is not over |
+ // the guest. |
+ gfx::Point embedder_scroll_location( |
+ embedder_rect.x() + embedder_rect.width() / 2, |
+ (embedder_rect.y() + guest_rect.y()) / 2); |
+ |
+ gfx::Vector2dF expected_offset(0.f, gesture_distance); |
+ |
+ content::SimulateGestureScrollSequence( |
+ embedder_contents, embedder_scroll_location, |
+ gfx::Vector2dF(0, -gesture_distance)); |
+ |
+ ScrollWaiter waiter(embedder_host_view); |
+ |
+ waiter.WaitForScrollChange(expected_offset); |
+ } |
+ |
+ content::RenderWidgetHostView* guest_host_view = |
+ guest_contents->GetRenderWidgetHostView(); |
+ EXPECT_EQ(gfx::Vector2dF(), guest_host_view->GetLastScrollOffset()); |
+ |
+ // Send scroll gesture to guest and verify embedder scrolls. |
+ // Perform a scroll gesture of the same magnitude, but in the opposite |
+ // direction and centered over the GuestView this time. |
+ guest_rect = guest_contents->GetContainerBounds(); |
+ embedder_rect = embedder_contents->GetContainerBounds(); |
+ guest_rect.set_x(guest_rect.x() - embedder_rect.x()); |
+ guest_rect.set_y(guest_rect.y() - embedder_rect.y()); |
+ { |
+ gfx::Point guest_scroll_location(guest_rect.x() + guest_rect.width() / 2, |
+ guest_rect.y()); |
+ |
+ ScrollWaiter waiter(embedder_host_view); |
+ |
+ content::SimulateGestureScrollSequence(embedder_contents, |
+ guest_scroll_location, |
+ gfx::Vector2dF(0, gesture_distance)); |
+ |
+ waiter.WaitForScrollChange(gfx::Vector2dF()); |
+ } |
+} |
+ |
#if defined(USE_AURA) |
// TODO(wjmaclean): when WebViewTest is re-enabled on the site-isolation |
// bots, then re-enable this test class as well. |