#include "third_party/blink/renderer/core/timing/responsiveness_metrics.h"
#include <memory>
#include "base/metrics/histogram_functions.h"
#include "base/rand_util.h"
#include "base/strings/strcat.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_id_helper.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/responsiveness_metrics/user_interaction_latency.h"
#include "third_party/blink/renderer/core/dom/dom_high_res_time_stamp.h"
#include "third_party/blink/renderer/core/event_type_names.h"
#include "third_party/blink/renderer/core/events/pointer_event_factory.h"
#include "third_party/blink/renderer/core/frame/frame.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/timing/performance.h"
#include "third_party/blink/renderer/core/timing/performance_event_timing.h"
#include "third_party/blink/renderer/core/timing/window_performance.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/perfetto/include/perfetto/tracing/track.h"
namespace blink {
namespace {
constexpr int kMinValueForSampling = …;
constexpr int kMaxValueForSampling = …;
constexpr int kUkmSamplingRate = …;
constexpr uint32_t kMinFirstInteractionID = …;
constexpr uint32_t kMaxFirstInteractionID = …;
constexpr uint32_t kInteractionIdIncrement = …;
constexpr blink::DOMHighResTimeStamp kMaxDelayForEntries = …;
constexpr base::TimeDelta kFlushTimerLength = …;
const char kHistogramMaxEventDuration[] = …;
const char kHistogramAllTypes[] = …;
const char kHistogramKeyboard[] = …;
const char kHistogramTapOrClick[] = …;
const char kHistogramDrag[] = …;
constexpr char kSlowInteractionToNextPaintTraceEventCategory[] = …;
constexpr char kSlowInteractionToNextPaintTraceEventName[] = …;
const char kPageLoadInternalEventTimingClickInteractionEvents[] = …;
enum ClickInteractionEvents { … };
void EmitSlowInteractionToNextPaintTraceEvent(
const ResponsivenessMetrics::EventTimestamps& event) { … }
ResponsivenessMetrics::EventTimestamps LongestEvent(
const WTF::Vector<ResponsivenessMetrics::EventTimestamps>& events) { … }
base::TimeDelta TotalEventDuration(
const WTF::Vector<ResponsivenessMetrics::EventTimestamps>& timestamps) { … }
WTF::String InteractionTypeToString(UserInteractionType interaction_type) { … }
std::unique_ptr<TracedValue> UserInteractionTraceData(
base::TimeDelta max_duration,
base::TimeDelta total_duration,
UserInteractionType interaction_type) { … }
void LogResponsivenessHistogram(base::TimeDelta max_event_duration,
const char* suffix) { … }
}
ResponsivenessMetrics::ResponsivenessMetrics(
WindowPerformance* window_performance)
: … { … }
ResponsivenessMetrics::~ResponsivenessMetrics() = default;
void ResponsivenessMetrics::RecordUserInteractionUKM(
LocalDOMWindow* window,
UserInteractionType interaction_type,
const WTF::Vector<EventTimestamps>& timestamps,
uint32_t interaction_offset) { … }
void ResponsivenessMetrics::NotifyPotentialDrag(PointerId pointer_id) { … }
void ResponsivenessMetrics::RecordDragTapOrClickUKM(
LocalDOMWindow* window,
PointerEntryAndInfo& pointer_info) { … }
bool ResponsivenessMetrics::SetPointerIdAndRecordLatency(
PerformanceEventTiming* entry,
EventTimestamps event_timestamps) { … }
void ResponsivenessMetrics::RecordKeyboardUKM(
LocalDOMWindow* window,
const WTF::Vector<EventTimestamps>& event_timestamps,
uint32_t interaction_offset) { … }
bool ResponsivenessMetrics::SetKeyIdAndRecordLatency(
PerformanceEventTiming* entry,
EventTimestamps event_timestamps) { … }
bool ResponsivenessMetrics::SetKeyIdAndRecordLatencyExperimental(
PerformanceEventTiming* entry,
EventTimestamps event_timestamps) { … }
void ResponsivenessMetrics::FlushExpiredKeydown(
DOMHighResTimeStamp current_time) { … }
void ResponsivenessMetrics::FlushKeydown() { … }
void ResponsivenessMetrics::FlushAllEventsAtPageHidden() { … }
uint32_t ResponsivenessMetrics::GetInteractionCount() const { … }
void ResponsivenessMetrics::UpdateInteractionId() { … }
uint32_t ResponsivenessMetrics::GetCurrentInteractionId() const { … }
void ResponsivenessMetrics::SetCurrentInteractionEventQueuedTimestamp(
base::TimeTicks queued_time) { … }
base::TimeTicks ResponsivenessMetrics::CurrentInteractionEventQueuedTimestamp()
const { … }
void ResponsivenessMetrics::FlushCompositionEndTimerFired(TimerBase*) { … }
void ResponsivenessMetrics::FlushSequenceBasedKeyboardEvents() { … }
bool ResponsivenessMetrics::IsHoldingKey(std::optional<int> key_code) { … }
void ResponsivenessMetrics::FlushPointerTimerFired(TimerBase*) { … }
void ResponsivenessMetrics::FlushPointerup() { … }
void ResponsivenessMetrics::ContextmenuFlushTimerFired(TimerBase*) { … }
void ResponsivenessMetrics::FlushPointerdownAndPointerup() { … }
void ResponsivenessMetrics::NotifyPointerdown(
PerformanceEventTiming* entry) const { … }
void ResponsivenessMetrics::FlushAllEventsForTesting() { … }
void ResponsivenessMetrics::KeyboardEntryAndTimestamps::Trace(
Visitor* visitor) const { … }
void ResponsivenessMetrics::PointerEntryAndInfo::Trace(Visitor* visitor) const { … }
void ResponsivenessMetrics::Trace(Visitor* visitor) const { … }
perfetto::protos::pbzero::WebContentInteraction::Type
ResponsivenessMetrics::UserInteractionTypeToProto(
UserInteractionType interaction_type) const { … }
void ResponsivenessMetrics::EmitInteractionToNextPaintTraceEvent(
const ResponsivenessMetrics::EventTimestamps& event,
UserInteractionType interaction_type,
base::TimeDelta total_event_duration) { … }
bool ResponsivenessMetrics::TryHandleKeyboardEventSimulatedClick(
PerformanceEventTiming* entry,
const std::optional<PointerId>& pointer_id) { … }
}