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