1 // Copyright 2016 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 #include "ui/events/blink/event_with_callback.h"
6 
7 #include "base/time/time.h"
8 #include "third_party/blink/public/common/input/web_input_event_attribution.h"
9 #include "ui/events/blink/blink_event_util.h"
10 #include "ui/events/blink/did_overscroll_params.h"
11 #include "ui/events/blink/web_input_event_traits.h"
12 
13 using blink::WebInputEvent;
14 using blink::WebGestureEvent;
15 
16 namespace ui {
17 
EventWithCallback(WebScopedInputEvent event,const LatencyInfo & latency,base::TimeTicks timestamp_now,InputHandlerProxy::EventDispositionCallback callback)18 EventWithCallback::EventWithCallback(
19     WebScopedInputEvent event,
20     const LatencyInfo& latency,
21     base::TimeTicks timestamp_now,
22     InputHandlerProxy::EventDispositionCallback callback)
23     : event_(event->Clone()),
24       latency_(latency),
25       creation_timestamp_(timestamp_now),
26       last_coalesced_timestamp_(timestamp_now) {
27   original_events_.emplace_back(std::move(event), latency, std::move(callback));
28 }
29 
EventWithCallback(WebScopedInputEvent event,const LatencyInfo & latency,base::TimeTicks creation_timestamp,base::TimeTicks last_coalesced_timestamp,std::unique_ptr<OriginalEventList> original_events)30 EventWithCallback::EventWithCallback(
31     WebScopedInputEvent event,
32     const LatencyInfo& latency,
33     base::TimeTicks creation_timestamp,
34     base::TimeTicks last_coalesced_timestamp,
35     std::unique_ptr<OriginalEventList> original_events)
36     : event_(std::move(event)),
37       latency_(latency),
38       creation_timestamp_(creation_timestamp),
39       last_coalesced_timestamp_(last_coalesced_timestamp) {
40   if (original_events)
41     original_events_.splice(original_events_.end(), *original_events);
42 }
43 
~EventWithCallback()44 EventWithCallback::~EventWithCallback() {}
45 
CanCoalesceWith(const EventWithCallback & other) const46 bool EventWithCallback::CanCoalesceWith(const EventWithCallback& other) const {
47   return CanCoalesce(other.event(), event());
48 }
49 
SetScrollbarManipulationHandledOnCompositorThread()50 void EventWithCallback::SetScrollbarManipulationHandledOnCompositorThread() {
51   for (auto& original_event : original_events_)
52     original_event.event_->SetScrollbarManipulationHandledOnCompositorThread();
53 }
54 
CoalesceWith(EventWithCallback * other,base::TimeTicks timestamp_now)55 void EventWithCallback::CoalesceWith(EventWithCallback* other,
56                                      base::TimeTicks timestamp_now) {
57   // |other| should be a newer event than |this|.
58   if (other->latency_.trace_id() >= 0 && latency_.trace_id() >= 0)
59     DCHECK_GT(other->latency_.trace_id(), latency_.trace_id());
60 
61   // New events get coalesced into older events, and the newer timestamp
62   // should always be preserved.
63   const base::TimeTicks time_stamp = other->event().TimeStamp();
64   Coalesce(other->event(), event_.get());
65   event_->SetTimeStamp(time_stamp);
66 
67   // When coalescing two input events, we keep the oldest LatencyInfo
68   // since it will represent the longest latency. If it's a GestureScrollUpdate
69   // event, also update the old event's last timestamp and scroll delta using
70   // the newer event's latency info.
71   if (event_->GetType() == WebInputEvent::kGestureScrollUpdate)
72     latency_.CoalesceScrollUpdateWith(other->latency_);
73   other->latency_ = latency_;
74   other->latency_.set_coalesced();
75 
76   // Move original events.
77   original_events_.splice(original_events_.end(), other->original_events_);
78   last_coalesced_timestamp_ = timestamp_now;
79 }
80 
HandledOnCompositorThread(InputHandlerProxy::EventDisposition disposition)81 static bool HandledOnCompositorThread(
82     InputHandlerProxy::EventDisposition disposition) {
83   return (disposition != InputHandlerProxy::DID_NOT_HANDLE &&
84           disposition !=
85               InputHandlerProxy::DID_NOT_HANDLE_NON_BLOCKING_DUE_TO_FLING &&
86           disposition != InputHandlerProxy::DID_HANDLE_NON_BLOCKING);
87 }
88 
RunCallbacks(InputHandlerProxy::EventDisposition disposition,const LatencyInfo & latency,std::unique_ptr<DidOverscrollParams> did_overscroll_params,const blink::WebInputEventAttribution & attribution)89 void EventWithCallback::RunCallbacks(
90     InputHandlerProxy::EventDisposition disposition,
91     const LatencyInfo& latency,
92     std::unique_ptr<DidOverscrollParams> did_overscroll_params,
93     const blink::WebInputEventAttribution& attribution) {
94   // |original_events_| could be empty if this is the scroll event extracted
95   // from the matrix multiplication.
96   if (original_events_.size() == 0)
97     return;
98 
99   // Ack the oldest event with original latency.
100   std::move(original_events_.front().callback_)
101       .Run(disposition, std::move(original_events_.front().event_), latency,
102            did_overscroll_params
103                ? std::make_unique<DidOverscrollParams>(*did_overscroll_params)
104                : nullptr,
105            attribution);
106   original_events_.pop_front();
107 
108   // If the event was handled on compositor thread, ack other events with
109   // coalesced latency to avoid redundant tracking. If not, the event should
110   // be handle on main thread, use the original latency instead.
111   bool handled = HandledOnCompositorThread(disposition);
112   for (auto& coalesced_event : original_events_) {
113     if (handled) {
114       coalesced_event.latency_ = latency;
115       coalesced_event.latency_.set_coalesced();
116     }
117     std::move(coalesced_event.callback_)
118         .Run(disposition, std::move(coalesced_event.event_),
119              coalesced_event.latency_,
120              did_overscroll_params
121                  ? std::make_unique<DidOverscrollParams>(*did_overscroll_params)
122                  : nullptr,
123              attribution);
124   }
125 }
126 
OriginalEventWithCallback(WebScopedInputEvent event,const LatencyInfo & latency,InputHandlerProxy::EventDispositionCallback callback)127 EventWithCallback::OriginalEventWithCallback::OriginalEventWithCallback(
128     WebScopedInputEvent event,
129     const LatencyInfo& latency,
130     InputHandlerProxy::EventDispositionCallback callback)
131     : event_(std::move(event)),
132       latency_(latency),
133       callback_(std::move(callback)) {}
134 
~OriginalEventWithCallback()135 EventWithCallback::OriginalEventWithCallback::~OriginalEventWithCallback() {}
136 
137 }  // namespace ui
138