From c3670194bbba14ba4657b01f40e5266ac848e6cf Mon Sep 17 00:00:00 2001 From: Robert Flack <flackr@chromium.org> Date: Tue, 30 Mar 2021 16:18:09 +0000 Subject: [PATCH] Store OverscrollControllerDelegate as a WeakPtr. This is a speculative fix for https://crbug.com/1183933. The OverscrollControllerDelegate is owned by the WebContentsViewAura but an unowned pointer is set on the given view's OverscrollController. It's unclear whether the WebContentsViewAura is guaranteed to outlive or live as long as the RenderWidgetHostViewAura. By using a weak pointer we ensure the delegate is no longer called if it is destructed. Bug: 1183933 Change-Id: I41dc6e2e4ba26dd5be958fff5e7da3a5fc66c513 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2791883 Reviewed-by: Ken Buchanan <kenrb@chromium.org> Reviewed-by: Bo <boliu@chromium.org> Commit-Queue: Robert Flack <flackr@chromium.org> Cr-Commit-Position: refs/heads/master@{#867641} --- content/browser/BUILD.gn | 1 + .../renderer_host/overscroll_controller.h | 4 ++-- .../overscroll_controller_delegate.cc | 17 +++++++++++++++++ .../overscroll_controller_delegate.h | 8 ++++++-- .../overscroll_controller_unittest.cc | 2 +- .../render_widget_host_view_aura_unittest.cc | 3 ++- .../site_per_process_hit_test_browsertest.cc | 3 ++- .../web_contents/web_contents_view_aura.cc | 6 ++++-- 8 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 content/browser/renderer_host/overscroll_controller_delegate.cc diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 702c05df5bb64..b90a3a4d7a74c 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn @@ -1502,6 +1502,7 @@ source_set("browser") { "renderer_host/overscroll_configuration.cc", "renderer_host/overscroll_controller.cc", "renderer_host/overscroll_controller.h", + "renderer_host/overscroll_controller_delegate.cc", "renderer_host/overscroll_controller_delegate.h", "renderer_host/p2p/socket_dispatcher_host.cc", "renderer_host/p2p/socket_dispatcher_host.h", diff --git a/content/browser/renderer_host/overscroll_controller.h b/content/browser/renderer_host/overscroll_controller.h index c0ad10492be0d..e77d592ed8c60 100644 --- a/content/browser/renderer_host/overscroll_controller.h +++ b/content/browser/renderer_host/overscroll_controller.h @@ -65,7 +65,7 @@ class CONTENT_EXPORT OverscrollController { OverscrollMode overscroll_mode() const { return overscroll_mode_; } - void set_delegate(OverscrollControllerDelegate* delegate) { + void set_delegate(base::WeakPtr<OverscrollControllerDelegate> delegate) { delegate_ = delegate; } @@ -159,7 +159,7 @@ class CONTENT_EXPORT OverscrollController { // The delegate that receives the overscroll updates. The delegate is not // owned by this controller. - OverscrollControllerDelegate* delegate_ = nullptr; + base::WeakPtr<OverscrollControllerDelegate> delegate_; // A inertial scroll (fling) event may complete an overscroll gesture and // navigate to a new page or cancel the overscroll animation. In both cases diff --git a/content/browser/renderer_host/overscroll_controller_delegate.cc b/content/browser/renderer_host/overscroll_controller_delegate.cc new file mode 100644 index 0000000000000..c2e79cb4d6515 --- /dev/null +++ b/content/browser/renderer_host/overscroll_controller_delegate.cc @@ -0,0 +1,17 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/renderer_host/overscroll_controller_delegate.h" + +namespace content { + +OverscrollControllerDelegate::OverscrollControllerDelegate() = default; +OverscrollControllerDelegate::~OverscrollControllerDelegate() = default; + +base::WeakPtr<OverscrollControllerDelegate> +OverscrollControllerDelegate::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + +} // namespace content diff --git a/content/browser/renderer_host/overscroll_controller_delegate.h b/content/browser/renderer_host/overscroll_controller_delegate.h index 3ae6679573f4d..91f34dae989b3 100644 --- a/content/browser/renderer_host/overscroll_controller_delegate.h +++ b/content/browser/renderer_host/overscroll_controller_delegate.h @@ -7,6 +7,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "base/optional.h" #include "content/browser/renderer_host/overscroll_controller.h" #include "content/common/content_export.h" @@ -19,8 +20,8 @@ namespace content { // overscroll deltas maintained and reported by the controller. class CONTENT_EXPORT OverscrollControllerDelegate { public: - OverscrollControllerDelegate() {} - virtual ~OverscrollControllerDelegate() {} + OverscrollControllerDelegate(); + virtual ~OverscrollControllerDelegate(); // Get the size of the display containing the view corresponding to the // delegate. @@ -47,7 +48,10 @@ class CONTENT_EXPORT OverscrollControllerDelegate { // overscroll delta corresponding to the current overscroll mode. virtual base::Optional<float> GetMaxOverscrollDelta() const = 0; + base::WeakPtr<OverscrollControllerDelegate> GetWeakPtr(); + private: + base::WeakPtrFactory<OverscrollControllerDelegate> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(OverscrollControllerDelegate); }; diff --git a/content/browser/renderer_host/overscroll_controller_unittest.cc b/content/browser/renderer_host/overscroll_controller_unittest.cc index 986a654f3b5dd..e9e0a5bee3524 100644 --- a/content/browser/renderer_host/overscroll_controller_unittest.cc +++ b/content/browser/renderer_host/overscroll_controller_unittest.cc @@ -30,7 +30,7 @@ class OverscrollControllerTest : public ::testing::Test { features::kTouchpadOverscrollHistoryNavigation); delegate_ = std::make_unique<TestOverscrollDelegate>(gfx::Size(400, 300)); controller_ = std::make_unique<OverscrollController>(); - controller_->set_delegate(delegate_.get()); + controller_->set_delegate(delegate_->GetWeakPtr()); } void TearDown() override { diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index 86344e96352cd..e90a9a9312a0b 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc @@ -808,7 +808,8 @@ class RenderWidgetHostViewAuraOverscrollTest ->GetDisplayNearestView(view_->GetNativeView()) .size(); overscroll_delegate_.reset(new TestOverscrollDelegate(display_size)); - view_->overscroll_controller()->set_delegate(overscroll_delegate_.get()); + view_->overscroll_controller()->set_delegate( + overscroll_delegate_->GetWeakPtr()); InitViewForFrame(nullptr); view_->SetBounds(gfx::Rect(0, 0, 400, 200)); diff --git a/content/browser/site_per_process_hit_test_browsertest.cc b/content/browser/site_per_process_hit_test_browsertest.cc index 43b73b74fa6fe..28b437e04c711 100644 --- a/content/browser/site_per_process_hit_test_browsertest.cc +++ b/content/browser/site_per_process_hit_test_browsertest.cc @@ -2350,7 +2350,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessHitTestBrowserTest, std::unique_ptr<MockOverscrollControllerDelegateAura> mock_overscroll_delegate = std::make_unique<MockOverscrollControllerDelegateAura>(rwhva); - rwhva->overscroll_controller()->set_delegate(mock_overscroll_delegate.get()); + rwhva->overscroll_controller()->set_delegate( + mock_overscroll_delegate->GetWeakPtr()); MockOverscrollObserver* mock_overscroll_observer = mock_overscroll_delegate.get(); #elif defined(OS_ANDROID) diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc index d8d434d386b40..14a77d49fd5df 100644 --- a/content/browser/web_contents/web_contents_view_aura.cc +++ b/content/browser/web_contents/web_contents_view_aura.cc @@ -765,8 +765,10 @@ void WebContentsViewAura::InstallOverscrollControllerDelegate( if (!gesture_nav_simple_) gesture_nav_simple_ = std::make_unique<GestureNavSimple>(web_contents_); - if (view) - view->overscroll_controller()->set_delegate(gesture_nav_simple_.get()); + if (view) { + view->overscroll_controller()->set_delegate( + gesture_nav_simple_->GetWeakPtr()); + } } ui::TouchSelectionController* WebContentsViewAura::GetSelectionController()