Commit d9269401 authored by khmel's avatar khmel Committed by Commit bot

Fix webview crash on attempt to scroll.

This fixes crash of webview when its content is scrolled using
2-fingers gesture via touchpad or using touchscreen.

BUG=615512
TEST=Manually on device using Arc++ OptIn UI, ToS is scrolled
     as expected using touchscreen or touchpad, no crashes.
CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_site_isolation

Review-Url: https://codereview.chromium.org/2015373002
Cr-Commit-Position: refs/heads/master@{#397901}
parent b060edf6
...@@ -3416,6 +3416,79 @@ IN_PROC_BROWSER_TEST_P(WebViewGuestScrollTouchTest, ...@@ -3416,6 +3416,79 @@ IN_PROC_BROWSER_TEST_P(WebViewGuestScrollTouchTest,
} }
} }
class WebViewScrollGuestContentTest : public WebViewTest {
public:
~WebViewScrollGuestContentTest() override {}
void SetUpCommandLine(base::CommandLine* command_line) override {
WebViewTest::SetUpCommandLine(command_line);
command_line->AppendSwitchASCII(switches::kTouchEvents,
switches::kTouchEventsEnabled);
}
};
INSTANTIATE_TEST_CASE_P(WebViewScrollGuestContent,
WebViewScrollGuestContentTest,
testing::Values(false));
IN_PROC_BROWSER_TEST_P(WebViewScrollGuestContentTest, ScrollGuestContent) {
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];
content::RenderWidgetHostView* guest_host_view =
guest_contents->GetRenderWidgetHostView();
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());
content::RenderWidgetHostView* embedder_host_view =
embedder_contents->GetRenderWidgetHostView();
EXPECT_EQ(gfx::Vector2dF(), guest_host_view->GetLastScrollOffset());
EXPECT_EQ(gfx::Vector2dF(), embedder_host_view->GetLastScrollOffset());
gfx::Point guest_scroll_location(guest_rect.x() + guest_rect.width() / 2,
guest_rect.y());
float gesture_distance = 15.f;
{
gfx::Vector2dF expected_offset(0.f, gesture_distance);
ScrollWaiter waiter(guest_host_view);
content::SimulateGestureScrollSequence(
embedder_contents, guest_scroll_location,
gfx::Vector2dF(0, -gesture_distance));
waiter.WaitForScrollChange(expected_offset);
}
EXPECT_EQ(gfx::Vector2dF(), embedder_host_view->GetLastScrollOffset());
// Use fling gesture to scroll back, velocity should be big enough to scroll
// content back.
float fling_velocity = 300.f;
{
ScrollWaiter waiter(guest_host_view);
content::SimulateGestureFlingSequence(
embedder_contents, guest_scroll_location,
gfx::Vector2dF(0, fling_velocity));
waiter.WaitForScrollChange(gfx::Vector2dF());
}
EXPECT_EQ(gfx::Vector2dF(), embedder_host_view->GetLastScrollOffset());
}
#if defined(USE_AURA) #if defined(USE_AURA)
// TODO(wjmaclean): when WebViewTest is re-enabled on the site-isolation // TODO(wjmaclean): when WebViewTest is re-enabled on the site-isolation
// bots, then re-enable this test class as well. // bots, then re-enable this test class as well.
......
...@@ -4,13 +4,13 @@ ...@@ -4,13 +4,13 @@
* source code is governed by a BSD-style license that can be found in the * source code is governed by a BSD-style license that can be found in the
* LICENSE file. * LICENSE file.
--> -->
<html> <html id='root' style="overflow-y: visible;">
<!-- Since the body of an app is not scrollable by default, explicitly <!-- Since the body of an app is not scrollable by default, explicitly
set it to be scrollable. --> set it to be scrollable. -->
<head> <head>
<script type="text/javascript" src="guest.js"></script> <script type="text/javascript" src="guest.js"></script>
</head> </head>
<body style="height: 200px; width: 300px; overflow-y: visible; margin: auto"> <body style="margin: auto">
Test guest.<br> Test guest.<br>
Test guest.<br> Test guest.<br>
Test guest.<br> Test guest.<br>
......
...@@ -20,7 +20,7 @@ window.onAppCommand = function(command) { ...@@ -20,7 +20,7 @@ window.onAppCommand = function(command) {
LOG('guest::onAppCommand: ' + command); LOG('guest::onAppCommand: ' + command);
switch (command) { switch (command) {
case 'set_overflow_hidden': case 'set_overflow_hidden':
document.body.style.overflow = 'hidden'; document.getElementById('root').style.overflow = 'hidden';
sendMessageToEmbedder('overflow_is_hidden'); sendMessageToEmbedder('overflow_is_hidden');
break; break;
}; };
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
--> -->
<html style="overflow-y: scroll;"> <html style="overflow-y: scroll;">
<body style= <body style=
"width: 400px; height: 400px; margin: 0px; padding: 0px; overflow-y: scroll"> "width: 400px; height: 400px; margin: 0px; padding: 0px;">
<div id="webview-tag-container"></div> <div id="webview-tag-container"></div>
<script src="main.js"></script> <script src="main.js"></script>
</body> </body>
......
...@@ -23,7 +23,7 @@ var startTest = function() { ...@@ -23,7 +23,7 @@ var startTest = function() {
webview.style.padding = '0px'; webview.style.padding = '0px';
webview.style.position = 'absolute'; webview.style.position = 'absolute';
webview.style.left = '50px'; webview.style.left = '50px';
webview.style.top = '100px' webview.style.top = '100px';
webview.src = 'guest.html'; webview.src = 'guest.html';
document.querySelector('#webview-tag-container').appendChild(webview); document.querySelector('#webview-tag-container').appendChild(webview);
}; };
......
...@@ -74,6 +74,9 @@ RenderWidgetHostViewGuest::RenderWidgetHostViewGuest( ...@@ -74,6 +74,9 @@ RenderWidgetHostViewGuest::RenderWidgetHostViewGuest(
// |guest| is NULL during test. // |guest| is NULL during test.
guest_(guest ? guest->AsWeakPtr() : base::WeakPtr<BrowserPluginGuest>()), guest_(guest ? guest->AsWeakPtr() : base::WeakPtr<BrowserPluginGuest>()),
platform_view_(platform_view) { platform_view_(platform_view) {
gfx::NativeView view = GetNativeView();
if (view)
UpdateScreenInfo(view);
} }
RenderWidgetHostViewGuest::~RenderWidgetHostViewGuest() {} RenderWidgetHostViewGuest::~RenderWidgetHostViewGuest() {}
......
...@@ -523,6 +523,37 @@ void SimulateGestureScrollSequence(WebContents* web_contents, ...@@ -523,6 +523,37 @@ void SimulateGestureScrollSequence(WebContents* web_contents,
widget_host->ForwardGestureEvent(scroll_end); widget_host->ForwardGestureEvent(scroll_end);
} }
void SimulateGestureFlingSequence(WebContents* web_contents,
const gfx::Point& point,
const gfx::Vector2dF& velocity) {
RenderWidgetHostImpl* widget_host = RenderWidgetHostImpl::From(
web_contents->GetRenderViewHost()->GetWidget());
blink::WebGestureEvent scroll_begin;
scroll_begin.type = blink::WebGestureEvent::GestureScrollBegin;
scroll_begin.sourceDevice = blink::WebGestureDeviceTouchpad;
scroll_begin.x = point.x();
scroll_begin.y = point.y();
widget_host->ForwardGestureEvent(scroll_begin);
blink::WebGestureEvent scroll_end;
scroll_end.type = blink::WebGestureEvent::GestureScrollEnd;
scroll_end.sourceDevice = blink::WebGestureDeviceTouchpad;
scroll_end.x = point.x();
scroll_end.y = point.y();
widget_host->ForwardGestureEvent(scroll_end);
blink::WebGestureEvent fling_start;
fling_start.type = blink::WebGestureEvent::GestureFlingStart;
fling_start.sourceDevice = blink::WebGestureDeviceTouchpad;
fling_start.x = point.x();
fling_start.y = point.y();
fling_start.data.flingStart.targetViewport = false;
fling_start.data.flingStart.velocityX = velocity.x();
fling_start.data.flingStart.velocityY = velocity.y();
widget_host->ForwardGestureEvent(fling_start);
}
void SimulateTapAt(WebContents* web_contents, const gfx::Point& point) { void SimulateTapAt(WebContents* web_contents, const gfx::Point& point) {
blink::WebGestureEvent tap; blink::WebGestureEvent tap;
tap.type = blink::WebGestureEvent::GestureTap; tap.type = blink::WebGestureEvent::GestureTap;
......
...@@ -130,6 +130,10 @@ void SimulateGestureScrollSequence(WebContents* web_contents, ...@@ -130,6 +130,10 @@ void SimulateGestureScrollSequence(WebContents* web_contents,
const gfx::Point& point, const gfx::Point& point,
const gfx::Vector2dF& delta); const gfx::Vector2dF& delta);
void SimulateGestureFlingSequence(WebContents* web_contents,
const gfx::Point& point,
const gfx::Vector2dF& velocity);
// Taps the screen at |point|. // Taps the screen at |point|.
void SimulateTapAt(WebContents* web_contents, const gfx::Point& point); void SimulateTapAt(WebContents* web_contents, const gfx::Point& point);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment