From a54391cda4342172a90b4f7304a42023a37cef99 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Thu, 29 Oct 2026 13:32:20 +0000 Subject: [PATCH] [RN] Sync Android touch payload and TurboModule source updates Synchronise Android touch payload field constants and their JNI and test-shadow implementations. Use designated initialisers for cached TurboModule method metadata. Restore missing source updates while preserving recently merged pull requests. Changelog: [Internal] fbshipit-source-id: f652b5906bf2419f0cedca9711c225a6f53cf054 --- .../react/uimanager/events/TouchesHelper.kt | 30 +++++++----- .../src/main/jni/react/jni/TouchesHelper.cpp | 49 ++++++++++++------- .../testutils/shadows/ShadowTouchesHelper.kt | 21 ++++---- .../android/ReactCommon/JavaTurboModule.cpp | 17 ++++--- 4 files changed, 69 insertions(+), 48 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchesHelper.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchesHelper.kt index 176373a7de57..8e30d686e41f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchesHelper.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchesHelper.kt @@ -23,8 +23,16 @@ internal object TouchesHelper { ReactNativeJNISoLoader.staticInit() } - // Values per pointer in the data passed to nativeCreateTouchPayload. - private const val POINTER_FIELDS = 8 + // Keep in sync with the field indices in TouchesHelper.cpp. + const val PAGE_X_INDEX = 0 + const val PAGE_Y_INDEX = 1 + const val LOCATION_X_INDEX = 2 + const val LOCATION_Y_INDEX = 3 + const val TARGET_SURFACE_INDEX = 4 + const val TARGET_INDEX = 5 + const val TIMESTAMP_INDEX = 6 + const val IDENTIFIER_INDEX = 7 + const val POINTER_FIELDS = 8 /** * Fills the pointer data of [nativeCreateTouchPayload]: for each pointer of the @@ -46,24 +54,24 @@ internal object TouchesHelper { val targetViewCoordinateY = motionEvent.y - event.viewY for (index in 0 until motionEvent.pointerCount) { - var field = index * POINTER_FIELDS + val field = index * POINTER_FIELDS // pageX,Y values are relative to the RootReactView // the motionEvent already contains coordinates in that view - pointerData[field++] = motionEvent.getX(index).pxToDp().toDouble() - pointerData[field++] = motionEvent.getY(index).pxToDp().toDouble() + pointerData[field + PAGE_X_INDEX] = motionEvent.getX(index).pxToDp().toDouble() + pointerData[field + PAGE_Y_INDEX] = motionEvent.getY(index).pxToDp().toDouble() // locationX,Y values are relative to the target view // To compute the values for the view, we subtract that views location from the event X,Y val locationX = motionEvent.getX(index) - targetViewCoordinateX val locationY = motionEvent.getY(index) - targetViewCoordinateY - pointerData[field++] = locationX.pxToDp().toDouble() - pointerData[field++] = locationY.pxToDp().toDouble() + pointerData[field + LOCATION_X_INDEX] = locationX.pxToDp().toDouble() + pointerData[field + LOCATION_Y_INDEX] = locationY.pxToDp().toDouble() - pointerData[field++] = event.surfaceId.toDouble() - pointerData[field++] = event.viewTag.toDouble() - pointerData[field++] = event.timestampMs.toDouble() - pointerData[field] = motionEvent.getPointerId(index).toDouble() + pointerData[field + TARGET_SURFACE_INDEX] = event.surfaceId.toDouble() + pointerData[field + TARGET_INDEX] = event.viewTag.toDouble() + pointerData[field + TIMESTAMP_INDEX] = event.timestampMs.toDouble() + pointerData[field + IDENTIFIER_INDEX] = motionEvent.getPointerId(index).toDouble() } return pointerData diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/jni/TouchesHelper.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/jni/TouchesHelper.cpp index 7f52b1ace1b2..6696c93d0bb8 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/jni/TouchesHelper.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/jni/TouchesHelper.cpp @@ -18,20 +18,29 @@ namespace facebook::react { namespace { -// Must match TouchesHelper.POINTER_FIELDS and the order documented on -// TouchesHelper.nativeCreateTouchPayload. +// Keep in sync with the field indices in TouchesHelper.kt. +constexpr jint kPageXIndex = 0; +constexpr jint kPageYIndex = 1; +constexpr jint kLocationXIndex = 2; +constexpr jint kLocationYIndex = 3; +constexpr jint kTargetSurfaceIndex = 4; +constexpr jint kTargetIndex = 5; +constexpr jint kTimestampIndex = 6; +constexpr jint kIdentifierIndex = 7; constexpr jint kPointerFields = 8; folly::dynamic createTouch(const double* fields) { folly::dynamic touch = folly::dynamic::object(); - touch.insert("pageX", fields[0]); - touch.insert("pageY", fields[1]); - touch.insert("locationX", fields[2]); - touch.insert("locationY", fields[3]); - touch.insert("targetSurface", static_cast(fields[4])); - touch.insert("target", static_cast(fields[5])); - touch.insert("timestamp", fields[6]); - touch.insert("identifier", fields[7]); + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) + touch.insert("pageX", fields[kPageXIndex]); + touch.insert("pageY", fields[kPageYIndex]); + touch.insert("locationX", fields[kLocationXIndex]); + touch.insert("locationY", fields[kLocationYIndex]); + touch.insert("targetSurface", static_cast(fields[kTargetSurfaceIndex])); + touch.insert("target", static_cast(fields[kTargetIndex])); + touch.insert("timestamp", fields[kTimestampIndex]); + touch.insert("identifier", fields[kIdentifierIndex]); + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) return touch; } @@ -53,6 +62,7 @@ local_ref createTouchPayload( folly::dynamic changedTouches = folly::dynamic::array(); folly::dynamic touches = folly::dynamic::array(); for (jint index = 0; index < pointerCount; index++) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) const double* fields = values.get() + index * kPointerFields; if ((changedPointers & (1 << index)) != 0) { changedTouches.push_back(createTouch(fields)); @@ -64,15 +74,18 @@ local_ref createTouchPayload( auto jPayload = WritableNativeMap::newObjectJavaArgs(); auto* payload = jPayload->cthis(); + // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) const double* fields = values.get() + eventPointer * kPointerFields; - payload->putDouble("pageX", fields[0]); - payload->putDouble("pageY", fields[1]); - payload->putDouble("locationX", fields[2]); - payload->putDouble("locationY", fields[3]); - payload->putInt("targetSurface", static_cast(fields[4])); - payload->putInt("target", static_cast(fields[5])); - payload->putDouble("timestamp", fields[6]); - payload->putDouble("identifier", fields[7]); + payload->putDouble("pageX", fields[kPageXIndex]); + payload->putDouble("pageY", fields[kPageYIndex]); + payload->putDouble("locationX", fields[kLocationXIndex]); + payload->putDouble("locationY", fields[kLocationYIndex]); + payload->putInt( + "targetSurface", static_cast(fields[kTargetSurfaceIndex])); + payload->putInt("target", static_cast(fields[kTargetIndex])); + payload->putDouble("timestamp", fields[kTimestampIndex]); + payload->putDouble("identifier", fields[kIdentifierIndex]); + // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) WritableNativeArray changedTouchesArray(std::move(changedTouches)); payload->putNativeArray("changedTouches", &changedTouchesArray); WritableNativeArray touchesArray(std::move(touches)); diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowTouchesHelper.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowTouchesHelper.kt index adacabf276dc..588f3787a331 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowTouchesHelper.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/testutils/shadows/ShadowTouchesHelper.kt @@ -19,7 +19,6 @@ import org.robolectric.annotation.Implements class ShadowTouchesHelper { companion object { - private const val POINTER_FIELDS = 8 /** Builds the same payload as the native TouchesHelper::createTouchPayload. */ @JvmStatic @@ -30,7 +29,7 @@ class ShadowTouchesHelper { changedPointers: Int, touchPointers: Int, ): WritableNativeMap { - val pointerCount = pointerData.size / POINTER_FIELDS + val pointerCount = pointerData.size / TouchesHelper.POINTER_FIELDS val changedTouches = JavaOnlyArray() val touches = JavaOnlyArray() for (index in 0 until pointerCount) { @@ -49,15 +48,15 @@ class ShadowTouchesHelper { } private fun putTouch(touch: WritableMap, pointerData: DoubleArray, index: Int) { - val field = index * POINTER_FIELDS - touch.putDouble("pageX", pointerData[field]) - touch.putDouble("pageY", pointerData[field + 1]) - touch.putDouble("locationX", pointerData[field + 2]) - touch.putDouble("locationY", pointerData[field + 3]) - touch.putInt("targetSurface", pointerData[field + 4].toInt()) - touch.putInt("target", pointerData[field + 5].toInt()) - touch.putDouble("timestamp", pointerData[field + 6]) - touch.putDouble("identifier", pointerData[field + 7]) + val field = index * TouchesHelper.POINTER_FIELDS + touch.putDouble("pageX", pointerData[field + TouchesHelper.PAGE_X_INDEX]) + touch.putDouble("pageY", pointerData[field + TouchesHelper.PAGE_Y_INDEX]) + touch.putDouble("locationX", pointerData[field + TouchesHelper.LOCATION_X_INDEX]) + touch.putDouble("locationY", pointerData[field + TouchesHelper.LOCATION_Y_INDEX]) + touch.putInt("targetSurface", pointerData[field + TouchesHelper.TARGET_SURFACE_INDEX].toInt()) + touch.putInt("target", pointerData[field + TouchesHelper.TARGET_INDEX].toInt()) + touch.putDouble("timestamp", pointerData[field + TouchesHelper.TIMESTAMP_INDEX]) + touch.putDouble("identifier", pointerData[field + TouchesHelper.IDENTIFIER_INDEX]) } } } diff --git a/packages/react-native/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.cpp b/packages/react-native/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.cpp index df3b9bbfc436..fd88b607428c 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.cpp @@ -594,14 +594,15 @@ const JavaTurboModule::MethodInfo& JavaTurboModule::getMethodInfo( std::lock_guard lock(methodInfosMutex_); auto entry = methodInfos_.find(methodID); if (entry == methodInfos_.end()) { - entry = methodInfos_ - .emplace( - methodID, - MethodInfo{ - getMethodArgTypesFromSignature(methodSignature), - methodSignature.substr( - methodSignature.find_last_of(')') + 1)}) - .first; + entry = + methodInfos_ + .emplace( + methodID, + MethodInfo{ + .argTypes = getMethodArgTypesFromSignature(methodSignature), + .returnType = methodSignature.substr( + methodSignature.find_last_of(')') + 1)}) + .first; } return entry->second; }