From e6d9f174769bfed89d8664f3f5c43e16ed8ff38f Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Tue, 8 Apr 2025 10:23:09 -0700 Subject: [PATCH] Enable direct manipulation for c++ NativeAnimated for Android (#50568) Summary: ## Changelog: [Android] [Internal] - Enable direct manipulation for c++ NativeAnimated for Android Reviewed By: javache Differential Revision: D71668422 --- .../react-native/ReactAndroid/api/ReactAndroid.api | 1 + .../com/facebook/react/fabric/FabricUIManager.java | 8 ++++++++ .../main/jni/react/fabric/FabricMountingManager.cpp | 11 +++++++++++ .../src/main/jni/react/fabric/FabricMountingManager.h | 4 ++++ .../main/jni/react/fabric/FabricUIManagerBinding.cpp | 6 +++++- 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 0bf50ab0beb3..f5fcb8d166a8 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -2378,6 +2378,7 @@ public class com/facebook/react/fabric/FabricUIManager : com/facebook/react/brid public fun stopSurface (Lcom/facebook/react/fabric/SurfaceHandlerBinding;)V public fun sweepActiveTouchForTag (II)V public fun synchronouslyUpdateViewOnUIThread (ILcom/facebook/react/bridge/ReadableMap;)V + public fun synchronouslyUpdateViewOnUIThread (ILcom/facebook/react/bridge/ReadableNativeMap;)V public fun updateRootLayoutSpecs (IIIII)V } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index a9c440d07bea..684b4411691c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -43,6 +43,7 @@ import com.facebook.react.bridge.ReactSoftExceptionLogger; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.ReadableNativeMap; import com.facebook.react.bridge.UIManager; import com.facebook.react.bridge.UIManagerListener; import com.facebook.react.bridge.UiThreadUtil; @@ -621,6 +622,13 @@ public void removeUIManagerEventListener(UIManagerListener listener) { mListeners.remove(listener); } + @UiThread + @ThreadConfined(UI) + public void synchronouslyUpdateViewOnUIThread( + final int reactTag, @NonNull final ReadableNativeMap props) { + synchronouslyUpdateViewOnUIThread(reactTag, (ReadableMap) props); + } + @Override @UiThread @ThreadConfined(UI) diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp index 5cdf7a4107ab..11e9bc3814e6 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp @@ -1068,4 +1068,15 @@ void FabricMountingManager::onAllAnimationsComplete() { allAnimationsCompleteJNI(javaUIManager_); } +void FabricMountingManager::synchronouslyUpdateViewOnUIThread( + Tag viewTag, + const folly::dynamic& props) { + static auto synchronouslyUpdateViewOnUIThreadJNI = + JFabricUIManager::javaClassStatic() + ->getMethod( + "synchronouslyUpdateViewOnUIThread"); + auto propsMap = ReadableNativeMap::newObjectCxxArgs(props); + synchronouslyUpdateViewOnUIThreadJNI(javaUIManager_, viewTag, propsMap.get()); +} + } // namespace facebook::react diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.h b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.h index 781489a5c867..61978317ff5e 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.h @@ -60,6 +60,10 @@ class FabricMountingManager final { void onAllAnimationsComplete(); + void synchronouslyUpdateViewOnUIThread( + Tag viewTag, + const folly::dynamic& props); + private: bool isOnMainThread(); diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp index 7fcbb024f3ca..e16008a27bce 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp @@ -622,7 +622,11 @@ void FabricUIManagerBinding::schedulerDidSetIsJSResponder( void FabricUIManagerBinding::schedulerShouldSynchronouslyUpdateViewOnUIThread( Tag tag, - const folly::dynamic& props) {} + const folly::dynamic& props) { + if (ReactNativeFeatureFlags::cxxNativeAnimatedEnabled() && mountingManager_) { + mountingManager_->synchronouslyUpdateViewOnUIThread(tag, props); + } +} void FabricUIManagerBinding::onAnimationStarted() { auto mountingManager = getMountingManager("onAnimationStarted");