From 69feed518d01a7d91f0c71509429c4388912131c Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Sun, 28 Feb 2021 15:16:14 -0800 Subject: [PATCH] Send UNIX timestamp along with JS touch events, instead of systemUptime Summary: We want to be able to instrument touch processing delays in JS, which does not have access to systemUptime; therefore we want a UNIX timestamp, which JS has access to and can compare to the touch time. It only matters that there is relative consistency between multiple touch events in JS, which is still the case; so this should have no impact on product code. Changelog: [Internal] Reviewed By: yungsters Differential Revision: D26705429 fbshipit-source-id: 0f2db726048fcab9a30e830970d7d8a8d2eae446 --- .../facebook/react/uimanager/events/Event.java | 18 +++++++++++++++++- .../react/uimanager/events/TouchesHelper.java | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java index bd3b06b16e6..e8976cce961 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java @@ -38,6 +38,15 @@ public abstract class Event { private long mTimestampMs; private int mUniqueID = sUniqueID++; + // Android native Event times use 'uptimeMillis', and historically we've used `uptimeMillis` + // throughout this Event class as the coalescing key for events, and for other purposes. + // To get an accurate(ish) absolute UNIX time for the event, we store the initial clock time here. + // uptimeMillis can then be added to this to get an accurate UNIX time. + // However, we still default to uptimeMillis: you must explicitly request UNIX time if you want + // that; see `getUnixTimestampMs`. + public static final long sInitialClockTimeUnixOffset = + SystemClock.currentTimeMillis() - SystemClock.uptimeMillis(); + protected Event() {} @Deprecated @@ -58,8 +67,10 @@ public abstract class Event { protected void init(int surfaceId, int viewTag) { mSurfaceId = surfaceId; mViewTag = viewTag; - mTimestampMs = SystemClock.uptimeMillis(); mInitialized = true; + + // This is a *relative* time. See `getUnixTimestampMs`. + mTimestampMs = SystemClock.uptimeMillis(); } /** @return the view id for the view that generated this event */ @@ -80,6 +91,11 @@ public abstract class Event { return mTimestampMs; } + /** @return the time at which the event happened as a UNIX timestamp, in milliseconds. */ + public final long getUnixTimestampMs() { + return sInitialClockTimeUnixOffset + mTimestampMs; + } + /** @return false if this Event can *never* be coalesced */ public boolean canCoalesce() { return true; diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchesHelper.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchesHelper.java index 187e6121160..b67f6e3eff0 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchesHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchesHelper.java @@ -64,7 +64,7 @@ public class TouchesHelper { touch.putDouble(LOCATION_Y_KEY, PixelUtil.toDIPFromPixel(locationY)); touch.putInt(TARGET_SURFACE_KEY, surfaceId); touch.putInt(TARGET_KEY, reactTarget); - touch.putDouble(TIMESTAMP_KEY, event.getTimestampMs()); + touch.putDouble(TIMESTAMP_KEY, event.getUnixTimestampMs()); touch.putDouble(POINTER_IDENTIFIER_KEY, motionEvent.getPointerId(index)); touches.pushMap(touch); }