| // Copyright 2016 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 "ui/events/blink/event_with_callback.h" |
| |
| #include "base/time/time.h" |
| #include "ui/events/blink/blink_event_util.h" |
| #include "ui/events/blink/did_overscroll_params.h" |
| #include "ui/events/blink/web_input_event_traits.h" |
| |
| using blink::WebInputEvent; |
| using blink::WebGestureEvent; |
| |
| namespace ui { |
| |
| EventWithCallback::EventWithCallback( |
| WebScopedInputEvent event, |
| const LatencyInfo& latency, |
| base::TimeTicks timestamp_now, |
| InputHandlerProxy::EventDispositionCallback callback) |
| : event_(WebInputEventTraits::Clone(*event)), |
| latency_(latency), |
| creation_timestamp_(timestamp_now), |
| last_coalesced_timestamp_(timestamp_now) { |
| original_events_.emplace_back(std::move(event), latency, std::move(callback)); |
| } |
| |
| EventWithCallback::EventWithCallback( |
| WebScopedInputEvent event, |
| const LatencyInfo& latency, |
| base::TimeTicks creation_timestamp, |
| base::TimeTicks last_coalesced_timestamp, |
| std::unique_ptr<OriginalEventList> original_events) |
| : event_(std::move(event)), |
| latency_(latency), |
| creation_timestamp_(creation_timestamp), |
| last_coalesced_timestamp_(last_coalesced_timestamp) { |
| if (original_events) |
| original_events_.splice(original_events_.end(), *original_events); |
| } |
| |
| EventWithCallback::~EventWithCallback() {} |
| |
| bool EventWithCallback::CanCoalesceWith(const EventWithCallback& other) const { |
| return CanCoalesce(other.event(), event()); |
| } |
| |
| void EventWithCallback::CoalesceWith(EventWithCallback* other, |
| base::TimeTicks timestamp_now) { |
| // |other| should be a newer event than |this|. |
| if (other->latency_.trace_id() >= 0 && latency_.trace_id() >= 0) |
| DCHECK_GT(other->latency_.trace_id(), latency_.trace_id()); |
| |
| // New events get coalesced into older events, and the newer timestamp |
| // should always be preserved. |
| const base::TimeTicks time_stamp = other->event().TimeStamp(); |
| Coalesce(other->event(), event_.get()); |
| event_->SetTimeStamp(time_stamp); |
| |
| // When coalescing two input events, we keep the oldest LatencyInfo |
| // since it will represent the longest latency. If it's a GestureScrollUpdate |
| // event, also update the old event's last timestamp and scroll delta using |
| // the newer event's latency info. |
| if (event_->GetType() == WebInputEvent::kGestureScrollUpdate) |
| latency_.CoalesceScrollUpdateWith(other->latency_); |
| other->latency_ = latency_; |
| other->latency_.set_coalesced(); |
| |
| // Move original events. |
| original_events_.splice(original_events_.end(), other->original_events_); |
| last_coalesced_timestamp_ = timestamp_now; |
| } |
| |
| static bool HandledOnCompositorThread( |
| InputHandlerProxy::EventDisposition disposition) { |
| return (disposition != InputHandlerProxy::DID_NOT_HANDLE && |
| disposition != |
| InputHandlerProxy::DID_NOT_HANDLE_NON_BLOCKING_DUE_TO_FLING && |
| disposition != InputHandlerProxy::DID_HANDLE_NON_BLOCKING); |
| } |
| |
| void EventWithCallback::RunCallbacks( |
| InputHandlerProxy::EventDisposition disposition, |
| const LatencyInfo& latency, |
| std::unique_ptr<DidOverscrollParams> did_overscroll_params) { |
| // |original_events_| could be empty if this is the scroll event extracted |
| // from the matrix multiplication. |
| if (original_events_.size() == 0) |
| return; |
| |
| // Ack the oldest event with original latency. |
| std::move(original_events_.front().callback_) |
| .Run(disposition, std::move(original_events_.front().event_), latency, |
| did_overscroll_params |
| ? std::make_unique<DidOverscrollParams>(*did_overscroll_params) |
| : nullptr); |
| original_events_.pop_front(); |
| |
| // If the event was handled on compositor thread, ack other events with |
| // coalesced latency to avoid redundant tracking. If not, the event should |
| // be handle on main thread, use the original latency instead. |
| bool handled = HandledOnCompositorThread(disposition); |
| for (auto& coalesced_event : original_events_) { |
| if (handled) { |
| coalesced_event.latency_ = latency; |
| coalesced_event.latency_.set_coalesced(); |
| } |
| std::move(coalesced_event.callback_) |
| .Run(disposition, std::move(coalesced_event.event_), |
| coalesced_event.latency_, |
| did_overscroll_params |
| ? std::make_unique<DidOverscrollParams>(*did_overscroll_params) |
| : nullptr); |
| } |
| } |
| |
| EventWithCallback::OriginalEventWithCallback::OriginalEventWithCallback( |
| WebScopedInputEvent event, |
| const LatencyInfo& latency, |
| InputHandlerProxy::EventDispositionCallback callback) |
| : event_(std::move(event)), |
| latency_(latency), |
| callback_(std::move(callback)) {} |
| |
| EventWithCallback::OriginalEventWithCallback::~OriginalEventWithCallback() {} |
| |
| } // namespace ui |