1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CC_INPUT_INPUT_HANDLER_H_
6 #define CC_INPUT_INPUT_HANDLER_H_
7 
8 #include <memory>
9 
10 #include "base/time/time.h"
11 #include "cc/cc_export.h"
12 #include "cc/input/event_listener_properties.h"
13 #include "cc/input/main_thread_scrolling_reason.h"
14 #include "cc/input/overscroll_behavior.h"
15 #include "cc/input/scroll_input_type.h"
16 #include "cc/input/scroll_state.h"
17 #include "cc/input/scrollbar.h"
18 #include "cc/input/touch_action.h"
19 #include "cc/metrics/events_metrics_manager.h"
20 #include "cc/paint/element_id.h"
21 #include "cc/trees/swap_promise_monitor.h"
22 #include "components/viz/common/frame_sinks/begin_frame_args.h"
23 #include "ui/events/types/scroll_types.h"
24 
25 namespace gfx {
26 class Point;
27 class ScrollOffset;
28 class SizeF;
29 class Vector2dF;
30 }  // namespace gfx
31 
32 namespace ui {
33 class LatencyInfo;
34 }  // namespace ui
35 
36 namespace cc {
37 
38 class EventMetrics;
39 class ScrollElasticityHelper;
40 
41 enum PointerResultType { kUnhandled = 0, kScrollbarScroll };
42 
43 // These enum values are reported in UMA. So these values should never be
44 // removed or changed.
45 enum class ScrollBeginThreadState {
46   kScrollingOnCompositor = 0,
47   kScrollingOnCompositorBlockedOnMain = 1,
48   kScrollingOnMain = 2,
49   kMaxValue = kScrollingOnMain,
50 };
51 
52 struct CC_EXPORT InputHandlerPointerResult {
53   InputHandlerPointerResult();
54   // Tells what type of processing occurred in the input handler as a result of
55   // the pointer event.
56   PointerResultType type;
57 
58   // Tells what scroll_units should be used.
59   ui::ScrollGranularity scroll_units;
60 
61   // If the input handler processed the event as a scrollbar scroll, it will
62   // return a gfx::ScrollOffset that produces the necessary scroll. However,
63   // it is still the client's responsibility to generate the gesture scrolls
64   // instead of the input handler performing it as a part of handling the
65   // pointer event (due to the latency attribution that happens at the
66   // InputHandlerProxy level).
67   gfx::ScrollOffset scroll_offset;
68 
69   // Used to determine which scroll_node needs to be scrolled. The primary
70   // purpose of this is to avoid hit testing for gestures that already know
71   // which scroller to target.
72   ElementId target_scroller;
73 };
74 
75 struct CC_EXPORT InputHandlerScrollResult {
76   InputHandlerScrollResult();
77   // Did any layer scroll as a result this ScrollUpdate call?
78   bool did_scroll;
79   // Was any of the scroll delta argument to this ScrollUpdate call not used?
80   bool did_overscroll_root;
81   // The total overscroll that has been accumulated by all ScrollUpdate calls
82   // that have had overscroll since the last ScrollBegin call. This resets upon
83   // a ScrollUpdate with no overscroll.
84   gfx::Vector2dF accumulated_root_overscroll;
85   // The amount of the scroll delta argument to this ScrollUpdate call that was
86   // not used for scrolling.
87   gfx::Vector2dF unused_scroll_delta;
88   // How the browser should handle the overscroll navigation based on the css
89   // property scroll-boundary-behavior.
90   OverscrollBehavior overscroll_behavior;
91   // The current offset of the currently scrolling node. It is in DIP or
92   // physical pixels depending on the use-zoom-for-dsf flag. If the currently
93   // scrolling node is the viewport, this would be the sum of the scroll offsets
94   // of the inner and outer node, representing the visual scroll offset.
95   gfx::Vector2dF current_visual_offset;
96 };
97 
98 class CC_EXPORT InputHandlerClient {
99  public:
100   InputHandlerClient(const InputHandlerClient&) = delete;
101   virtual ~InputHandlerClient() = default;
102 
103   InputHandlerClient& operator=(const InputHandlerClient&) = delete;
104 
105   virtual void WillShutdown() = 0;
106   virtual void Animate(base::TimeTicks time) = 0;
107   virtual void ReconcileElasticOverscrollAndRootScroll() = 0;
108   virtual void UpdateRootLayerStateForSynchronousInputHandler(
109       const gfx::ScrollOffset& total_scroll_offset,
110       const gfx::ScrollOffset& max_scroll_offset,
111       const gfx::SizeF& scrollable_size,
112       float page_scale_factor,
113       float min_page_scale_factor,
114       float max_page_scale_factor) = 0;
115   virtual void DeliverInputForBeginFrame(const viz::BeginFrameArgs& args) = 0;
116   virtual void DeliverInputForHighLatencyMode() = 0;
117 
118  protected:
119   InputHandlerClient() = default;
120 };
121 
122 // The InputHandler is a way for the embedders to interact with the impl thread
123 // side of the compositor implementation. There is one InputHandler per
124 // LayerTreeHost. To use the input handler, implement the InputHanderClient
125 // interface and bind it to the handler on the compositor thread.
126 class CC_EXPORT InputHandler {
127  public:
128   // Note these are used in a histogram. Do not reorder or delete existing
129   // entries.
130   enum ScrollThread {
131     SCROLL_ON_MAIN_THREAD = 0,
132     SCROLL_ON_IMPL_THREAD,
133     SCROLL_IGNORED,
134     SCROLL_UNKNOWN,
135     LAST_SCROLL_STATUS = SCROLL_UNKNOWN
136   };
137 
138   InputHandler(const InputHandler&) = delete;
139   InputHandler& operator=(const InputHandler&) = delete;
140 
141   struct ScrollStatus {
ScrollStatusScrollStatus142     ScrollStatus()
143         : thread(SCROLL_ON_IMPL_THREAD),
144           main_thread_scrolling_reasons(
145               MainThreadScrollingReason::kNotScrollingOnMain),
146           bubble(false) {}
ScrollStatusScrollStatus147     ScrollStatus(ScrollThread thread, uint32_t main_thread_scrolling_reasons)
148         : thread(thread),
149           main_thread_scrolling_reasons(main_thread_scrolling_reasons) {}
150     ScrollThread thread;
151     uint32_t main_thread_scrolling_reasons;
152     bool bubble;
153   };
154 
155   enum class TouchStartOrMoveEventListenerType {
156     NO_HANDLER,
157     HANDLER,
158     HANDLER_ON_SCROLLING_LAYER
159   };
160 
161   // Binds a client to this handler to receive notifications. Only one client
162   // can be bound to an InputHandler. The client must live at least until the
163   // handler calls WillShutdown() on the client.
164   virtual void BindToClient(InputHandlerClient* client) = 0;
165 
166   // Selects a ScrollNode to be "latched" for scrolling using the
167   // |scroll_state| start position. The selected node remains latched until the
168   // gesture is ended by a call to ScrollEnd.  Returns SCROLL_STARTED if a node
169   // at the coordinates can be scrolled and was latched, SCROLL_ON_MAIN_THREAD
170   // if the scroll event should instead be delegated to the main thread, or
171   // SCROLL_IGNORED if there is nothing to be scrolled at the given
172   // coordinates.
173   virtual ScrollStatus ScrollBegin(ScrollState* scroll_state,
174                                    ScrollInputType type) = 0;
175 
176   // Similar to ScrollBegin, except the hit test is skipped and scroll always
177   // targets at the root layer.
178   virtual ScrollStatus RootScrollBegin(ScrollState* scroll_state,
179                                        ScrollInputType type) = 0;
180 
181   // Scroll the layer selected by |ScrollBegin| by given |scroll_state| delta.
182   // Internally, the delta is transformed to local layer's coordinate space for
183   // scrolls gestures that are direct manipulation (e.g. touch). If the
184   // viewport is latched, and it can no longer scroll, the root overscroll
185   // accumulated within this ScrollBegin() scope is reported in the return
186   // value's |accumulated_overscroll| field. Should only be called if
187   // ScrollBegin() returned SCROLL_STARTED.
188   //
189   // Is a no-op if no scroller was latched to in ScrollBegin and returns an
190   // empty-initialized InputHandlerScrollResult.
191   //
192   // |delayed_by| is the delay from the event that caused the scroll. This is
193   // taken into account when determining the duration of the animation if one
194   // is created.
195   virtual InputHandlerScrollResult ScrollUpdate(ScrollState* scroll_state,
196                                                 base::TimeDelta delayed_by) = 0;
197 
198   // Stop scrolling the selected layer. Must be called only if ScrollBegin()
199   // returned SCROLL_STARTED. No-op if ScrollBegin wasn't called or didn't
200   // result in a successful scroll latch. Snap to a snap position if
201   // |should_snap| is true.
202   virtual void ScrollEnd(bool should_snap) = 0;
203 
204   // Called to notify every time scroll-begin/end is attempted by an input
205   // event.
206   virtual void RecordScrollBegin(ScrollInputType input_type,
207                                  ScrollBeginThreadState scroll_start_state) = 0;
208   virtual void RecordScrollEnd(ScrollInputType input_type) = 0;
209 
210   virtual InputHandlerPointerResult MouseMoveAt(
211       const gfx::Point& mouse_position) = 0;
212   // TODO(arakeri): Pass in the modifier instead of a bool once the refactor
213   // (crbug.com/1022097) is done. For details, see crbug.com/1016955.
214   virtual InputHandlerPointerResult MouseDown(const gfx::PointF& mouse_position,
215                                               bool shift_modifier) = 0;
216   virtual InputHandlerPointerResult MouseUp(
217       const gfx::PointF& mouse_position) = 0;
218   virtual void MouseLeave() = 0;
219 
220   // Returns frame_element_id from the layer hit by the given point.
221   // If the hit test failed, an invalid element ID is returned.
222   virtual ElementId FindFrameElementIdAtPoint(
223       const gfx::PointF& mouse_position) = 0;
224 
225   // Requests a callback to UpdateRootLayerStateForSynchronousInputHandler()
226   // giving the current root scroll and page scale information.
227   virtual void RequestUpdateForSynchronousInputHandler() = 0;
228 
229   // Called when the root scroll offset has been changed in the synchronous
230   // input handler by the application (outside of input event handling). Offset
231   // is expected in "content/page coordinates".
232   virtual void SetSynchronousInputHandlerRootScrollOffset(
233       const gfx::ScrollOffset& root_content_offset) = 0;
234 
235   virtual void PinchGestureBegin() = 0;
236   virtual void PinchGestureUpdate(float magnify_delta,
237                                   const gfx::Point& anchor) = 0;
238   virtual void PinchGestureEnd(const gfx::Point& anchor, bool snap_to_min) = 0;
239 
240   // Request another callback to InputHandlerClient::Animate().
241   virtual void SetNeedsAnimateInput() = 0;
242 
243   // Returns true if there is an active scroll on the viewport.
244   virtual bool IsCurrentlyScrollingViewport() const = 0;
245 
246   // Whether the layer under |viewport_point| is the currently scrolling layer.
247   virtual bool IsCurrentlyScrollingLayerAt(
248       const gfx::Point& viewport_point) const = 0;
249 
250   virtual EventListenerProperties GetEventListenerProperties(
251       EventListenerClass event_class) const = 0;
252 
253   // Returns true if |viewport_point| hits a wheel event handler region that
254   // could block scrolling.
255   virtual bool HasBlockingWheelEventHandlerAt(
256       const gfx::Point& viewport_point) const = 0;
257 
258   // It returns the type of a touch start or move event listener at
259   // |viewport_point|. Whether the page should be given the opportunity to
260   // suppress scrolling by consuming touch events that started at
261   // |viewport_point|, and whether |viewport_point| is on the currently
262   // scrolling layer.
263   // |out_touch_action| is assigned the whitelisted touch action for the
264   // |viewport_point|. In the case there are no touch handlers or touch action
265   // regions, |out_touch_action| is assigned TouchAction::kAuto since the
266   // default touch action is auto.
267   virtual TouchStartOrMoveEventListenerType
268   EventListenerTypeForTouchStartOrMoveAt(const gfx::Point& viewport_point,
269                                          TouchAction* out_touch_action) = 0;
270 
271   // Calling CreateLatencyInfoSwapPromiseMonitor() to get a scoped
272   // LatencyInfoSwapPromiseMonitor. During the life time of the
273   // LatencyInfoSwapPromiseMonitor, if SetNeedsRedraw() or SetNeedsRedrawRect()
274   // is called on LayerTreeHostImpl, the original latency info will be turned
275   // into a LatencyInfoSwapPromise.
276   virtual std::unique_ptr<SwapPromiseMonitor>
277   CreateLatencyInfoSwapPromiseMonitor(ui::LatencyInfo* latency) = 0;
278 
279   // During the lifetime of the returned EventsMetricsManager::ScopedMonitor, if
280   // SetNeedsOneBeginImplFrame() or SetNeedsRedraw() are called on
281   // LayerTreeHostImpl or a scroll animation is updated, |event_metrics| will be
282   // saved for reporting event latency metrics.
283   virtual std::unique_ptr<EventsMetricsManager::ScopedMonitor>
284   GetScopedEventMetricsMonitor(const EventMetrics& event_metrics) = 0;
285 
286   virtual ScrollElasticityHelper* CreateScrollElasticityHelper() = 0;
287 
288   // Called by the single-threaded UI Compositor to get or set the scroll offset
289   // on the impl side. Returns false if |element_id| isn't in the active tree.
290   virtual bool GetScrollOffsetForLayer(ElementId element_id,
291                                        gfx::ScrollOffset* offset) = 0;
292   virtual bool ScrollLayerTo(ElementId element_id,
293                              const gfx::ScrollOffset& offset) = 0;
294 
295   virtual bool ScrollingShouldSwitchtoMainThread() = 0;
296 
297   // Sets the initial and target offset for scroll snapping for the currently
298   // scrolling node and the given natural displacement. Also sets the target
299   // element of the snap's scrolling animation.
300   // |natural_displacement_in_viewport| is the estimated total scrolling for
301   // the active scroll sequence.
302   // Returns false if their is no position to snap to.
303   virtual bool GetSnapFlingInfoAndSetAnimatingSnapTarget(
304       const gfx::Vector2dF& natural_displacement_in_viewport,
305       gfx::Vector2dF* initial_offset,
306       gfx::Vector2dF* target_offset) = 0;
307 
308   // |did_finish| is true if the animation reached its target position (i.e.
309   // it wasn't aborted).
310   virtual void ScrollEndForSnapFling(bool did_finish) = 0;
311 
312  protected:
313   InputHandler() = default;
314   virtual ~InputHandler() = default;
315 };
316 
317 }  // namespace cc
318 
319 #endif  // CC_INPUT_INPUT_HANDLER_H_
320