blob: cbed0013120417f9caa90fe23ef6505856b2395a [file] [log] [blame]
// 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