blob: 356e9cae3878b4838ff8e9421a477c54039dc6f0 [file] [log] [blame]
Avi Drissman3f7a9d82022-09-08 20:55:421// Copyright 2020 The Chromium Authors
Mohsen Izadia52ab642020-03-03 05:21:272// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CC_METRICS_EVENT_METRICS_H_
6#define CC_METRICS_EVENT_METRICS_H_
7
Omar Elmekkawy171cf7f2023-01-16 16:52:518#include <cstdint>
Mohsen Izadiebb5f2172020-05-14 18:17:539#include <memory>
Arthur Sonzogni5bc3326c2024-02-29 19:39:0510#include <optional>
Jasmine Xiongdc63b5c2022-08-10 06:31:4211#include <string>
Mohsen Izadib1efd8c2020-05-29 17:30:2812#include <vector>
Mohsen Izadiebb5f2172020-05-14 18:17:5313
Keishi Hattori0e45c022021-11-27 09:25:5214#include "base/memory/raw_ptr.h"
Mohsen Izadide23be82020-12-09 02:19:0615#include "base/time/tick_clock.h"
Mohsen Izadia52ab642020-03-03 05:21:2716#include "base/time/time.h"
Violetta Fedotova842ccc32023-02-03 20:59:5317#include "base/types/id_type.h"
Mohsen Izadia52ab642020-03-03 05:21:2718#include "cc/cc_export.h"
Jonathan Ross86b8f3b12024-03-13 19:15:1519#include "components/viz/common/frame_sinks/begin_frame_args.h"
Mohsen Izadia52ab642020-03-03 05:21:2720#include "ui/events/types/event_type.h"
Dave Tapuskafb0ad6e2020-05-04 19:11:0821#include "ui/events/types/scroll_input_type.h"
Violetta Fedotova842ccc32023-02-03 20:59:5322#include "ui/latency/latency_info.h"
Mohsen Izadia52ab642020-03-03 05:21:2723namespace cc {
Mohsen Izadi5efb13432021-12-13 18:24:3324class PinchEventMetrics;
25class ScrollEventMetrics;
26class ScrollUpdateEventMetrics;
Mohsen Izadia52ab642020-03-03 05:21:2727
Mohsen Izadid1d3a422020-03-18 03:17:2228// Data about an event used by CompositorFrameReporter in generating event
29// latency metrics.
Mohsen Izadia52ab642020-03-03 05:21:2730class CC_EXPORT EventMetrics {
31 public:
Mohsen Izadib8878bf72020-11-06 19:16:4232 using List = std::vector<std::unique_ptr<EventMetrics>>;
Violetta Fedotova842ccc32023-02-03 20:59:5333 using TraceId = base::IdType64<class ui::LatencyInfo>;
Sadrul Habib Chowdhury248bce432020-07-03 02:55:3434 // Event types we are interested in. This list should be in the same order as
35 // values of EventLatencyEventType enum from enums.xml file.
Mohsen Izadib1efd8c2020-05-29 17:30:2836 enum class EventType {
37 kMousePressed,
38 kMouseReleased,
39 kMouseWheel,
Avi Drissmanae99ae282024-07-22 20:44:2840 // TODO(crbug.com/40126863): Currently, all EventType::kKeyPressed events
41 // are reported under EventLatency.KeyPressed histogram. This includes both
Alison Gale59c007a2024-04-20 03:05:4042 // key-down and key-char events. Consider reporting them separately.
Mohsen Izadib1efd8c2020-05-29 17:30:2843 kKeyPressed,
44 kKeyReleased,
45 kTouchPressed,
46 kTouchReleased,
47 kTouchMoved,
48 kGestureScrollBegin,
49 kGestureScrollUpdate,
50 kGestureScrollEnd,
Mohsen Izadiab4b0a42020-05-29 23:33:3451 kGestureDoubleTap,
52 kGestureLongPress,
53 kGestureLongTap,
54 kGestureShowPress,
55 kGestureTap,
56 kGestureTapCancel,
57 kGestureTapDown,
58 kGestureTapUnconfirmed,
59 kGestureTwoFingerTap,
Mohsen Izadi8c3ca222020-08-28 16:05:4460 kFirstGestureScrollUpdate,
Mohsen Izadi644b7822020-12-04 03:18:3761 kMouseDragged,
Mohsen Izadi46b73c32021-02-19 19:27:4762 kGesturePinchBegin,
63 kGesturePinchEnd,
64 kGesturePinchUpdate,
Mohsen Izadi3e917672021-07-15 06:01:2865 kInertialGestureScrollUpdate,
Navin Ramsaroop2949bf152023-05-31 22:01:4166 kMouseMoved,
67 kMaxValue = kMouseMoved,
Mohsen Izadib1efd8c2020-05-29 17:30:2868 };
69
Mohsen Izadide23be82020-12-09 02:19:0670 // Stages of event dispatch in different processes/threads.
71 enum class DispatchStage {
72 kGenerated,
Violetta Fedotovac6b2fb4f2023-04-21 10:54:3973 // 'kScrollsBlockingTouchDispatchedToRenderer' is used by Scroll events to
74 // understand when a corresponding TouchMove event arrived in the Browser
75 // Main. If the related TouchMove wasn't blocking, this stage field is not
76 // set.
77 kScrollsBlockingTouchDispatchedToRenderer,
Violetta Fedotovae38c0332022-09-02 17:48:2278 kArrivedInBrowserMain,
Mohsen Izadide23be82020-12-09 02:19:0679 kArrivedInRendererCompositor,
80 kRendererCompositorStarted,
81 kRendererCompositorFinished,
Mohsen Izadidafa8ac32020-12-09 15:45:1982 kRendererMainStarted,
83 kRendererMainFinished,
84 kMaxValue = kRendererMainFinished,
Mohsen Izadide23be82020-12-09 02:19:0685 };
86
Violetta Fedotovac6b2fb4f2023-04-21 10:54:3987 static std::unique_ptr<EventMetrics> Create(ui::EventType type,
Kartar Singhb5098a6392023-07-24 15:24:4988 base::TimeTicks timestamp,
Arthur Sonzognica067f262023-11-10 14:18:1089 std::optional<TraceId> trace_id);
Violetta Fedotovac6b2fb4f2023-04-21 10:54:3990
Mohsen Izadide23be82020-12-09 02:19:0691 // Returns a new instance if the event is of a type we are interested in.
Mohsen Izadi5efb13432021-12-13 18:24:3392 // Otherwise, returns `nullptr`. For scroll and pinch events, use the
93 // appropriate subcalss instead.
Violetta Fedotovac6b2fb4f2023-04-21 10:54:3994 static std::unique_ptr<EventMetrics> Create(
95 ui::EventType type,
96 base::TimeTicks timestamp,
Kartar Singhb5098a6392023-07-24 15:24:4997 base::TimeTicks arrived_in_browser_main_timestamp,
Arthur Sonzognica067f262023-11-10 14:18:1098 std::optional<TraceId> trace_id);
Mohsen Izadide23be82020-12-09 02:19:0699
100 // Similar to `Create()` with an extra `base::TickClock` to use in tests.
101 static std::unique_ptr<EventMetrics> CreateForTesting(
102 ui::EventType type,
Mohsen Izadide23be82020-12-09 02:19:06103 base::TimeTicks timestamp,
Violetta Fedotovac6b2fb4f2023-04-21 10:54:39104 base::TimeTicks arrived_in_browser_main_timestamp,
Kartar Singhc1dbdfd2023-08-22 14:30:34105 const base::TickClock* tick_clock,
Arthur Sonzognica067f262023-11-10 14:18:10106 std::optional<TraceId> trace_id);
Mohsen Izadide23be82020-12-09 02:19:06107
108 // Used to create an instance for an event generated based on an existing
109 // event. If the new event is of an interesting type, we expect that the
110 // existing event is also of an interesting type in which case `existing` is
Mohsen Izadi5efb13432021-12-13 18:24:33111 // not `nullptr` and timestamps (up to and including `last_dispatch_stage`)
112 // and tick clock from `existing` will be used for the new metrics object. If
113 // the new event is not an interesting one, return value would be `nullptr`.
114 // For scroll and pinch events, use the appropriate subclass instead.
Mohsen Izadide23be82020-12-09 02:19:06115 static std::unique_ptr<EventMetrics> CreateFromExisting(
116 ui::EventType type,
Mohsen Izadide23be82020-12-09 02:19:06117 DispatchStage last_dispatch_stage,
118 const EventMetrics* existing);
Mohsen Izadia52ab642020-03-03 05:21:27119
Mohsen Izadi5efb13432021-12-13 18:24:33120 virtual ~EventMetrics();
Mohsen Izadid1d3a422020-03-18 03:17:22121
Mohsen Izadi5efb13432021-12-13 18:24:33122 EventMetrics& operator=(const EventMetrics&) = delete;
Mohsen Izadide23be82020-12-09 02:19:06123
Mohsen Izadib1efd8c2020-05-29 17:30:28124 EventType type() const { return type_; }
125
Arthur Sonzognica067f262023-11-10 14:18:10126 std::optional<TraceId> trace_id() const { return trace_id_; }
Kartar Singhb5098a6392023-07-24 15:24:49127
Mohsen Izadib1efd8c2020-05-29 17:30:28128 // Returns a string representing event type.
Mohsen Izadid1d3a422020-03-18 03:17:22129 const char* GetTypeName() const;
Yichena8c4bd92022-10-27 00:47:00130 static const char* GetTypeName(EventType type);
Mohsen Izadid1d3a422020-03-18 03:17:22131
Mohsen Izadi820e5e42023-01-12 02:00:07132 // Returns custom histogram bucketing for the metric. If returns `nullopt`,
133 // default bucketing will be used.
134 struct HistogramBucketing {
135 base::TimeDelta min;
136 base::TimeDelta max;
137 size_t count;
138 const char* version_suffix;
139 };
Arthur Sonzognica067f262023-11-10 14:18:10140 const std::optional<HistogramBucketing>& GetHistogramBucketing() const;
Mohsen Izadi820e5e42023-01-12 02:00:07141
Jasmine Xiongdc63b5c2022-08-10 06:31:42142 void SetHighLatencyStage(const std::string& stage);
143 const std::vector<std::string>& GetHighLatencyStages() const {
144 return high_latency_stages_;
145 }
146 void ClearHighLatencyStagesForTesting() { high_latency_stages_.clear(); }
147
Mohsen Izadide23be82020-12-09 02:19:06148 void SetDispatchStageTimestamp(DispatchStage stage);
149 base::TimeTicks GetDispatchStageTimestamp(DispatchStage stage) const;
150
Mohsen Izadidafa8ac32020-12-09 15:45:19151 // Resets the metrics object to dispatch stage `stage` by setting timestamps
152 // of dispatch stages after `stage` to null timestamp,
Mohsen Izadide23be82020-12-09 02:19:06153 void ResetToDispatchStage(DispatchStage stage);
154
behdaddeab7ba92021-05-10 16:25:21155 bool HasSmoothInputEvent() const;
156
Mohsen Izadi5efb13432021-12-13 18:24:33157 virtual ScrollEventMetrics* AsScroll();
158 const ScrollEventMetrics* AsScroll() const;
Mohsen Izadide23be82020-12-09 02:19:06159
Mohsen Izadi5efb13432021-12-13 18:24:33160 virtual ScrollUpdateEventMetrics* AsScrollUpdate();
161 const ScrollUpdateEventMetrics* AsScrollUpdate() const;
162
163 virtual PinchEventMetrics* AsPinch();
164 const PinchEventMetrics* AsPinch() const;
165
166 virtual std::unique_ptr<EventMetrics> Clone() const;
167
Mohsen Izadi6b7ffaafe2022-05-31 17:52:11168 bool should_record_tracing() const { return should_record_tracing_; }
169 void tracing_recorded() {
170 DCHECK(should_record_tracing_);
171 should_record_tracing_ = false;
Mohsen Izadid32e777a2022-02-15 22:23:42172 }
173
Steve Kobes134c6e212022-06-09 20:39:41174 bool requires_main_thread_update() const {
175 return requires_main_thread_update_;
176 }
177 void set_requires_main_thread_update() {
178 DCHECK(!requires_main_thread_update_);
179 requires_main_thread_update_ = true;
180 }
181
Mohsen Izadi5efb13432021-12-13 18:24:33182 protected:
183 EventMetrics(EventType type,
184 base::TimeTicks timestamp,
Kartar Singhb5098a6392023-07-24 15:24:49185 const base::TickClock* tick_clock,
Arthur Sonzognica067f262023-11-10 14:18:10186 std::optional<TraceId> trace_id);
Mohsen Izadi6b7ffaafe2022-05-31 17:52:11187
Violetta Fedotovae38c0332022-09-02 17:48:22188 EventMetrics(EventType type,
189 base::TimeTicks timestamp,
190 base::TimeTicks arrived_in_browser_main_timestamp,
Kartar Singhb5098a6392023-07-24 15:24:49191 const base::TickClock* tick_clock,
Arthur Sonzognica067f262023-11-10 14:18:10192 std::optional<TraceId> trace_id);
Violetta Fedotovae38c0332022-09-02 17:48:22193
Mohsen Izadi6b7ffaafe2022-05-31 17:52:11194 // Creates a clone of `other` that might be used in creating `EventMetrics`
195 // objects for some injected events. Since this object itself does not
196 // directly correspond to an event, it won't be used in recording trace
197 // events.
Mohsen Izadi5efb13432021-12-13 18:24:33198 EventMetrics(const EventMetrics& other);
199
200 // Copy timestamps of dispatch stages (up to and including
201 // `last_dispatch_stage`) from `other`.
202 void CopyTimestampsFrom(const EventMetrics& other,
203 DispatchStage last_dispatch_stage);
Mohsen Izadia52ab642020-03-03 05:21:27204
Violetta Fedotovac6b2fb4f2023-04-21 10:54:39205 void SetDispatchStageTimestamp(DispatchStage stage,
206 base::TimeTicks timestamp);
207
Mohsen Izadia52ab642020-03-03 05:21:27208 private:
Mohsen Izadi5efb13432021-12-13 18:24:33209 friend class ScrollEventMetrics;
210 friend class ScrollUpdateEventMetrics;
211
Mohsen Izadide23be82020-12-09 02:19:06212 static std::unique_ptr<EventMetrics> CreateInternal(
213 ui::EventType type,
Mohsen Izadide23be82020-12-09 02:19:06214 base::TimeTicks timestamp,
Violetta Fedotovac6b2fb4f2023-04-21 10:54:39215 base::TimeTicks arrived_in_browser_main_timestamp,
Kartar Singhb5098a6392023-07-24 15:24:49216 const base::TickClock* tick_clock,
Arthur Sonzognica067f262023-11-10 14:18:10217 std::optional<TraceId> trace_id);
Mohsen Izadide23be82020-12-09 02:19:06218
Mohsen Izadib1efd8c2020-05-29 17:30:28219 EventType type_;
Mohsen Izadid1d3a422020-03-18 03:17:22220
Jasmine Xiongdc63b5c2022-08-10 06:31:42221 std::vector<std::string> high_latency_stages_;
222
Keishi Hattori0e45c022021-11-27 09:25:52223 const raw_ptr<const base::TickClock> tick_clock_;
Mohsen Izadide23be82020-12-09 02:19:06224
225 // Timestamps of different stages of event dispatch. Timestamps are set as the
226 // event moves forward in the pipeline. In the end, some stages might not have
227 // a timestamp which means the event did not pass those stages.
228 base::TimeTicks
229 dispatch_stage_timestamps_[static_cast<int>(DispatchStage::kMaxValue) +
230 1];
Mohsen Izadid32e777a2022-02-15 22:23:42231
Mohsen Izadi6b7ffaafe2022-05-31 17:52:11232 // Determines whether a tracing event should be recorded for this object or
233 // not. This is `true` by default and set to `false` after a tracing event is
234 // recorded to avoid multiple recordings. Also, it is `false` for cloned
235 // objects as they are not meant to be recorded in tracings.
236 bool should_record_tracing_ = true;
Steve Kobes134c6e212022-06-09 20:39:41237
238 // This is set on an EventMetrics object that comes from the impl thread, if
239 // the visual update from the event requires the main thread. Currently used
240 // for GestureScrollUpdate with scroll unification, when the scroller isn't
241 // composited or has main-thread scrolling reasons on the ScrollNode.
242 bool requires_main_thread_update_ = false;
Kartar Singhb5098a6392023-07-24 15:24:49243
244 // This is a trace id of an input event. It can be null for events which don't
245 // have a corresponding input, for example a generated event based on existing
246 // event.
Arthur Sonzognica067f262023-11-10 14:18:10247 std::optional<TraceId> trace_id_;
Mohsen Izadia52ab642020-03-03 05:21:27248};
249
Mohsen Izadi5efb13432021-12-13 18:24:33250class CC_EXPORT ScrollEventMetrics : public EventMetrics {
251 public:
252 // Type of scroll events. This list should be in the same order as values of
253 // `EventLatencyScrollInputType` enum from enums.xml file.
254 enum class ScrollType {
255 kAutoscroll,
256 kScrollbar,
257 kTouchscreen,
258 kWheel,
259 kMaxValue = kWheel,
260 };
261
262 // Returns a new instance if the event is of a type we are interested in.
263 // Otherwise, returns `nullptr`. Should only be used for scroll events other
264 // than scroll-update.
Violetta Fedotovac6b2fb4f2023-04-21 10:54:39265 // The |blocking_touch_dispatched_to_renderer| must be not null only for
266 // scrolls which corresponding TouchMove was blocking.
Violetta Fedotovae38c0332022-09-02 17:48:22267 //
268 // TODO(b/224960731): Fix tests and stop supporting the case when
269 // `arrived_in_browser_main_timestamp` is null.
Mohsen Izadi5efb13432021-12-13 18:24:33270 static std::unique_ptr<ScrollEventMetrics> Create(
271 ui::EventType type,
272 ui::ScrollInputType input_type,
273 bool is_inertial,
Violetta Fedotovae38c0332022-09-02 17:48:22274 base::TimeTicks timestamp,
Violetta Fedotovac6b2fb4f2023-04-21 10:54:39275 base::TimeTicks arrived_in_browser_main_timestamp,
Kartar Singhb5098a6392023-07-24 15:24:49276 base::TimeTicks blocking_touch_dispatched_to_renderer,
Arthur Sonzognica067f262023-11-10 14:18:10277 std::optional<TraceId> trace_id);
Violetta Fedotovae38c0332022-09-02 17:48:22278
279 // Prefer to use `Create()` above. This method is used only by the Browser
280 // process which have own breakdowns.
Violetta Fedotovac6b2fb4f2023-04-21 10:54:39281 // Similar to `Create()` above but doesn't set kArrivedInBrowserMain and
282 // kScrollsBlockingTouchDispatchedToRenderer.
Violetta Fedotovae38c0332022-09-02 17:48:22283 static std::unique_ptr<ScrollEventMetrics> CreateForBrowser(
284 ui::EventType type,
285 ui::ScrollInputType input_type,
286 bool is_inertial,
Kartar Singhb5098a6392023-07-24 15:24:49287 base::TimeTicks timestamp,
Arthur Sonzognica067f262023-11-10 14:18:10288 std::optional<TraceId> trace_id);
Mohsen Izadi5efb13432021-12-13 18:24:33289
290 // Similar to `Create()` with an extra `base::TickClock` to use in tests.
291 // Should only be used for scroll events other than scroll-update.
292 static std::unique_ptr<ScrollEventMetrics> CreateForTesting(
293 ui::EventType type,
294 ui::ScrollInputType input_type,
295 bool is_inertial,
296 base::TimeTicks timestamp,
Violetta Fedotovae38c0332022-09-02 17:48:22297 base::TimeTicks arrived_in_browser_main_timestamp,
Mohsen Izadi5efb13432021-12-13 18:24:33298 const base::TickClock* tick_clock);
299
300 // Used to create an instance for an event generated based on an existing
301 // event. If the new event is of an interesting type, we expect that the
302 // existing event is also of an interesting type in which case `existing` is
303 // not `nullptr` and timestamps (up to and including `last_dispatch_stage`)
304 // and tick clock from `existing` will be used for the new metrics object. If
305 // the new event is not an interesting one, return value would be `nullptr`.
306 // Should only be used for scroll events other than scroll-update.
307 static std::unique_ptr<ScrollEventMetrics> CreateFromExisting(
308 ui::EventType type,
309 ui::ScrollInputType input_type,
310 bool is_inertial,
311 DispatchStage last_dispatch_stage,
312 const EventMetrics* existing);
313
314 ~ScrollEventMetrics() override;
315
316 ScrollType scroll_type() const { return scroll_type_; }
317
318 // Returns a string representing input type for a scroll event.
319 const char* GetScrollTypeName() const;
320
321 ScrollEventMetrics* AsScroll() override;
322
323 std::unique_ptr<EventMetrics> Clone() const override;
324
Jonathan Ross86b8f3b12024-03-13 19:15:15325 void set_begin_frame_args(const viz::BeginFrameArgs& args) { args_ = args; }
326
327 const viz::BeginFrameArgs& begin_frame_args() const { return args_; }
328
Jonathan Ross379ca482025-06-02 14:21:15329 void set_did_scroll(bool did_scroll) { did_scroll_ = did_scroll; }
330 bool did_scroll() const { return did_scroll_; }
331
Mohsen Izadi5efb13432021-12-13 18:24:33332 protected:
333 ScrollEventMetrics(EventType type,
334 ScrollType scroll_type,
335 base::TimeTicks timestamp,
Violetta Fedotovae38c0332022-09-02 17:48:22336 base::TimeTicks arrived_in_browser_main_timestamp,
Kartar Singhb5098a6392023-07-24 15:24:49337 const base::TickClock* tick_clock,
Arthur Sonzognica067f262023-11-10 14:18:10338 std::optional<TraceId> trace_id);
Mohsen Izadi5efb13432021-12-13 18:24:33339 ScrollEventMetrics(const ScrollEventMetrics&);
340
341 private:
342 static std::unique_ptr<ScrollEventMetrics> CreateInternal(
343 ui::EventType type,
344 ui::ScrollInputType input_type,
345 bool is_inertial,
346 base::TimeTicks timestamp,
Violetta Fedotovae38c0332022-09-02 17:48:22347 base::TimeTicks arrived_in_browser_main_timestamp,
Kartar Singhb5098a6392023-07-24 15:24:49348 const base::TickClock* tick_clock,
Arthur Sonzognica067f262023-11-10 14:18:10349 std::optional<TraceId> trace_id);
Mohsen Izadi5efb13432021-12-13 18:24:33350
351 // Type of the input device for the event.
352 ScrollType scroll_type_;
Jonathan Ross86b8f3b12024-03-13 19:15:15353
354 // The active viz::BeginFrameArgs when the event arrived in the Renderer.
355 // These may not match those of CompositorFrameReporter for which the event
356 // is eventually displayed.
357 viz::BeginFrameArgs args_;
Jonathan Ross379ca482025-06-02 14:21:15358
359 // The scroll delta may not be actually applied. Event if it is consumed. This
360 // denotes that a scroll did actually occur.
361 bool did_scroll_ = false;
Mohsen Izadi5efb13432021-12-13 18:24:33362};
363
364class CC_EXPORT ScrollUpdateEventMetrics : public ScrollEventMetrics {
365 public:
366 // Determines whether a scroll-update event is the first one in a gesture
367 // scroll sequence or not.
368 enum class ScrollUpdateType {
369 kStarted,
370 kContinued,
371 kMaxValue = kContinued,
372 };
373
374 // Returns a new instance if the event is of a type we are interested in.
375 // Otherwise, returns `nullptr`. Should only be used for scroll-update events.
Jonathan Ross6f1642e2024-05-10 14:15:18376 // The `arrived_in_browser_main_timestamp` can be null for events that were
377 // generated synthetically within the Renderer. The
378 // `blocking_touch_dispatched_to_renderer` must be not null only for
Violetta Fedotovac6b2fb4f2023-04-21 10:54:39379 // scrolls which corresponding TouchMove was blocking.
Violetta Fedotovae38c0332022-09-02 17:48:22380 //
Jonathan Ross6f1642e2024-05-10 14:15:18381 // TODO(b/329346768): Build `trace_id` generation for synthetic events.
Mohsen Izadi5efb13432021-12-13 18:24:33382 static std::unique_ptr<ScrollUpdateEventMetrics> Create(
383 ui::EventType type,
384 ui::ScrollInputType input_type,
385 bool is_inertial,
386 ScrollUpdateType scroll_update_type,
387 float delta,
Violetta Fedotovae38c0332022-09-02 17:48:22388 base::TimeTicks timestamp,
Violetta Fedotova842ccc32023-02-03 20:59:53389 base::TimeTicks arrived_in_browser_main_timestamp,
Jonathan Ross6f1642e2024-05-10 14:15:18390 base::TimeTicks blocking_touch_dispatched_to_renderer,
391 std::optional<TraceId> trace_id);
Violetta Fedotovae38c0332022-09-02 17:48:22392
393 // Prefer to use `Create()` above. This method is used only by the Browser
394 // process which have own breakdowns.
Violetta Fedotovac6b2fb4f2023-04-21 10:54:39395 // Similar to `Create()` above but doesn't set kArrivedInBrowserMain and
396 // kScrollsBlockingTouchDispatchedToRenderer.
Violetta Fedotovae38c0332022-09-02 17:48:22397 static std::unique_ptr<ScrollUpdateEventMetrics> CreateForBrowser(
398 ui::EventType type,
399 ui::ScrollInputType input_type,
400 bool is_inertial,
401 ScrollUpdateType scroll_update_type,
402 float delta,
Violetta Fedotova842ccc32023-02-03 20:59:53403 base::TimeTicks timestamp,
404 TraceId trace_id);
Mohsen Izadi5efb13432021-12-13 18:24:33405
406 // Similar to `Create()` with an extra `base::TickClock` to use in tests.
407 // Should only be used for scroll-update events.
408 static std::unique_ptr<ScrollUpdateEventMetrics> CreateForTesting(
409 ui::EventType type,
410 ui::ScrollInputType input_type,
411 bool is_inertial,
412 ScrollUpdateType scroll_update_type,
413 float delta,
414 base::TimeTicks timestamp,
Violetta Fedotovae38c0332022-09-02 17:48:22415 base::TimeTicks arrived_in_browser_main_timestamp,
Kartar Singhc1dbdfd2023-08-22 14:30:34416 const base::TickClock* tick_clock,
Arthur Sonzognica067f262023-11-10 14:18:10417 std::optional<TraceId> trace_id);
Mohsen Izadi5efb13432021-12-13 18:24:33418
419 // Used to create an instance for an event generated based on an existing
420 // event. If the new event is of an interesting type, we expect that the
421 // existing event is also of an interesting type in which case `existing` is
422 // not `nullptr` and timestamps (up to and including `last_dispatch_stage`)
423 // and tick clock from `existing` will be used for the new metrics object. If
424 // the new event is not an interesting one, return value would be `nullptr`.
425 // Should only be used for scroll-update events.
426 static std::unique_ptr<ScrollUpdateEventMetrics> CreateFromExisting(
427 ui::EventType type,
428 ui::ScrollInputType input_type,
429 bool is_inertial,
430 ScrollUpdateType scroll_update_type,
431 float delta,
432 DispatchStage last_dispatch_stage,
433 const EventMetrics* existing);
434
435 ~ScrollUpdateEventMetrics() override;
436
437 void CoalesceWith(const ScrollUpdateEventMetrics& newer_scroll_update);
438
439 ScrollUpdateEventMetrics* AsScrollUpdate() override;
440
441 float delta() const { return delta_; }
442
443 float predicted_delta() const { return predicted_delta_; }
Omar Elmekkawy171cf7f2023-01-16 16:52:51444
Kartar Singh554930c2023-05-22 11:28:22445 int32_t coalesced_event_count() const { return coalesced_event_count_; }
Violetta Fedotova842ccc32023-02-03 20:59:53446
Mohsen Izadi5efb13432021-12-13 18:24:33447 void set_predicted_delta(float predicted_delta) {
448 predicted_delta_ = predicted_delta;
449 }
450
451 base::TimeTicks last_timestamp() const { return last_timestamp_; }
452
453 std::unique_ptr<EventMetrics> Clone() const override;
454
Arthur Sonzognica067f262023-11-10 14:18:10455 void set_is_janky_scrolled_frame(std::optional<bool> is_janky) {
Kartar Singh748fc332023-07-28 19:07:44456 is_janky_scrolled_frame_ = is_janky;
457 }
Arthur Sonzognica067f262023-11-10 14:18:10458 std::optional<bool> is_janky_scrolled_frame() const {
Kartar Singh748fc332023-07-28 19:07:44459 return is_janky_scrolled_frame_;
460 }
461
Petr Cermak04dd1bc2025-03-24 13:32:35462 void set_is_janky_scrolled_frame_v3(std::optional<bool> is_janky) {
463 is_janky_scrolled_frame_v3_ = is_janky;
464 }
465 std::optional<bool> is_janky_scrolled_frame_v3() const {
466 return is_janky_scrolled_frame_v3_;
467 }
468
Mohsen Izadi5efb13432021-12-13 18:24:33469 protected:
470 ScrollUpdateEventMetrics(EventType type,
471 ScrollType scroll_type,
472 ScrollUpdateType scroll_update_type,
473 float delta,
474 base::TimeTicks timestamp,
Violetta Fedotovae38c0332022-09-02 17:48:22475 base::TimeTicks arrived_in_browser_main_timestamp,
Violetta Fedotova842ccc32023-02-03 20:59:53476 const base::TickClock* tick_clock,
Arthur Sonzognica067f262023-11-10 14:18:10477 std::optional<TraceId> trace_id);
Mohsen Izadi5efb13432021-12-13 18:24:33478 ScrollUpdateEventMetrics(const ScrollUpdateEventMetrics&);
479
480 private:
481 static std::unique_ptr<ScrollUpdateEventMetrics> CreateInternal(
482 ui::EventType type,
483 ui::ScrollInputType input_type,
484 bool is_inertial,
485 ScrollUpdateType scroll_update_type,
486 float delta,
487 base::TimeTicks timestamp,
Violetta Fedotovae38c0332022-09-02 17:48:22488 base::TimeTicks arrived_in_browser_main_timestamp,
Violetta Fedotova842ccc32023-02-03 20:59:53489 const base::TickClock* tick_clock,
Arthur Sonzognica067f262023-11-10 14:18:10490 std::optional<TraceId> trace_id);
Mohsen Izadi5efb13432021-12-13 18:24:33491
492 float delta_;
493 float predicted_delta_;
494
495 // Timestamp of the last event coalesced into this one.
496 base::TimeTicks last_timestamp_;
Omar Elmekkawy171cf7f2023-01-16 16:52:51497
498 // Total events that were coalesced into this into this ScrollUpdate
499 int32_t coalesced_event_count_ = 1;
Kartar Singh748fc332023-07-28 19:07:44500
Arthur Sonzognica067f262023-11-10 14:18:10501 std::optional<bool> is_janky_scrolled_frame_ = std::nullopt;
Petr Cermak04dd1bc2025-03-24 13:32:35502 std::optional<bool> is_janky_scrolled_frame_v3_ = std::nullopt;
Mohsen Izadi5efb13432021-12-13 18:24:33503};
504
505class CC_EXPORT PinchEventMetrics : public EventMetrics {
506 public:
507 // Type of pinch events. This list should be in the same order as values of
508 // `EventLatencyPinchInputType` enum from enums.xml file.
509 enum class PinchType {
510 kTouchpad,
511 kTouchscreen,
512 kMaxValue = kTouchscreen,
513 };
514
515 // Returns a new instance if the event is of a type we are interested in.
516 // Otherwise, returns `nullptr`. Should only be used for pinch events.
517 static std::unique_ptr<PinchEventMetrics> Create(
518 ui::EventType type,
519 ui::ScrollInputType input_type,
Kartar Singhb5098a6392023-07-24 15:24:49520 base::TimeTicks timestamp,
521 TraceId trace_id);
Mohsen Izadi5efb13432021-12-13 18:24:33522
523 // Similar to `Create()` with an extra `base::TickClock` to use in tests.
524 // Should only be used for pinch events.
525 static std::unique_ptr<PinchEventMetrics> CreateForTesting(
526 ui::EventType type,
527 ui::ScrollInputType input_type,
528 base::TimeTicks timestamp,
529 const base::TickClock* tick_clock);
530
531 ~PinchEventMetrics() override;
532
533 PinchType pinch_type() const { return pinch_type_; }
534
535 // Returns a string representing input type for a pinch event. Should only be
536 // called for pinch events.
537 const char* GetPinchTypeName() const;
538
539 PinchEventMetrics* AsPinch() override;
540
541 std::unique_ptr<EventMetrics> Clone() const override;
542
543 protected:
544 PinchEventMetrics(EventType type,
545 PinchType pinch_type,
546 base::TimeTicks timestamp,
Kartar Singhb5098a6392023-07-24 15:24:49547 const base::TickClock* tick_clock,
Arthur Sonzognica067f262023-11-10 14:18:10548 std::optional<TraceId> trace_id);
Mohsen Izadi5efb13432021-12-13 18:24:33549 PinchEventMetrics(const PinchEventMetrics&);
550
551 private:
552 static std::unique_ptr<PinchEventMetrics> CreateInternal(
553 ui::EventType type,
554 ui::ScrollInputType input_type,
555 base::TimeTicks timestamp,
Kartar Singhb5098a6392023-07-24 15:24:49556 const base::TickClock* tick_clock,
Arthur Sonzognica067f262023-11-10 14:18:10557 std::optional<TraceId> trace_id);
Mohsen Izadi5efb13432021-12-13 18:24:33558
559 PinchType pinch_type_;
560};
561
Mingjing Zhang6beed0b52020-04-02 02:00:28562// Struct storing event metrics from both main and impl threads.
563struct CC_EXPORT EventMetricsSet {
564 EventMetricsSet();
565 ~EventMetricsSet();
Mohsen Izadib8878bf72020-11-06 19:16:42566 EventMetricsSet(EventMetrics::List main_thread_event_metrics,
Stacy Gaikovaia7c07f1f2025-05-28 21:47:03567 EventMetrics::List impl_thread_event_metrics,
568 EventMetrics::List raster_thread_event_metrics);
Mingjing Zhang6beed0b52020-04-02 02:00:28569 EventMetricsSet(EventMetricsSet&&);
570 EventMetricsSet& operator=(EventMetricsSet&&);
571
572 EventMetricsSet(const EventMetricsSet&) = delete;
573 EventMetricsSet& operator=(const EventMetricsSet&) = delete;
574
Mohsen Izadib8878bf72020-11-06 19:16:42575 EventMetrics::List main_event_metrics;
576 EventMetrics::List impl_event_metrics;
Stacy Gaikovaia7c07f1f2025-05-28 21:47:03577 EventMetrics::List raster_event_metrics;
Mingjing Zhang6beed0b52020-04-02 02:00:28578};
579
Mohsen Izadia52ab642020-03-03 05:21:27580} // namespace cc
581
582#endif // CC_METRICS_EVENT_METRICS_H_