From 9fd541b120cf896fddaa23a614cd5b219c2b7ad8 Mon Sep 17 00:00:00 2001 From: Ruslan Shestopalyuk Date: Thu, 10 Oct 2024 06:13:58 -0700 Subject: [PATCH] Add an event start timestamp field into RawEvent (#46949) Summary: # Changelog: [Internal] - This adds an (optional) event start time field into RawEvent, so that it can be threaded by the platform-specific code to tell where is the earliest point of the event start (depending on the platform). For example, on Android platform it can be the point of time when the original MotionEvent was received. Differential Revision: D64175467 --- .../ReactCommon/react/renderer/core/EventDispatcher.cpp | 4 ++-- .../ReactCommon/react/renderer/core/EventLogger.h | 5 ++++- .../ReactCommon/react/renderer/core/RawEvent.h | 6 ++++++ .../renderer/core/tests/EventQueueProcessorTest.cpp | 6 ++++-- .../renderer/observers/events/EventPerformanceLogger.cpp | 9 +++++++-- .../renderer/observers/events/EventPerformanceLogger.h | 7 +++++-- .../react-native/ReactCommon/react/timing/primitives.h | 2 ++ 7 files changed, 30 insertions(+), 9 deletions(-) diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.cpp b/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.cpp index 9efe362d27bdee..daf4edc10777e6 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.cpp @@ -37,8 +37,8 @@ void EventDispatcher::dispatchEvent(RawEvent&& rawEvent) const { auto eventLogger = eventLogger_.lock(); if (eventLogger != nullptr) { - rawEvent.loggingTag = - eventLogger->onEventStart(rawEvent.type, rawEvent.eventTarget); + rawEvent.loggingTag = eventLogger->onEventStart( + rawEvent.type, rawEvent.eventTarget, rawEvent.eventStartTimeStamp); } eventQueue_.enqueueEvent(std::move(rawEvent)); } diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventLogger.h b/packages/react-native/ReactCommon/react/renderer/core/EventLogger.h index ceb3a7b02bf703..86fdc36297a756 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventLogger.h +++ b/packages/react-native/ReactCommon/react/renderer/core/EventLogger.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include namespace facebook::react { @@ -30,7 +31,9 @@ class EventLogger { */ virtual EventTag onEventStart( std::string_view name, - SharedEventTarget target) = 0; + SharedEventTarget target, + DOMHighResTimeStamp eventStartTimeStamp = + DOM_HIGH_RES_TIME_STAMP_UNSET) = 0; /* * Called when event starts getting dispatched (processed by the handlers, if diff --git a/packages/react-native/ReactCommon/react/renderer/core/RawEvent.h b/packages/react-native/ReactCommon/react/renderer/core/RawEvent.h index 03a2f0857aa1a0..c79aca59aa9920 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/RawEvent.h +++ b/packages/react-native/ReactCommon/react/renderer/core/RawEvent.h @@ -13,6 +13,7 @@ #include #include #include +#include namespace facebook::react { @@ -69,6 +70,11 @@ struct RawEvent { SharedEventTarget eventTarget; Category category; EventTag loggingTag{0}; + + // The client may specify a platform-specific timestamp for the event start + // time, for example when MotionEvent was triggered on the Android native + // side. + DOMHighResTimeStamp eventStartTimeStamp{DOM_HIGH_RES_TIME_STAMP_UNSET}; }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/core/tests/EventQueueProcessorTest.cpp b/packages/react-native/ReactCommon/react/renderer/core/tests/EventQueueProcessorTest.cpp index 9a59a6d16be30c..e841ab161e9a14 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/tests/EventQueueProcessorTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/tests/EventQueueProcessorTest.cpp @@ -21,8 +21,10 @@ namespace facebook::react { class MockEventLogger : public EventLogger { - EventTag onEventStart(std::string_view /*name*/, SharedEventTarget /*target*/) - override { + EventTag onEventStart( + std::string_view /*name*/, + SharedEventTarget /*target*/, + DOMHighResTimeStamp /*eventStartTimeStamp*/) override { return EMPTY_EVENT_TAG; } void onEventProcessingStart(EventTag /*tag*/) override {} diff --git a/packages/react-native/ReactCommon/react/renderer/observers/events/EventPerformanceLogger.cpp b/packages/react-native/ReactCommon/react/renderer/observers/events/EventPerformanceLogger.cpp index 48b2c8c00beb2a..7c0bf6e813c7d7 100644 --- a/packages/react-native/ReactCommon/react/renderer/observers/events/EventPerformanceLogger.cpp +++ b/packages/react-native/ReactCommon/react/renderer/observers/events/EventPerformanceLogger.cpp @@ -103,7 +103,8 @@ EventPerformanceLogger::EventPerformanceLogger( EventTag EventPerformanceLogger::onEventStart( std::string_view name, - SharedEventTarget target) { + SharedEventTarget target, + DOMHighResTimeStamp eventStartTimeStamp) { auto performanceEntryReporter = performanceEntryReporter_.lock(); if (performanceEntryReporter == nullptr) { return EMPTY_EVENT_TAG; @@ -119,7 +120,11 @@ EventTag EventPerformanceLogger::onEventStart( auto eventTag = createEventTag(); - auto timeStamp = performanceEntryReporter->getCurrentTimeStamp(); + // The event start timestamp may be provided by the caller in order to + // specify the platform specific event start time. + auto timeStamp = eventStartTimeStamp == DOM_HIGH_RES_TIME_STAMP_UNSET + ? performanceEntryReporter->getCurrentTimeStamp() + : eventStartTimeStamp; { std::lock_guard lock(eventsInFlightMutex_); eventsInFlight_.emplace( diff --git a/packages/react-native/ReactCommon/react/renderer/observers/events/EventPerformanceLogger.h b/packages/react-native/ReactCommon/react/renderer/observers/events/EventPerformanceLogger.h index a1121f2ee52c7b..b878459f270a50 100644 --- a/packages/react-native/ReactCommon/react/renderer/observers/events/EventPerformanceLogger.h +++ b/packages/react-native/ReactCommon/react/renderer/observers/events/EventPerformanceLogger.h @@ -27,8 +27,11 @@ class EventPerformanceLogger : public EventLogger, #pragma mark - EventLogger - EventTag onEventStart(std::string_view name, SharedEventTarget target) - override; + EventTag onEventStart( + std::string_view name, + SharedEventTarget target, + DOMHighResTimeStamp eventStartTimeStamp = + DOM_HIGH_RES_TIME_STAMP_UNSET) override; void onEventProcessingStart(EventTag tag) override; void onEventProcessingEnd(EventTag tag) override; diff --git a/packages/react-native/ReactCommon/react/timing/primitives.h b/packages/react-native/ReactCommon/react/timing/primitives.h index 135be263c9b05e..c6b3c304635cdc 100644 --- a/packages/react-native/ReactCommon/react/timing/primitives.h +++ b/packages/react-native/ReactCommon/react/timing/primitives.h @@ -17,6 +17,8 @@ namespace facebook::react { // not necessary in React Native. using DOMHighResTimeStamp = double; +constexpr DOMHighResTimeStamp DOM_HIGH_RES_TIME_STAMP_UNSET = -1.0; + inline DOMHighResTimeStamp chronoToDOMHighResTimeStamp( std::chrono::steady_clock::duration duration) { return static_cast>(duration)