Commit 13560dc4 authored by sahel's avatar sahel Committed by Commit Bot

Fling_Scheduler_mac returns proper compositor in oopif

This cl changes the fling scheduler mac to get the root view for oopifs so
that it has BrowserCompositor. Without this change fling|autoscroll inside
an oopif on mac would not work when viz is enabled.

On Non-mac platforms GetNativeView() in GetCompositor() takes care of going
through the nested oopifs.

The added browsertests will fail without this patch when viz is enabled.

Bug: 249063
Test: BrowserSideFlingBrowserTest.(Touchpad|Touchscreen)FlingInOOPIF
Change-Id: I3ccf3fc4356c6c467bb5714110e88d284b0d559a
Reviewed-on: https://chromium-review.googlesource.com/1195655
Commit-Queue: Sahel Sharify <sahel@chromium.org>
Reviewed-by: default avatarNavid Zolghadr <nzolghadr@chromium.org>
Reviewed-by: default avatarKen Buchanan <kenrb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#587646}
parent 152b082f
...@@ -7,7 +7,10 @@ ...@@ -7,7 +7,10 @@
#include "content/public/test/browser_test_utils.h" #include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h" #include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/hit_test_region_observer.h"
#include "content/shell/browser/shell.h" #include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "net/dns/mock_host_resolver.h"
#include "third_party/blink/public/platform/web_input_event.h" #include "third_party/blink/public/platform/web_input_event.h"
#include "ui/events/base_event_utils.h" #include "ui/events/base_event_utils.h"
...@@ -55,6 +58,16 @@ class BrowserSideFlingBrowserTest : public ContentBrowserTest { ...@@ -55,6 +58,16 @@ class BrowserSideFlingBrowserTest : public ContentBrowserTest {
run_loop_->Quit(); run_loop_->Quit();
} }
void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1");
SetupCrossSiteRedirector(embedded_test_server());
ASSERT_TRUE(embedded_test_server()->Start());
}
void SetUpCommandLine(base::CommandLine* command_line) override {
IsolateAllSitesForTesting(command_line);
}
protected: protected:
RenderWidgetHostImpl* GetWidgetHost() { RenderWidgetHostImpl* GetWidgetHost() {
return RenderWidgetHostImpl::From( return RenderWidgetHostImpl::From(
...@@ -76,15 +89,38 @@ class BrowserSideFlingBrowserTest : public ContentBrowserTest { ...@@ -76,15 +89,38 @@ class BrowserSideFlingBrowserTest : public ContentBrowserTest {
main_thread_sync.Wait(); main_thread_sync.Wait();
} }
std::unique_ptr<base::RunLoop> run_loop_; void LoadPageWithOOPIF() {
// navigate main frame to URL.
GURL main_url(embedded_test_server()->GetURL(
"a.com", "/frame_tree/page_with_positioned_frame.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
private: // Navigate oopif to URL.
DISALLOW_COPY_AND_ASSIGN(BrowserSideFlingBrowserTest); FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
}; ->GetFrameTree()
->root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* iframe_node = root->child_at(0);
GURL iframe_url(embedded_test_server()->GetURL("b.com", "/tall_page.html"));
NavigateFrameToURL(iframe_node, iframe_url);
IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest, TouchscreenFling) { WaitForHitTestDataOrChildSurfaceReady(iframe_node->current_frame_host());
LoadURL(kBrowserFlingDataURL); FrameTreeVisualizer visualizer;
ASSERT_EQ(
" Site A ------------ proxies for B\n"
" +--Site B ------- proxies for A\n"
"Where A = http://a.com/\n"
" B = http://b.com/",
visualizer.DepictFrameTree(root));
root_view_ = static_cast<RenderWidgetHostViewBase*>(
root->current_frame_host()->GetRenderWidgetHost()->GetView());
child_view_ = static_cast<RenderWidgetHostViewBase*>(
iframe_node->current_frame_host()->GetRenderWidgetHost()->GetView());
}
void SimulateTouchscreenFling(RenderWidgetHostImpl* render_widget_host) {
DCHECK(render_widget_host);
// Send a GSB to start scrolling sequence. // Send a GSB to start scrolling sequence.
blink::WebGestureEvent gesture_scroll_begin( blink::WebGestureEvent gesture_scroll_begin(
blink::WebGestureEvent::kGestureScrollBegin, blink::WebGestureEvent::kGestureScrollBegin,
...@@ -94,56 +130,135 @@ IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest, TouchscreenFling) { ...@@ -94,56 +130,135 @@ IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest, TouchscreenFling) {
blink::WebGestureEvent::ScrollUnits::kPrecisePixels; blink::WebGestureEvent::ScrollUnits::kPrecisePixels;
gesture_scroll_begin.data.scroll_begin.delta_x_hint = 0.f; gesture_scroll_begin.data.scroll_begin.delta_x_hint = 0.f;
gesture_scroll_begin.data.scroll_begin.delta_y_hint = -5.f; gesture_scroll_begin.data.scroll_begin.delta_y_hint = -5.f;
GetWidgetHost()->ForwardGestureEvent(gesture_scroll_begin); const gfx::PointF scroll_location_in_widget(1, 1);
const gfx::PointF scroll_location_in_root =
child_view_ ? child_view_->TransformPointToRootCoordSpaceF(
scroll_location_in_widget)
: scroll_location_in_widget;
const gfx::PointF scroll_location_in_screen =
child_view_ ? scroll_location_in_root +
root_view_->GetViewBounds().OffsetFromOrigin()
: scroll_location_in_widget;
gesture_scroll_begin.SetPositionInWidget(scroll_location_in_widget);
gesture_scroll_begin.SetPositionInScreen(scroll_location_in_screen);
render_widget_host->ForwardGestureEvent(gesture_scroll_begin);
// Send a GFS and wait for the page to scroll making sure that fling progress // Send a GFS.
// has started.
blink::WebGestureEvent gesture_fling_start( blink::WebGestureEvent gesture_fling_start(
blink::WebGestureEvent::kGestureFlingStart, blink::WebGestureEvent::kGestureFlingStart,
blink::WebInputEvent::kNoModifiers, ui::EventTimeForNow()); blink::WebInputEvent::kNoModifiers, ui::EventTimeForNow());
gesture_fling_start.SetSourceDevice(blink::kWebGestureDeviceTouchscreen); gesture_fling_start.SetSourceDevice(blink::kWebGestureDeviceTouchscreen);
gesture_fling_start.data.fling_start.velocity_x = 0.f; gesture_fling_start.data.fling_start.velocity_x = 0.f;
gesture_fling_start.data.fling_start.velocity_y = -2000.f; gesture_fling_start.data.fling_start.velocity_y = -2000.f;
GetWidgetHost()->ForwardGestureEvent(gesture_fling_start); gesture_fling_start.SetPositionInWidget(scroll_location_in_widget);
RenderFrameSubmissionObserver observer( gesture_fling_start.SetPositionInScreen(scroll_location_in_screen);
GetWidgetHost()->render_frame_metadata_provider()); render_widget_host->ForwardGestureEvent(gesture_fling_start);
gfx::Vector2dF default_scroll_offset;
while (observer.LastRenderFrameMetadata()
.root_scroll_offset.value_or(default_scroll_offset)
.y() <= 0) {
observer.WaitForMetadataChange();
} }
}
IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest, TouchpadFling) {
LoadURL(kBrowserFlingDataURL);
void SimulateTouchpadFling(RenderWidgetHostImpl* render_widget_host) {
DCHECK(render_widget_host);
// Send a wheel event to start scrolling sequence. // Send a wheel event to start scrolling sequence.
auto input_msg_watcher = std::make_unique<InputMsgWatcher>( auto input_msg_watcher = std::make_unique<InputMsgWatcher>(
GetWidgetHost(), blink::WebInputEvent::kMouseWheel); GetWidgetHost(), blink::WebInputEvent::kMouseWheel);
blink::WebMouseWheelEvent wheel_event = blink::WebMouseWheelEvent wheel_event =
SyntheticWebMouseWheelEventBuilder::Build(10, 10, 0, -53, 0, true); SyntheticWebMouseWheelEventBuilder::Build(10, 10, 0, -53, 0, true);
wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan; wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
GetWidgetHost()->ForwardWheelEvent(wheel_event); const gfx::PointF position_in_widget(1, 1);
const gfx::PointF position_in_root =
child_view_
? child_view_->TransformPointToRootCoordSpaceF(position_in_widget)
: position_in_widget;
const gfx::PointF position_in_screen =
child_view_
? position_in_root + root_view_->GetViewBounds().OffsetFromOrigin()
: position_in_widget;
wheel_event.SetPositionInWidget(position_in_widget);
wheel_event.SetPositionInScreen(position_in_screen);
render_widget_host->ForwardWheelEvent(wheel_event);
input_msg_watcher->WaitForAck(); input_msg_watcher->WaitForAck();
// Send a GFS and wait for the page to scroll more than 60 pixels making sure // Send a GFS.
// that fling progress has started.
blink::WebGestureEvent gesture_fling_start( blink::WebGestureEvent gesture_fling_start(
blink::WebGestureEvent::kGestureFlingStart, blink::WebGestureEvent::kGestureFlingStart,
blink::WebInputEvent::kNoModifiers, ui::EventTimeForNow()); blink::WebInputEvent::kNoModifiers, ui::EventTimeForNow());
gesture_fling_start.SetSourceDevice(blink::kWebGestureDeviceTouchpad); gesture_fling_start.SetSourceDevice(blink::kWebGestureDeviceTouchpad);
gesture_fling_start.data.fling_start.velocity_x = 0.f; gesture_fling_start.data.fling_start.velocity_x = 0.f;
gesture_fling_start.data.fling_start.velocity_y = -2000.f; gesture_fling_start.data.fling_start.velocity_y = -2000.f;
GetWidgetHost()->ForwardGestureEvent(gesture_fling_start); gesture_fling_start.SetPositionInWidget(position_in_widget);
gesture_fling_start.SetPositionInScreen(position_in_screen);
render_widget_host->ForwardGestureEvent(gesture_fling_start);
}
void WaitForScroll() {
RenderFrameSubmissionObserver observer( RenderFrameSubmissionObserver observer(
GetWidgetHost()->render_frame_metadata_provider()); GetWidgetHost()->render_frame_metadata_provider());
gfx::Vector2dF default_scroll_offset; gfx::Vector2dF default_scroll_offset;
// scrollTop > 0 is not enough since the first progressFling is called from
// FlingController::ProcessGestureFlingStart. Wait for scrollTop to exceed
// 100 pixels to make sure that ProgressFling has been called through
// FlingScheduler at least once.
while (observer.LastRenderFrameMetadata() while (observer.LastRenderFrameMetadata()
.root_scroll_offset.value_or(default_scroll_offset) .root_scroll_offset.value_or(default_scroll_offset)
.y() <= 60) { .y() <= 100) {
observer.WaitForMetadataChange(); observer.WaitForMetadataChange();
} }
}
void GiveItSomeTime() {
base::RunLoop run_loop;
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, run_loop.QuitClosure(),
base::TimeDelta::FromMilliseconds(10));
run_loop.Run();
}
void WaitForChildScroll() {
FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
->GetFrameTree()
->root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* iframe_node = root->child_at(0);
int scroll_top = EvalJs(iframe_node->current_frame_host(), "window.scrollY")
.ExtractDouble();
// scrollTop > 0 is not enough since the first progressFling is called from
// FlingController::ProcessGestureFlingStart. Wait for scrollTop to exceed
// 100 pixels to make sure that ProgressFling has been called through
// FlingScheduler at least once.
while (scroll_top < 100) {
GiveItSomeTime();
scroll_top = EvalJs(iframe_node->current_frame_host(), "window.scrollY")
.ExtractDouble();
}
}
std::unique_ptr<base::RunLoop> run_loop_;
RenderWidgetHostViewBase* child_view_ = nullptr;
RenderWidgetHostViewBase* root_view_ = nullptr;
private:
DISALLOW_COPY_AND_ASSIGN(BrowserSideFlingBrowserTest);
};
IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest, TouchscreenFling) {
LoadURL(kBrowserFlingDataURL);
SimulateTouchscreenFling(GetWidgetHost());
WaitForScroll();
}
IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest, TouchpadFling) {
LoadURL(kBrowserFlingDataURL);
SimulateTouchpadFling(GetWidgetHost());
WaitForScroll();
}
IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest, TouchscreenFlingInOOPIF) {
LoadPageWithOOPIF();
SimulateTouchscreenFling(child_view_->host());
WaitForChildScroll();
}
IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest, TouchpadFlingInOOPIF) {
LoadPageWithOOPIF();
SimulateTouchscreenFling(child_view_->host());
WaitForChildScroll();
} }
// Disabled on MacOS because it doesn't support touchscreen scroll. // Disabled on MacOS because it doesn't support touchscreen scroll.
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "content/browser/renderer_host/input/fling_scheduler_mac.h" #include "content/browser/renderer_host/input/fling_scheduler_mac.h"
#include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_child_frame.h"
#include "content/browser/renderer_host/render_widget_host_view_mac.h" #include "content/browser/renderer_host/render_widget_host_view_mac.h"
#include "ui/compositor/compositor.h" #include "ui/compositor/compositor.h"
...@@ -15,16 +16,20 @@ FlingSchedulerMac::FlingSchedulerMac(RenderWidgetHostImpl* host) ...@@ -15,16 +16,20 @@ FlingSchedulerMac::FlingSchedulerMac(RenderWidgetHostImpl* host)
FlingSchedulerMac::~FlingSchedulerMac() = default; FlingSchedulerMac::~FlingSchedulerMac() = default;
ui::Compositor* FlingSchedulerMac::GetCompositor() { ui::Compositor* FlingSchedulerMac::GetCompositor() {
if (!host_->GetView()) RenderWidgetHostViewBase* view = host_->GetView();
if (!view)
return nullptr; return nullptr;
// RWHV_child_frame doesn't have DelegatedFrameHost with ui::Compositor. if (view->IsRenderWidgetHostViewChildFrame()) {
if (host_->GetView()->IsRenderWidgetHostViewChildFrame()) view = view->GetRootView();
if (!view)
return nullptr; return nullptr;
RenderWidgetHostViewMac* view = }
static_cast<RenderWidgetHostViewMac*>(host_->GetView());
if (view->BrowserCompositor()) RenderWidgetHostViewMac* mac_view =
return view->BrowserCompositor()->GetCompositor(); static_cast<RenderWidgetHostViewMac*>(view);
if (mac_view->BrowserCompositor())
return mac_view->BrowserCompositor()->GetCompositor();
return nullptr; return nullptr;
} }
......
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