Remove LayerScrollOffsetDelegate, make all input paths go thru proxy.
This removes the cc::LayerScrollOffsetDelegate interface, moving it
into the InputHandlerClient interface.
It also removes the pointer to cc::LayerTreeHostImpl (as a
cc::InputHandler*) from the WebView embedder code. Instead make the
WebView code always go through the SynchronousInputHandlerProxy (which
is the InputHandlerProxy) to talk to the compositor about input-related
things.
R=boliu, [email protected]
BUG=531746
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel
Review URL: https://codereview.chromium.org/1353013002
Cr-Commit-Position: refs/heads/master@{#350056}
diff --git a/cc/input/input_handler.h b/cc/input/input_handler.h
index b2fa8d2..51db013 100644
--- a/cc/input/input_handler.h
+++ b/cc/input/input_handler.h
@@ -52,6 +52,13 @@
virtual void Animate(base::TimeTicks time) = 0;
virtual void MainThreadHasStoppedFlinging() = 0;
virtual void ReconcileElasticOverscrollAndRootScroll() = 0;
+ virtual void UpdateRootLayerStateForSynchronousInputHandler(
+ const gfx::ScrollOffset& total_scroll_offset,
+ const gfx::ScrollOffset& max_scroll_offset,
+ const gfx::SizeF& scrollable_size,
+ float page_scale_factor,
+ float min_page_scale_factor,
+ float max_page_scale_factor) = 0;
protected:
InputHandlerClient() {}
@@ -126,15 +133,13 @@
// returned SCROLL_STARTED.
virtual void ScrollEnd() = 0;
- virtual void SetRootLayerScrollOffsetDelegate(
- LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate) = 0;
+ // Requests a callback to UpdateRootLayerStateForSynchronousInputHandler()
+ // giving the current root scroll and page scale information.
+ virtual void RequestUpdateForSynchronousInputHandler() = 0;
- // Called when the delegate's root scroll offset has changed for reasons
- // other than a SetTotalScrollOffset call. This passes along the new value of
- // the offset.
- // NOTE: This should only called after a valid delegate was set via a call to
- // SetRootLayerScrollOffsetDelegate.
- virtual void OnRootLayerDelegatedScrollOffsetChanged(
+ // Called when the root scroll offset has been changed in the synchronous
+ // input handler by the application (outside of input event handling).
+ virtual void SetSynchronousInputHandlerRootScrollOffset(
const gfx::ScrollOffset& root_offset) = 0;
virtual void PinchGestureBegin() = 0;
diff --git a/cc/input/layer_scroll_offset_delegate.h b/cc/input/layer_scroll_offset_delegate.h
deleted file mode 100644
index 84a6f5b..0000000
--- a/cc/input/layer_scroll_offset_delegate.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_INPUT_LAYER_SCROLL_OFFSET_DELEGATE_H_
-#define CC_INPUT_LAYER_SCROLL_OFFSET_DELEGATE_H_
-
-#include "base/basictypes.h"
-#include "base/callback_forward.h"
-#include "base/time/time.h"
-#include "ui/gfx/geometry/scroll_offset.h"
-#include "ui/gfx/geometry/size_f.h"
-
-namespace cc {
-
-// The LayerScrollOffsetDelegate allows for the embedder to take ownership of
-// the scroll offset of the root layer.
-//
-// The LayerScrollOffsetDelegate is only used on the impl thread.
-class LayerScrollOffsetDelegate {
- public:
- // This is called by the compositor to notify the delegate of any change to
- // the following parameters:
- // |total_scroll_offset| current scroll offset of the root layer,
- // |max_scroll_offset| total scroll offset upper bound for the root layer,
- // |scrollable_size| root layer scrollable size,
- // |page_scale_factor| current page scale,
- // |min_page_scale_factor| page scale lower limit,
- // |max_page_scale_factor| page scale upper limit.
- virtual void UpdateRootLayerState(
- const gfx::ScrollOffset& total_scroll_offset,
- const gfx::ScrollOffset& max_scroll_offset,
- const gfx::SizeF& scrollable_size,
- float page_scale_factor,
- float min_page_scale_factor,
- float max_page_scale_factor) = 0;
-
- protected:
- LayerScrollOffsetDelegate() {}
- virtual ~LayerScrollOffsetDelegate() {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(LayerScrollOffsetDelegate);
-};
-
-} // namespace cc
-
-#endif // CC_INPUT_LAYER_SCROLL_OFFSET_DELEGATE_H_
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 0be5ac0..36e7bdd 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -185,7 +185,6 @@
scroll_affects_scroll_handler_(false),
scroll_layer_id_when_mouse_over_scrollbar_(0),
tile_priorities_dirty_(false),
- root_layer_scroll_offset_delegate_(nullptr),
settings_(settings),
visible_(true),
cached_managed_memory_policy_(
@@ -425,8 +424,9 @@
AnimateScrollbars(monotonic_time);
AnimateTopControls(monotonic_time);
- // Animating stuff can change the root scroll offset, so inform the delegate.
- NotifyRootLayerScrollOffsetDelegate();
+ // Animating stuff can change the root scroll offset, so inform the
+ // synchronous input handler.
+ UpdateRootLayerStateForSynchronousInputHandler();
}
bool LayerTreeHostImpl::PrepareTiles() {
@@ -1929,8 +1929,9 @@
pending_page_scale_animation->scale,
pending_page_scale_animation->duration);
}
- // Activation can change the root scroll offset, so inform the delegate.
- NotifyRootLayerScrollOffsetDelegate();
+ // Activation can change the root scroll offset, so inform the synchronous
+ // input handler.
+ UpdateRootLayerStateForSynchronousInputHandler();
}
void LayerTreeHostImpl::SetVisible(bool visible) {
@@ -2714,8 +2715,9 @@
scroll_result.accumulated_root_overscroll = accumulated_root_overscroll_;
scroll_result.unused_scroll_delta = unused_root_delta;
- // Scrolling can change the root scroll offset, so inform the delegate.
- NotifyRootLayerScrollOffsetDelegate();
+ // Scrolling can change the root scroll offset, so inform the synchronous
+ // input handler.
+ UpdateRootLayerStateForSynchronousInputHandler();
return scroll_result;
}
@@ -2762,20 +2764,17 @@
return false;
}
-void LayerTreeHostImpl::SetRootLayerScrollOffsetDelegate(
- LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate) {
- root_layer_scroll_offset_delegate_ = root_layer_scroll_offset_delegate;
- // When first set, clobber the delegate's scroll offset with compositor's.
- NotifyRootLayerScrollOffsetDelegate();
+void LayerTreeHostImpl::RequestUpdateForSynchronousInputHandler() {
+ UpdateRootLayerStateForSynchronousInputHandler();
}
-void LayerTreeHostImpl::OnRootLayerDelegatedScrollOffsetChanged(
+void LayerTreeHostImpl::SetSynchronousInputHandlerRootScrollOffset(
const gfx::ScrollOffset& root_offset) {
active_tree_->DistributeRootScrollOffset(root_offset);
client_->SetNeedsCommitOnImplThread();
- // After applying the delegate's scroll offset, tell it what we ended up with.
- DCHECK(root_layer_scroll_offset_delegate_);
- NotifyRootLayerScrollOffsetDelegate();
+ // After applying the synchronous input handler's scroll offset, tell it what
+ // we ended up with.
+ UpdateRootLayerStateForSynchronousInputHandler();
// No need to SetNeedsRedraw, this is for WebView and every frame has redraw
// requested by the WebView embedder already.
}
@@ -2914,8 +2913,9 @@
client_->SetNeedsCommitOnImplThread();
SetNeedsRedraw();
client_->RenewTreePriority();
- // Pinching can change the root scroll offset, so inform the delegate.
- NotifyRootLayerScrollOffsetDelegate();
+ // Pinching can change the root scroll offset, so inform the synchronous input
+ // handler.
+ UpdateRootLayerStateForSynchronousInputHandler();
}
void LayerTreeHostImpl::PinchGestureEnd() {
@@ -3391,10 +3391,10 @@
(*it)->OnForwardScrollUpdateToMainThreadOnImpl();
}
-void LayerTreeHostImpl::NotifyRootLayerScrollOffsetDelegate() {
- if (!root_layer_scroll_offset_delegate_)
+void LayerTreeHostImpl::UpdateRootLayerStateForSynchronousInputHandler() {
+ if (!input_handler_client_)
return;
- root_layer_scroll_offset_delegate_->UpdateRootLayerState(
+ input_handler_client_->UpdateRootLayerStateForSynchronousInputHandler(
active_tree_->TotalScrollOffset(), active_tree_->TotalMaxScrollOffset(),
active_tree_->ScrollableSize(), active_tree_->current_page_scale_factor(),
active_tree_->min_page_scale_factor(),
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 358b88d..f3d4a67 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -21,7 +21,6 @@
#include "cc/debug/frame_timing_tracker.h"
#include "cc/debug/micro_benchmark_controller_impl.h"
#include "cc/input/input_handler.h"
-#include "cc/input/layer_scroll_offset_delegate.h"
#include "cc/input/top_controls_manager_client.h"
#include "cc/layers/layer_lists.h"
#include "cc/layers/render_pass_sink.h"
@@ -173,9 +172,8 @@
const gfx::Vector2dF& scroll_delta) override;
bool ScrollVerticallyByPage(const gfx::Point& viewport_point,
ScrollDirection direction) override;
- void SetRootLayerScrollOffsetDelegate(
- LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate) override;
- void OnRootLayerDelegatedScrollOffsetChanged(
+ void RequestUpdateForSynchronousInputHandler() override;
+ void SetSynchronousInputHandlerRootScrollOffset(
const gfx::ScrollOffset& root_offset) override;
void ScrollEnd() override;
InputHandler::ScrollStatus FlingScrollBegin() override;
@@ -674,7 +672,8 @@
void NotifySwapPromiseMonitorsOfSetNeedsRedraw();
void NotifySwapPromiseMonitorsOfForwardingToMainThread();
- void NotifyRootLayerScrollOffsetDelegate();
+
+ void UpdateRootLayerStateForSynchronousInputHandler();
void ScrollAnimationCreate(LayerImpl* layer_impl,
const gfx::ScrollOffset& target_offset,
@@ -737,9 +736,6 @@
bool tile_priorities_dirty_;
- // The optional delegate for the root layer scroll offset.
- LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate_;
-
const LayerTreeSettings settings_;
LayerTreeDebugState debug_state_;
bool visible_;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index eeaf88f..9921731 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -4557,21 +4557,26 @@
inner_viewport_scroll_layer->MaxScrollOffset());
}
-class TestScrollOffsetDelegate : public LayerScrollOffsetDelegate {
+class TestInputHandlerClient : public InputHandlerClient {
public:
- TestScrollOffsetDelegate()
+ TestInputHandlerClient()
: page_scale_factor_(0.f),
min_page_scale_factor_(-1.f),
max_page_scale_factor_(-1.f) {}
+ ~TestInputHandlerClient() override {}
- ~TestScrollOffsetDelegate() override {}
-
- void UpdateRootLayerState(const gfx::ScrollOffset& total_scroll_offset,
- const gfx::ScrollOffset& max_scroll_offset,
- const gfx::SizeF& scrollable_size,
- float page_scale_factor,
- float min_page_scale_factor,
- float max_page_scale_factor) override {
+ // InputHandlerClient implementation.
+ void WillShutdown() override {}
+ void Animate(base::TimeTicks time) override {}
+ void MainThreadHasStoppedFlinging() override {}
+ void ReconcileElasticOverscrollAndRootScroll() override {}
+ void UpdateRootLayerStateForSynchronousInputHandler(
+ const gfx::ScrollOffset& total_scroll_offset,
+ const gfx::ScrollOffset& max_scroll_offset,
+ const gfx::SizeF& scrollable_size,
+ float page_scale_factor,
+ float min_page_scale_factor,
+ float max_page_scale_factor) override {
DCHECK(total_scroll_offset.x() <= max_scroll_offset.x());
DCHECK(total_scroll_offset.y() <= max_scroll_offset.y());
last_set_scroll_offset_ = total_scroll_offset;
@@ -4616,51 +4621,56 @@
};
TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) {
- TestScrollOffsetDelegate scroll_delegate;
+ TestInputHandlerClient scroll_watcher;
host_impl_->SetViewportSize(gfx::Size(10, 20));
LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
LayerImpl* clip_layer = scroll_layer->parent()->parent();
clip_layer->SetBounds(gfx::Size(10, 20));
- // Setting the delegate results in the current scroll offset being set.
+ host_impl_->BindToClient(&scroll_watcher);
+
gfx::Vector2dF initial_scroll_delta(10.f, 10.f);
scroll_layer->PushScrollOffsetFromMainThread(gfx::ScrollOffset());
scroll_layer->SetScrollDelta(initial_scroll_delta);
- host_impl_->SetRootLayerScrollOffsetDelegate(&scroll_delegate);
- EXPECT_EQ(initial_scroll_delta.ToString(),
- scroll_delegate.last_set_scroll_offset().ToString());
+
+ EXPECT_EQ(gfx::ScrollOffset(), scroll_watcher.last_set_scroll_offset());
+
+ // Requesting an update results in the current scroll offset being set.
+ host_impl_->RequestUpdateForSynchronousInputHandler();
+ EXPECT_EQ(gfx::ScrollOffset(initial_scroll_delta),
+ scroll_watcher.last_set_scroll_offset());
// Setting the delegate results in the scrollable_size, max_scroll_offset,
// page_scale_factor and {min|max}_page_scale_factor being set.
- EXPECT_EQ(gfx::SizeF(100, 100), scroll_delegate.scrollable_size());
- EXPECT_EQ(gfx::ScrollOffset(90, 80), scroll_delegate.max_scroll_offset());
- EXPECT_EQ(1.f, scroll_delegate.page_scale_factor());
- EXPECT_EQ(1.f, scroll_delegate.min_page_scale_factor());
- EXPECT_EQ(1.f, scroll_delegate.max_page_scale_factor());
+ EXPECT_EQ(gfx::SizeF(100, 100), scroll_watcher.scrollable_size());
+ EXPECT_EQ(gfx::ScrollOffset(90, 80), scroll_watcher.max_scroll_offset());
+ EXPECT_EQ(1.f, scroll_watcher.page_scale_factor());
+ EXPECT_EQ(1.f, scroll_watcher.min_page_scale_factor());
+ EXPECT_EQ(1.f, scroll_watcher.max_page_scale_factor());
// Put a page scale on the tree.
host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 0.5f, 4.f);
- EXPECT_EQ(1.f, scroll_delegate.page_scale_factor());
- EXPECT_EQ(1.f, scroll_delegate.min_page_scale_factor());
- EXPECT_EQ(1.f, scroll_delegate.max_page_scale_factor());
+ EXPECT_EQ(1.f, scroll_watcher.page_scale_factor());
+ EXPECT_EQ(1.f, scroll_watcher.min_page_scale_factor());
+ EXPECT_EQ(1.f, scroll_watcher.max_page_scale_factor());
// Activation will update the delegate.
host_impl_->ActivateSyncTree();
- EXPECT_EQ(2.f, scroll_delegate.page_scale_factor());
- EXPECT_EQ(.5f, scroll_delegate.min_page_scale_factor());
- EXPECT_EQ(4.f, scroll_delegate.max_page_scale_factor());
+ EXPECT_EQ(2.f, scroll_watcher.page_scale_factor());
+ EXPECT_EQ(.5f, scroll_watcher.min_page_scale_factor());
+ EXPECT_EQ(4.f, scroll_watcher.max_page_scale_factor());
// Reset the page scale for the rest of the test.
host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
- EXPECT_EQ(2.f, scroll_delegate.page_scale_factor());
- EXPECT_EQ(.5f, scroll_delegate.min_page_scale_factor());
- EXPECT_EQ(4.f, scroll_delegate.max_page_scale_factor());
+ EXPECT_EQ(2.f, scroll_watcher.page_scale_factor());
+ EXPECT_EQ(.5f, scroll_watcher.min_page_scale_factor());
+ EXPECT_EQ(4.f, scroll_watcher.max_page_scale_factor());
// Animating page scale can change the root offset, so it should update the
// delegate.
host_impl_->Animate();
- EXPECT_EQ(1.f, scroll_delegate.page_scale_factor());
- EXPECT_EQ(.5f, scroll_delegate.min_page_scale_factor());
- EXPECT_EQ(4.f, scroll_delegate.max_page_scale_factor());
+ EXPECT_EQ(1.f, scroll_watcher.page_scale_factor());
+ EXPECT_EQ(.5f, scroll_watcher.min_page_scale_factor());
+ EXPECT_EQ(4.f, scroll_watcher.max_page_scale_factor());
// The pinch gesture doesn't put the delegate into a state where the scroll
// offset is outside of the scroll range. (this is verified by DCHECKs in the
@@ -4678,19 +4688,19 @@
EXPECT_EQ(InputHandler::SCROLL_STARTED,
host_impl_->ScrollBegin(gfx::Point(), InputHandler::GESTURE));
- host_impl_->OnRootLayerDelegatedScrollOffsetChanged(current_offset);
+ host_impl_->SetSynchronousInputHandlerRootScrollOffset(current_offset);
host_impl_->ScrollBy(gfx::Point(), scroll_delta);
EXPECT_EQ(ScrollOffsetWithDelta(current_offset, scroll_delta),
- scroll_delegate.last_set_scroll_offset());
+ scroll_watcher.last_set_scroll_offset());
current_offset = gfx::ScrollOffset(42.f, 41.f);
- host_impl_->OnRootLayerDelegatedScrollOffsetChanged(current_offset);
+ host_impl_->SetSynchronousInputHandlerRootScrollOffset(current_offset);
host_impl_->ScrollBy(gfx::Point(), scroll_delta);
EXPECT_EQ(current_offset + gfx::ScrollOffset(scroll_delta),
- scroll_delegate.last_set_scroll_offset());
+ scroll_watcher.last_set_scroll_offset());
host_impl_->ScrollEnd();
- host_impl_->OnRootLayerDelegatedScrollOffsetChanged(gfx::ScrollOffset());
+ host_impl_->SetSynchronousInputHandlerRootScrollOffset(gfx::ScrollOffset());
// Forces a full tree synchronization and ensures that the scroll delegate
// sees the correct size of the new tree.
@@ -4699,16 +4709,10 @@
host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
CreateScrollAndContentsLayers(host_impl_->pending_tree(), new_size);
host_impl_->ActivateSyncTree();
- EXPECT_EQ(new_size, scroll_delegate.scrollable_size());
+ EXPECT_EQ(new_size, scroll_watcher.scrollable_size());
- // Un-setting the delegate should propagate the delegate's current offset to
- // the root scrollable layer.
- current_offset = gfx::ScrollOffset(13.f, 12.f);
- host_impl_->OnRootLayerDelegatedScrollOffsetChanged(current_offset);
- host_impl_->SetRootLayerScrollOffsetDelegate(NULL);
-
- EXPECT_EQ(current_offset.ToString(),
- scroll_layer->CurrentScrollOffset().ToString());
+ // Tear down the LayerTreeHostImpl before the InputHandlerClient.
+ host_impl_.reset();
}
void CheckLayerScrollDelta(LayerImpl* layer, gfx::Vector2dF scroll_delta) {
@@ -4723,12 +4727,10 @@
TEST_F(LayerTreeHostImplTest,
ExternalRootLayerScrollOffsetDelegationReflectedInNextDraw) {
- TestScrollOffsetDelegate scroll_delegate;
host_impl_->SetViewportSize(gfx::Size(10, 20));
LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
LayerImpl* clip_layer = scroll_layer->parent()->parent();
clip_layer->SetBounds(gfx::Size(10, 20));
- host_impl_->SetRootLayerScrollOffsetDelegate(&scroll_delegate);
// Draw first frame to clear any pending draws and check scroll.
DrawFrame();
@@ -4737,7 +4739,7 @@
// Set external scroll delta on delegate and notify LayerTreeHost.
gfx::ScrollOffset scroll_offset(10.f, 10.f);
- host_impl_->OnRootLayerDelegatedScrollOffsetChanged(scroll_offset);
+ host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset);
// Check scroll delta reflected in layer.
LayerTreeHostImpl::FrameData frame;
@@ -4746,8 +4748,6 @@
host_impl_->DidDrawAllLayers(frame);
EXPECT_FALSE(frame.has_no_damage);
CheckLayerScrollDelta(scroll_layer, ScrollOffsetToVector2dF(scroll_offset));
-
- host_impl_->SetRootLayerScrollOffsetDelegate(NULL);
}
TEST_F(LayerTreeHostImplTest, OverscrollRoot) {
@@ -7698,9 +7698,6 @@
SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport);
- TestScrollOffsetDelegate scroll_delegate;
- host_impl_->SetRootLayerScrollOffsetDelegate(&scroll_delegate);
-
LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
DrawFrame();
@@ -7712,7 +7709,7 @@
gfx::ScrollOffset current_offset(70.f, 100.f);
- host_impl_->OnRootLayerDelegatedScrollOffsetChanged(current_offset);
+ host_impl_->SetSynchronousInputHandlerRootScrollOffset(current_offset);
EXPECT_EQ(gfx::ScrollOffset(25.f, 40.f), inner_scroll->MaxScrollOffset());
EXPECT_EQ(gfx::ScrollOffset(50.f, 80.f), outer_scroll->MaxScrollOffset());
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc
index 484b4a2e..79fde4f2 100644
--- a/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -1066,6 +1066,19 @@
}
}
+ void UpdateRootLayerStateForSynchronousInputHandler(
+ const gfx::ScrollOffset& total_scroll_offset,
+ const gfx::ScrollOffset& max_scroll_offset,
+ const gfx::SizeF& scrollable_size,
+ float page_scale_factor,
+ float min_page_scale_factor,
+ float max_page_scale_factor) override {
+ if (!task_runner_->BelongsToCurrentThread()) {
+ ADD_FAILURE() << "UpdateRootLayerStateForSynchronousInputHandler called "
+ << " on wrong thread";
+ }
+ }
+
private:
base::SingleThreadTaskRunner* task_runner_;
bool* received_stop_flinging_;
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 00db0a64..61a64d634 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -19,7 +19,6 @@
#include "cc/base/synced_property.h"
#include "cc/debug/devtools_instrumentation.h"
#include "cc/debug/traced_value.h"
-#include "cc/input/layer_scroll_offset_delegate.h"
#include "cc/input/page_scale_animation.h"
#include "cc/layers/heads_up_display_layer_impl.h"
#include "cc/layers/layer.h"
diff --git a/content/browser/android/in_process/synchronous_compositor_impl.cc b/content/browser/android/in_process/synchronous_compositor_impl.cc
index 06d622ce..98466724 100644
--- a/content/browser/android/in_process/synchronous_compositor_impl.cc
+++ b/content/browser/android/in_process/synchronous_compositor_impl.cc
@@ -8,7 +8,6 @@
#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/message_loop/message_loop.h"
-#include "cc/input/input_handler.h"
#include "content/browser/android/in_process/synchronous_compositor_external_begin_frame_source.h"
#include "content/browser/android/in_process/synchronous_compositor_factory_impl.h"
#include "content/browser/android/in_process/synchronous_compositor_registry.h"
@@ -21,6 +20,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
+#include "ui/gfx/geometry/scroll_offset.h"
#include "ui/gl/gl_surface.h"
namespace content {
@@ -79,7 +79,7 @@
begin_frame_source_(nullptr),
contents_(contents),
routing_id_(contents->GetRoutingID()),
- input_handler_(nullptr),
+ synchronous_input_handler_proxy_(nullptr),
registered_with_client_(false),
is_active_(true),
renderer_needs_begin_frames_(false),
@@ -92,7 +92,7 @@
SynchronousCompositorImpl::~SynchronousCompositorImpl() {
DCHECK(!output_surface_);
DCHECK(!begin_frame_source_);
- DCHECK(!input_handler_);
+ DCHECK(!synchronous_input_handler_proxy_);
}
void SynchronousCompositorImpl::SetClient(
@@ -120,7 +120,7 @@
DCHECK(CalledOnValidThread());
DCHECK(compositor_client_);
DCHECK(output_surface_);
- DCHECK(input_handler_);
+ DCHECK(synchronous_input_handler_proxy_);
DCHECK(!registered_with_client_);
registered_with_client_ = true;
@@ -130,12 +130,10 @@
base::Bind(&SynchronousCompositorImpl::DidActivatePendingTree,
weak_ptr_factory_.GetWeakPtr()));
- // Setting the delegate causes UpdateRootLayerState immediately so do it
- // after setting the client.
- input_handler_->SetRootLayerScrollOffsetDelegate(this);
// This disables the input system from animating inputs autonomously, instead
// routing all input animations through the SynchronousInputHandler, which is
- // |this| class.
+ // |this| class. Calling this causes an UpdateRootLayerState() immediately so,
+ // do it after setting the client.
synchronous_input_handler_proxy_->SetOnlySynchronouslyAnimateRootFlings(this);
}
@@ -155,19 +153,16 @@
void SynchronousCompositorImpl::DidInitializeRendererObjects(
SynchronousCompositorOutputSurface* output_surface,
SynchronousCompositorExternalBeginFrameSource* begin_frame_source,
- cc::InputHandler* input_handler,
SynchronousInputHandlerProxy* synchronous_input_handler_proxy) {
DCHECK(!output_surface_);
DCHECK(!begin_frame_source_);
DCHECK(output_surface);
DCHECK(begin_frame_source);
DCHECK(compositor_client_);
- DCHECK(input_handler);
DCHECK(synchronous_input_handler_proxy);
output_surface_ = output_surface;
begin_frame_source_ = begin_frame_source;
- input_handler_ = input_handler;
synchronous_input_handler_proxy_ = synchronous_input_handler_proxy;
output_surface_->SetCompositor(this);
@@ -180,16 +175,18 @@
DCHECK(compositor_client_);
if (registered_with_client_) {
- input_handler_->SetRootLayerScrollOffsetDelegate(nullptr);
output_surface_->SetTreeActivationCallback(base::Closure());
compositor_client_->DidDestroyCompositor(this);
registered_with_client_ = false;
}
+ // This object is being destroyed, so remove pointers to it.
begin_frame_source_->SetCompositor(nullptr);
output_surface_->SetCompositor(nullptr);
+ synchronous_input_handler_proxy_->SetOnlySynchronouslyAnimateRootFlings(
+ nullptr);
- input_handler_ = nullptr;
+ synchronous_input_handler_proxy_ = nullptr;
begin_frame_source_ = nullptr;
output_surface_ = nullptr;
// Don't propogate this signal from one renderer to the next.
@@ -276,9 +273,10 @@
void SynchronousCompositorImpl::DidChangeRootLayerScrollOffset(
const gfx::ScrollOffset& root_offset) {
DCHECK(CalledOnValidThread());
- if (!input_handler_)
+ if (!synchronous_input_handler_proxy_)
return;
- input_handler_->OnRootLayerDelegatedScrollOffsetChanged(root_offset);
+ synchronous_input_handler_proxy_->SynchronouslySetRootScrollOffset(
+ root_offset);
}
void SynchronousCompositorImpl::SetIsActive(bool is_active) {
diff --git a/content/browser/android/in_process/synchronous_compositor_impl.h b/content/browser/android/in_process/synchronous_compositor_impl.h
index 2f310bd..049fe78 100644
--- a/content/browser/android/in_process/synchronous_compositor_impl.h
+++ b/content/browser/android/in_process/synchronous_compositor_impl.h
@@ -10,7 +10,6 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
-#include "cc/input/layer_scroll_offset_delegate.h"
#include "content/browser/android/in_process/synchronous_compositor_output_surface.h"
#include "content/common/input/input_event_ack_state.h"
#include "content/public/browser/android/synchronous_compositor.h"
@@ -38,8 +37,7 @@
// This class is created on the main thread but most of the APIs are called
// from the Compositor thread.
class SynchronousCompositorImpl
- : public cc::LayerScrollOffsetDelegate,
- public SynchronousInputHandler,
+ : public SynchronousInputHandler,
public SynchronousCompositor,
public WebContentsUserData<SynchronousCompositorImpl> {
public:
@@ -55,7 +53,6 @@
void DidInitializeRendererObjects(
SynchronousCompositorOutputSurface* output_surface,
SynchronousCompositorExternalBeginFrameSource* begin_frame_source,
- cc::InputHandler* input_handler,
SynchronousInputHandlerProxy* synchronous_input_handler_proxy);
void DidDestroyRendererObjects();
@@ -86,8 +83,6 @@
// SynchronousInputHandler
void SetNeedsSynchronousAnimateInput() override;
-
- // LayerScrollOffsetDelegate
void UpdateRootLayerState(const gfx::ScrollOffset& total_scroll_offset,
const gfx::ScrollOffset& max_scroll_offset,
const gfx::SizeF& scrollable_size,
@@ -117,7 +112,6 @@
SynchronousCompositorExternalBeginFrameSource* begin_frame_source_;
WebContents* contents_;
const int routing_id_;
- cc::InputHandler* input_handler_;
SynchronousInputHandlerProxy* synchronous_input_handler_proxy_;
bool registered_with_client_;
bool is_active_;
diff --git a/content/browser/android/in_process/synchronous_compositor_registry.cc b/content/browser/android/in_process/synchronous_compositor_registry.cc
index 84c45a2..d101797 100644
--- a/content/browser/android/in_process/synchronous_compositor_registry.cc
+++ b/content/browser/android/in_process/synchronous_compositor_registry.cc
@@ -107,13 +107,11 @@
void SynchronousCompositorRegistry::RegisterInputHandler(
int routing_id,
- cc::InputHandler* input_handler,
SynchronousInputHandlerProxy* synchronous_input_handler_proxy) {
DCHECK(CalledOnValidThread());
- DCHECK(input_handler);
+ DCHECK(synchronous_input_handler_proxy);
Entry& entry = entry_map_[routing_id];
- DCHECK(!entry.input_handler);
- entry.input_handler = input_handler;
+ DCHECK(!entry.synchronous_input_handler_proxy);
entry.synchronous_input_handler_proxy = synchronous_input_handler_proxy;
CheckIsReady(routing_id);
}
@@ -125,7 +123,7 @@
if (entry.IsReady())
UnregisterObjects(routing_id);
- entry.input_handler = nullptr;
+ entry.synchronous_input_handler_proxy = nullptr;
RemoveEntryIfNeeded(routing_id);
}
@@ -134,7 +132,7 @@
Entry& entry = entry_map_[routing_id];
if (entry.IsReady()) {
entry.compositor->DidInitializeRendererObjects(
- entry.output_surface, entry.begin_frame_source, entry.input_handler,
+ entry.output_surface, entry.begin_frame_source,
entry.synchronous_input_handler_proxy);
}
}
@@ -150,7 +148,7 @@
DCHECK(entry_map_.find(routing_id) != entry_map_.end());
Entry& entry = entry_map_[routing_id];
if (!entry.compositor && !entry.begin_frame_source && !entry.output_surface &&
- !entry.input_handler) {
+ !entry.synchronous_input_handler_proxy) {
entry_map_.erase(routing_id);
}
}
@@ -163,11 +161,10 @@
: compositor(nullptr),
begin_frame_source(nullptr),
output_surface(nullptr),
- input_handler(nullptr),
synchronous_input_handler_proxy(nullptr) {}
bool SynchronousCompositorRegistry::Entry::IsReady() {
- return compositor && begin_frame_source && output_surface && input_handler &&
+ return compositor && begin_frame_source && output_surface &&
synchronous_input_handler_proxy;
}
diff --git a/content/browser/android/in_process/synchronous_compositor_registry.h b/content/browser/android/in_process/synchronous_compositor_registry.h
index f84bb0d..f7dc913 100644
--- a/content/browser/android/in_process/synchronous_compositor_registry.h
+++ b/content/browser/android/in_process/synchronous_compositor_registry.h
@@ -41,7 +41,6 @@
SynchronousCompositorOutputSurface* output_surface);
void RegisterInputHandler(
int routing_id,
- cc::InputHandler* input_handler,
SynchronousInputHandlerProxy* synchronous_input_handler_proxy);
void UnregisterInputHandler(int routing_id);
@@ -54,7 +53,6 @@
SynchronousCompositorImpl* compositor;
SynchronousCompositorExternalBeginFrameSource* begin_frame_source;
SynchronousCompositorOutputSurface* output_surface;
- cc::InputHandler* input_handler;
SynchronousInputHandlerProxy* synchronous_input_handler_proxy;
Entry();
diff --git a/content/browser/android/in_process/synchronous_input_event_filter.cc b/content/browser/android/in_process/synchronous_input_event_filter.cc
index c3669af..6645607 100644
--- a/content/browser/android/in_process/synchronous_input_event_filter.cc
+++ b/content/browser/android/in_process/synchronous_input_event_filter.cc
@@ -5,7 +5,6 @@
#include "content/browser/android/in_process/synchronous_input_event_filter.h"
#include "base/callback.h"
-#include "cc/input/input_handler.h"
#include "content/browser/android/in_process/synchronous_compositor_impl.h"
#include "content/browser/android/in_process/synchronous_compositor_registry.h"
#include "content/public/browser/browser_thread.h"
@@ -48,11 +47,10 @@
void SynchronousInputEventFilter::DidAddInputHandler(
int routing_id,
- cc::InputHandler* input_handler,
SynchronousInputHandlerProxy* synchronous_input_handler_proxy) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
SynchronousCompositorRegistry::GetInstance()->RegisterInputHandler(
- routing_id, input_handler, synchronous_input_handler_proxy);
+ routing_id, synchronous_input_handler_proxy);
}
void SynchronousInputEventFilter::DidRemoveInputHandler(int routing_id) {
diff --git a/content/browser/android/in_process/synchronous_input_event_filter.h b/content/browser/android/in_process/synchronous_input_event_filter.h
index 9174a4d..89feee1 100644
--- a/content/browser/android/in_process/synchronous_input_event_filter.h
+++ b/content/browser/android/in_process/synchronous_input_event_filter.h
@@ -35,7 +35,6 @@
void SetBoundHandler(const Handler& handler) override;
void DidAddInputHandler(
int routing_id,
- cc::InputHandler* input_handler,
SynchronousInputHandlerProxy* synchronous_input_handler_proxy) override;
void DidRemoveInputHandler(int routing_id) override;
void DidOverscroll(int routing_id,
diff --git a/content/renderer/input/input_event_filter.cc b/content/renderer/input/input_event_filter.cc
index 36476a71..931b4e7 100644
--- a/content/renderer/input/input_event_filter.cc
+++ b/content/renderer/input/input_event_filter.cc
@@ -57,7 +57,6 @@
void InputEventFilter::DidAddInputHandler(
int routing_id,
- cc::InputHandler* input_handler,
SynchronousInputHandlerProxy* synchronous_input_handler_proxy) {
base::AutoLock locked(routes_lock_);
routes_.insert(routing_id);
diff --git a/content/renderer/input/input_event_filter.h b/content/renderer/input/input_event_filter.h
index 1678a79..2f87d57 100644
--- a/content/renderer/input/input_event_filter.h
+++ b/content/renderer/input/input_event_filter.h
@@ -62,7 +62,6 @@
void SetBoundHandler(const Handler& handler) override;
void DidAddInputHandler(
int routing_id,
- cc::InputHandler* input_handler,
SynchronousInputHandlerProxy* synchronous_input_handler_proxy) override;
void DidRemoveInputHandler(int routing_id) override;
void DidOverscroll(int routing_id,
diff --git a/content/renderer/input/input_event_filter_unittest.cc b/content/renderer/input/input_event_filter_unittest.cc
index 98e6326..e96cd7a 100644
--- a/content/renderer/input/input_event_filter_unittest.cc
+++ b/content/renderer/input/input_event_filter_unittest.cc
@@ -165,7 +165,7 @@
EXPECT_EQ(0U, event_recorder_.record_count());
EXPECT_EQ(0U, message_recorder_.message_count());
- filter_->DidAddInputHandler(kTestRoutingID, nullptr, nullptr);
+ filter_->DidAddInputHandler(kTestRoutingID, nullptr);
AddEventsToFilter(filter_.get(), kEvents, arraysize(kEvents));
ASSERT_EQ(arraysize(kEvents), ipc_sink_.message_count());
@@ -241,7 +241,7 @@
}
TEST_F(InputEventFilterTest, PreserveRelativeOrder) {
- filter_->DidAddInputHandler(kTestRoutingID, nullptr, nullptr);
+ filter_->DidAddInputHandler(kTestRoutingID, nullptr);
event_recorder_.set_send_to_widget(true);
diff --git a/content/renderer/input/input_handler_manager.cc b/content/renderer/input/input_handler_manager.cc
index 3a298e3..cbc9a15 100644
--- a/content/renderer/input/input_handler_manager.cc
+++ b/content/renderer/input/input_handler_manager.cc
@@ -93,8 +93,7 @@
"result", "AddingRoute");
scoped_ptr<InputHandlerWrapper> wrapper(new InputHandlerWrapper(
this, routing_id, main_task_runner, input_handler, render_view_impl));
- client_->DidAddInputHandler(routing_id, input_handler.get(),
- wrapper->input_handler_proxy());
+ client_->DidAddInputHandler(routing_id, wrapper->input_handler_proxy());
input_handlers_.add(routing_id, wrapper.Pass());
}
diff --git a/content/renderer/input/input_handler_manager_client.h b/content/renderer/input/input_handler_manager_client.h
index a098808c..834f253 100644
--- a/content/renderer/input/input_handler_manager_client.h
+++ b/content/renderer/input/input_handler_manager_client.h
@@ -45,7 +45,6 @@
// Called from the compositor thread.
virtual void DidAddInputHandler(
int routing_id,
- cc::InputHandler* input_handler,
SynchronousInputHandlerProxy* synchronous_handler) = 0;
virtual void DidRemoveInputHandler(int routing_id) = 0;
virtual void DidOverscroll(int routing_id,
diff --git a/content/renderer/input/input_handler_proxy.cc b/content/renderer/input/input_handler_proxy.cc
index 302c66d..b5dcb18 100644
--- a/content/renderer/input/input_handler_proxy.cc
+++ b/content/renderer/input/input_handler_proxy.cc
@@ -816,21 +816,44 @@
scroll_elasticity_controller_->ReconcileStretchAndScroll();
}
+void InputHandlerProxy::UpdateRootLayerStateForSynchronousInputHandler(
+ const gfx::ScrollOffset& total_scroll_offset,
+ const gfx::ScrollOffset& max_scroll_offset,
+ const gfx::SizeF& scrollable_size,
+ float page_scale_factor,
+ float min_page_scale_factor,
+ float max_page_scale_factor) {
+ if (synchronous_input_handler_) {
+ synchronous_input_handler_->UpdateRootLayerState(
+ total_scroll_offset, max_scroll_offset, scrollable_size,
+ page_scale_factor, min_page_scale_factor, max_page_scale_factor);
+ }
+}
+
void InputHandlerProxy::SetOnlySynchronouslyAnimateRootFlings(
SynchronousInputHandler* synchronous_input_handler) {
- allow_root_animate_ = false;
+ allow_root_animate_ = !synchronous_input_handler;
synchronous_input_handler_ = synchronous_input_handler;
+ if (synchronous_input_handler_)
+ input_handler_->RequestUpdateForSynchronousInputHandler();
}
void InputHandlerProxy::SynchronouslyAnimate(base::TimeTicks time) {
// When this function is used, SetOnlySynchronouslyAnimate() should have been
// previously called. IOW you should either be entirely in synchronous mode or
// not.
+ DCHECK(synchronous_input_handler_);
DCHECK(!allow_root_animate_);
base::AutoReset<bool> reset(&allow_root_animate_, true);
Animate(time);
}
+void InputHandlerProxy::SynchronouslySetRootScrollOffset(
+ const gfx::ScrollOffset& root_offset) {
+ DCHECK(synchronous_input_handler_);
+ input_handler_->SetSynchronousInputHandlerRootScrollOffset(root_offset);
+}
+
void InputHandlerProxy::HandleOverscroll(
const gfx::Point& causal_event_viewport_point,
const cc::InputHandlerScrollResult& scroll_result) {
diff --git a/content/renderer/input/input_handler_proxy.h b/content/renderer/input/input_handler_proxy.h
index b61067c..6ebf073 100644
--- a/content/renderer/input/input_handler_proxy.h
+++ b/content/renderer/input/input_handler_proxy.h
@@ -54,11 +54,20 @@
void Animate(base::TimeTicks time) override;
void MainThreadHasStoppedFlinging() override;
void ReconcileElasticOverscrollAndRootScroll() override;
+ void UpdateRootLayerStateForSynchronousInputHandler(
+ const gfx::ScrollOffset& total_scroll_offset,
+ const gfx::ScrollOffset& max_scroll_offset,
+ const gfx::SizeF& scrollable_size,
+ float page_scale_factor,
+ float min_page_scale_factor,
+ float max_page_scale_factor) override;
// SynchronousInputHandlerProxy implementation.
void SetOnlySynchronouslyAnimateRootFlings(
SynchronousInputHandler* synchronous_input_handler) override;
void SynchronouslyAnimate(base::TimeTicks time) override;
+ void SynchronouslySetRootScrollOffset(
+ const gfx::ScrollOffset& root_offset) override;
// blink::WebGestureCurveTarget implementation.
virtual bool scrollBy(const blink::WebFloatSize& offset,
diff --git a/content/renderer/input/input_handler_proxy_unittest.cc b/content/renderer/input/input_handler_proxy_unittest.cc
index d5b5df1..3cc7f43 100644
--- a/content/renderer/input/input_handler_proxy_unittest.cc
+++ b/content/renderer/input/input_handler_proxy_unittest.cc
@@ -17,6 +17,8 @@
#include "third_party/WebKit/public/platform/WebPoint.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "ui/events/latency_info.h"
+#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/size_f.h"
using blink::WebActiveWheelFlingParameters;
using blink::WebFloatPoint;
@@ -132,12 +134,9 @@
MOCK_METHOD1(HaveWheelEventHandlersAt, bool(const gfx::Point& point));
MOCK_METHOD1(DoTouchEventsBlockScrollAt, bool(const gfx::Point& point));
- void SetRootLayerScrollOffsetDelegate(
- cc::LayerScrollOffsetDelegate* root_layer_scroll_offset_delegate)
- override {}
-
- void OnRootLayerDelegatedScrollOffsetChanged(
- const gfx::ScrollOffset& root_offset) override {}
+ MOCK_METHOD0(RequestUpdateForSynchronousInputHandler, void());
+ MOCK_METHOD1(SetSynchronousInputHandlerRootScrollOffset,
+ void(const gfx::ScrollOffset& root_offset));
bool IsCurrentlyScrollingRoot() const override { return is_scrolling_root_; }
void set_is_scrolling_root(bool is) { is_scrolling_root_ = is; }
@@ -150,6 +149,13 @@
class MockSynchronousInputHandler : public content::SynchronousInputHandler {
public:
MOCK_METHOD0(SetNeedsSynchronousAnimateInput, void());
+ MOCK_METHOD6(UpdateRootLayerState,
+ void(const gfx::ScrollOffset& total_scroll_offset,
+ const gfx::ScrollOffset& max_scroll_offset,
+ const gfx::SizeF& scrollable_size,
+ float page_scale_factor,
+ float min_page_scale_factor,
+ float max_page_scale_factor));
};
// A simple WebGestureCurve implementation that flings at a constant velocity
@@ -247,9 +253,13 @@
scroll_result_did_not_scroll_.did_scroll = false;
if (install_synchronous_handler_) {
+ EXPECT_CALL(mock_input_handler_,
+ RequestUpdateForSynchronousInputHandler())
+ .Times(1);
input_handler_->SetOnlySynchronouslyAnimateRootFlings(
&mock_synchronous_input_handler_);
}
+
mock_input_handler_.set_is_scrolling_root(synchronous_root_scroll_);
}
@@ -2311,6 +2321,8 @@
input_handler_.reset(
new content::InputHandlerProxy(&mock_input_handler_, &mock_client));
if (install_synchronous_handler_) {
+ EXPECT_CALL(mock_input_handler_, RequestUpdateForSynchronousInputHandler())
+ .Times(1);
input_handler_->SetOnlySynchronouslyAnimateRootFlings(
&mock_synchronous_input_handler_);
}
@@ -2336,6 +2348,75 @@
VERIFY_AND_RESET_MOCKS();
}
+TEST(SynchronousInputHandlerProxyTest, StartupShutdown) {
+ testing::StrictMock<MockInputHandler> mock_input_handler;
+ testing::StrictMock<MockInputHandlerProxyClient> mock_client;
+ testing::StrictMock<MockSynchronousInputHandler>
+ mock_synchronous_input_handler;
+ content::InputHandlerProxy proxy(&mock_input_handler, &mock_client);
+
+ // When adding a SynchronousInputHandler, immediately request an
+ // UpdateRootLayerStateForSynchronousInputHandler() call.
+ EXPECT_CALL(mock_input_handler, RequestUpdateForSynchronousInputHandler())
+ .Times(1);
+ proxy.SetOnlySynchronouslyAnimateRootFlings(&mock_synchronous_input_handler);
+
+ testing::Mock::VerifyAndClearExpectations(&mock_input_handler);
+ testing::Mock::VerifyAndClearExpectations(&mock_client);
+ testing::Mock::VerifyAndClearExpectations(&mock_synchronous_input_handler);
+
+ EXPECT_CALL(mock_input_handler, RequestUpdateForSynchronousInputHandler())
+ .Times(0);
+ proxy.SetOnlySynchronouslyAnimateRootFlings(nullptr);
+
+ testing::Mock::VerifyAndClearExpectations(&mock_input_handler);
+ testing::Mock::VerifyAndClearExpectations(&mock_client);
+ testing::Mock::VerifyAndClearExpectations(&mock_synchronous_input_handler);
+}
+
+TEST(SynchronousInputHandlerProxyTest, UpdateRootLayerState) {
+ testing::NiceMock<MockInputHandler> mock_input_handler;
+ testing::StrictMock<MockInputHandlerProxyClient> mock_client;
+ testing::StrictMock<MockSynchronousInputHandler>
+ mock_synchronous_input_handler;
+ content::InputHandlerProxy proxy(&mock_input_handler, &mock_client);
+
+ proxy.SetOnlySynchronouslyAnimateRootFlings(&mock_synchronous_input_handler);
+
+ // When adding a SynchronousInputHandler, immediately request an
+ // UpdateRootLayerStateForSynchronousInputHandler() call.
+ EXPECT_CALL(
+ mock_synchronous_input_handler,
+ UpdateRootLayerState(gfx::ScrollOffset(1, 2), gfx::ScrollOffset(3, 4),
+ gfx::SizeF(5, 6), 7, 8, 9))
+ .Times(1);
+ proxy.UpdateRootLayerStateForSynchronousInputHandler(
+ gfx::ScrollOffset(1, 2), gfx::ScrollOffset(3, 4), gfx::SizeF(5, 6), 7, 8,
+ 9);
+
+ testing::Mock::VerifyAndClearExpectations(&mock_input_handler);
+ testing::Mock::VerifyAndClearExpectations(&mock_client);
+ testing::Mock::VerifyAndClearExpectations(&mock_synchronous_input_handler);
+}
+
+TEST(SynchronousInputHandlerProxyTest, SetOffset) {
+ testing::NiceMock<MockInputHandler> mock_input_handler;
+ testing::StrictMock<MockInputHandlerProxyClient> mock_client;
+ testing::StrictMock<MockSynchronousInputHandler>
+ mock_synchronous_input_handler;
+ content::InputHandlerProxy proxy(&mock_input_handler, &mock_client);
+
+ proxy.SetOnlySynchronouslyAnimateRootFlings(&mock_synchronous_input_handler);
+
+ EXPECT_CALL(mock_input_handler, SetSynchronousInputHandlerRootScrollOffset(
+ gfx::ScrollOffset(5, 6)));
+ proxy.SynchronouslySetRootScrollOffset(gfx::ScrollOffset(5, 6));
+
+ testing::Mock::VerifyAndClearExpectations(&mock_input_handler);
+ testing::Mock::VerifyAndClearExpectations(&mock_client);
+ testing::Mock::VerifyAndClearExpectations(&mock_synchronous_input_handler);
+}
+
INSTANTIATE_TEST_CASE_P(AnimateInput,
InputHandlerProxyTest,
testing::ValuesIn(test_types));
diff --git a/content/renderer/input/synchronous_input_handler_proxy.h b/content/renderer/input/synchronous_input_handler_proxy.h
index 8f84aad7..438f41ce 100644
--- a/content/renderer/input/synchronous_input_handler_proxy.h
+++ b/content/renderer/input/synchronous_input_handler_proxy.h
@@ -7,6 +7,11 @@
#include "base/time/time.h"
+namespace gfx {
+class ScrollOffset;
+class SizeF;
+}
+
namespace content {
class CONTENT_EXPORT SynchronousInputHandler {
@@ -16,6 +21,16 @@
// animation. The embedder/app may choose to override and ignore the
// request for animation.
virtual void SetNeedsSynchronousAnimateInput() = 0;
+
+ // Informs the Android WebView embedder of the current root scroll and page
+ // scale state.
+ virtual void UpdateRootLayerState(
+ const gfx::ScrollOffset& total_scroll_offset,
+ const gfx::ScrollOffset& max_scroll_offset,
+ const gfx::SizeF& scrollable_size,
+ float page_scale_factor,
+ float min_page_scale_factor,
+ float max_page_scale_factor) = 0;
};
// Android WebView requires synchronous scrolling from the WebView application.
@@ -38,6 +53,14 @@
// it returns, it expects the animation scroll offsets to be visible to the
// application.
virtual void SynchronouslyAnimate(base::TimeTicks time) = 0;
+
+ // Called when the synchronous input handler wants to change the root scroll
+ // offset. Since it has the final say, this overrides values from compositor-
+ // controlled behaviour. After the offset is applied, the
+ // SynchronousInputHandler should be given back the result in case it differs
+ // from what was sent.
+ virtual void SynchronouslySetRootScrollOffset(
+ const gfx::ScrollOffset& root_offset) = 0;
};
} // namespace content