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)