blob: 951cdfc2ceb741033ae40776704559d921965ffa [file] [log] [blame]
// Copyright 2020 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 "cc/metrics/event_metrics.h"
#include <utility>
#include "base/check.h"
#include "base/memory/ptr_util.h"
#include "base/notreached.h"
#include "base/stl_util.h"
namespace cc {
namespace {
constexpr struct {
EventMetrics::EventType metrics_event_type;
ui::EventType ui_event_type;
const char* name;
} kWhitelistedEvents[] = {
#define EVENT_TYPE(name, ui_type) \
{ EventMetrics::EventType::k##name, ui_type, #name }
EVENT_TYPE(MousePressed, ui::ET_MOUSE_PRESSED),
EVENT_TYPE(MouseReleased, ui::ET_MOUSE_RELEASED),
EVENT_TYPE(MouseWheel, ui::ET_MOUSEWHEEL),
EVENT_TYPE(KeyPressed, ui::ET_KEY_PRESSED),
EVENT_TYPE(KeyReleased, ui::ET_KEY_RELEASED),
EVENT_TYPE(TouchPressed, ui::ET_TOUCH_PRESSED),
EVENT_TYPE(TouchReleased, ui::ET_TOUCH_RELEASED),
EVENT_TYPE(TouchMoved, ui::ET_TOUCH_MOVED),
EVENT_TYPE(GestureScrollBegin, ui::ET_GESTURE_SCROLL_BEGIN),
EVENT_TYPE(GestureScrollUpdate, ui::ET_GESTURE_SCROLL_UPDATE),
EVENT_TYPE(GestureScrollEnd, ui::ET_GESTURE_SCROLL_END),
EVENT_TYPE(GestureDoubleTap, ui::ET_GESTURE_DOUBLE_TAP),
EVENT_TYPE(GestureLongPress, ui::ET_GESTURE_LONG_PRESS),
EVENT_TYPE(GestureLongTap, ui::ET_GESTURE_LONG_TAP),
EVENT_TYPE(GestureShowPress, ui::ET_GESTURE_SHOW_PRESS),
EVENT_TYPE(GestureTap, ui::ET_GESTURE_TAP),
EVENT_TYPE(GestureTapCancel, ui::ET_GESTURE_TAP_CANCEL),
EVENT_TYPE(GestureTapDown, ui::ET_GESTURE_TAP_DOWN),
EVENT_TYPE(GestureTapUnconfirmed, ui::ET_GESTURE_TAP_UNCONFIRMED),
EVENT_TYPE(GestureTwoFingerTap, ui::ET_GESTURE_TWO_FINGER_TAP),
#undef EVENT_TYPE
};
static_assert(base::size(kWhitelistedEvents) ==
static_cast<int>(EventMetrics::EventType::kMaxValue) + 1,
"EventMetrics::EventType has changed.");
constexpr struct {
EventMetrics::ScrollType metrics_scroll_type;
ui::ScrollInputType ui_scroll_type;
const char* name;
} kScrollTypes[] = {
#define SCROLL_TYPE(name, ui_type) \
{ EventMetrics::ScrollType::k##name, ui_type, #name }
SCROLL_TYPE(Autoscroll, ui::ScrollInputType::kAutoscroll),
SCROLL_TYPE(Scrollbar, ui::ScrollInputType::kScrollbar),
SCROLL_TYPE(Touchscreen, ui::ScrollInputType::kTouchscreen),
SCROLL_TYPE(Wheel, ui::ScrollInputType::kWheel),
#undef SCROLL_TYPE
};
static_assert(base::size(kScrollTypes) ==
static_cast<int>(EventMetrics::ScrollType::kMaxValue) + 1,
"EventMetrics::ScrollType has changed.");
base::Optional<EventMetrics::EventType> ToWhitelistedEventType(
ui::EventType ui_event_type) {
for (size_t i = 0; i < base::size(kWhitelistedEvents); i++) {
if (ui_event_type == kWhitelistedEvents[i].ui_event_type) {
EventMetrics::EventType metrics_event_type =
static_cast<EventMetrics::EventType>(i);
DCHECK_EQ(metrics_event_type, kWhitelistedEvents[i].metrics_event_type);
return metrics_event_type;
}
}
return base::nullopt;
}
base::Optional<EventMetrics::ScrollType> ToScrollType(
const base::Optional<ui::ScrollInputType>& scroll_input_type) {
if (!scroll_input_type)
return base::nullopt;
for (size_t i = 0; i < base::size(kScrollTypes); i++) {
if (*scroll_input_type == kScrollTypes[i].ui_scroll_type) {
EventMetrics::ScrollType metrics_scroll_type =
static_cast<EventMetrics::ScrollType>(i);
DCHECK_EQ(metrics_scroll_type, kScrollTypes[i].metrics_scroll_type);
return metrics_scroll_type;
}
}
NOTREACHED();
return base::nullopt;
}
} // namespace
std::unique_ptr<EventMetrics> EventMetrics::Create(
ui::EventType type,
base::TimeTicks time_stamp,
base::Optional<ui::ScrollInputType> scroll_input_type) {
base::Optional<EventType> whitelisted_type = ToWhitelistedEventType(type);
if (!whitelisted_type)
return nullptr;
return base::WrapUnique(new EventMetrics(*whitelisted_type, time_stamp,
ToScrollType(scroll_input_type)));
}
EventMetrics::EventMetrics(EventType type,
base::TimeTicks time_stamp,
base::Optional<ScrollType> scroll_type)
: type_(type), time_stamp_(time_stamp), scroll_type_(scroll_type) {}
EventMetrics::EventMetrics(const EventMetrics&) = default;
EventMetrics& EventMetrics::operator=(const EventMetrics&) = default;
const char* EventMetrics::GetTypeName() const {
return kWhitelistedEvents[static_cast<int>(type_)].name;
}
const char* EventMetrics::GetScrollTypeName() const {
DCHECK(scroll_type_) << "Event is not a scroll event.";
return kScrollTypes[static_cast<int>(*scroll_type_)].name;
}
bool EventMetrics::operator==(const EventMetrics& other) const {
return std::tie(type_, time_stamp_, scroll_type_) ==
std::tie(other.type_, other.time_stamp_, other.scroll_type_);
}
// EventMetricsSet
EventMetricsSet::EventMetricsSet() = default;
EventMetricsSet::~EventMetricsSet() = default;
EventMetricsSet::EventMetricsSet(
std::vector<EventMetrics> main_thread_event_metrics,
std::vector<EventMetrics> impl_thread_event_metrics)
: main_event_metrics(std::move(main_thread_event_metrics)),
impl_event_metrics(std::move(impl_thread_event_metrics)) {}
EventMetricsSet::EventMetricsSet(EventMetricsSet&& other) = default;
EventMetricsSet& EventMetricsSet::operator=(EventMetricsSet&& other) = default;
} // namespace cc