Add feature flag useCxxNativeAnimated (#50038)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/50038

Changelog: [Internal]

Creating a new feature flag to gate change for integrating c++ native animated

Reviewed By: rozele

Differential Revision: D71216797

fbshipit-source-id: 9669628a0789701ab6d447a8561027f3a335ef4f
This commit is contained in:
Zeya Peng
2025-03-25 18:51:52 -07:00
committed by Facebook GitHub Bot
parent a70fe45370
commit e7b3424cce
24 changed files with 216 additions and 87 deletions
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<9a17ecc37b3ecd8c0830d9875e8b4453>>
* @generated SignedSource<<9f43ddaa47a45d604adda2e2296c1484>>
*/
/**
@@ -42,6 +42,12 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun animatedShouldSignalBatch(): Boolean = accessor.animatedShouldSignalBatch()
/**
* Use a C++ implementation of Native Animated instead of the platform implementation.
*/
@JvmStatic
public fun cxxNativeAnimatedEnabled(): Boolean = accessor.cxxNativeAnimatedEnabled()
/**
* Prevent FabricMountingManager from reordering mountItems, which may lead to invalid state on the UI thread
*/
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<a510210d8ca4af5b17ea54113ace27b4>>
* @generated SignedSource<<7196636e08059866a9324ab57609e492>>
*/
/**
@@ -22,6 +22,7 @@ package com.facebook.react.internal.featureflags
internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccessor {
private var commonTestFlagCache: Boolean? = null
private var animatedShouldSignalBatchCache: Boolean? = null
private var cxxNativeAnimatedEnabledCache: Boolean? = null
private var disableMountItemReorderingAndroidCache: Boolean? = null
private var enableAccumulatedUpdatesInRawPropsAndroidCache: Boolean? = null
private var enableBridgelessArchitectureCache: Boolean? = null
@@ -80,6 +81,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
return cached
}
override fun cxxNativeAnimatedEnabled(): Boolean {
var cached = cxxNativeAnimatedEnabledCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.cxxNativeAnimatedEnabled()
cxxNativeAnimatedEnabledCache = cached
}
return cached
}
override fun disableMountItemReorderingAndroid(): Boolean {
var cached = disableMountItemReorderingAndroidCache
if (cached == null) {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<773a44eea2720802432ce2f0b8d19027>>
* @generated SignedSource<<463515a955baca809dd6463107ca325c>>
*/
/**
@@ -32,6 +32,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
@DoNotStrip @JvmStatic public external fun animatedShouldSignalBatch(): Boolean
@DoNotStrip @JvmStatic public external fun cxxNativeAnimatedEnabled(): Boolean
@DoNotStrip @JvmStatic public external fun disableMountItemReorderingAndroid(): Boolean
@DoNotStrip @JvmStatic public external fun enableAccumulatedUpdatesInRawPropsAndroid(): Boolean
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<6144e43dc39f259ac7f4de359da03d03>>
* @generated SignedSource<<0c111ea4ea86fce421aa4addb8ad0e4e>>
*/
/**
@@ -27,6 +27,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
override fun animatedShouldSignalBatch(): Boolean = false
override fun cxxNativeAnimatedEnabled(): Boolean = false
override fun disableMountItemReorderingAndroid(): Boolean = false
override fun enableAccumulatedUpdatesInRawPropsAndroid(): Boolean = false
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<22c91abf446f63afd0c09b02536b13f0>>
* @generated SignedSource<<6171c6bc5492b1a0252746e928754f97>>
*/
/**
@@ -26,6 +26,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
private var commonTestFlagCache: Boolean? = null
private var animatedShouldSignalBatchCache: Boolean? = null
private var cxxNativeAnimatedEnabledCache: Boolean? = null
private var disableMountItemReorderingAndroidCache: Boolean? = null
private var enableAccumulatedUpdatesInRawPropsAndroidCache: Boolean? = null
private var enableBridgelessArchitectureCache: Boolean? = null
@@ -86,6 +87,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
return cached
}
override fun cxxNativeAnimatedEnabled(): Boolean {
var cached = cxxNativeAnimatedEnabledCache
if (cached == null) {
cached = currentProvider.cxxNativeAnimatedEnabled()
accessedFeatureFlags.add("cxxNativeAnimatedEnabled")
cxxNativeAnimatedEnabledCache = cached
}
return cached
}
override fun disableMountItemReorderingAndroid(): Boolean {
var cached = disableMountItemReorderingAndroidCache
if (cached == null) {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<3e4b1e03b718d5c2ea03b0a29382d849>>
* @generated SignedSource<<a4f3222340cd676eefdd3794d3f1d4da>>
*/
/**
@@ -27,6 +27,8 @@ public interface ReactNativeFeatureFlagsProvider {
@DoNotStrip public fun animatedShouldSignalBatch(): Boolean
@DoNotStrip public fun cxxNativeAnimatedEnabled(): Boolean
@DoNotStrip public fun disableMountItemReorderingAndroid(): Boolean
@DoNotStrip public fun enableAccumulatedUpdatesInRawPropsAndroid(): Boolean
@@ -15,6 +15,7 @@ import com.facebook.react.bridge.ModuleSpec
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.common.ClassFinder
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.module.annotations.ReactModuleList
import com.facebook.react.module.model.ReactModuleInfo
@@ -115,7 +116,9 @@ constructor(private val config: MainPackageConfig? = null) :
ImageLoaderModule.NAME -> ImageLoaderModule(reactContext)
ImageStoreManager.NAME -> ImageStoreManager(reactContext)
IntentModule.NAME -> IntentModule(reactContext)
NativeAnimatedModule.NAME -> NativeAnimatedModule(reactContext)
NativeAnimatedModule.NAME ->
if (ReactNativeFeatureFlags.cxxNativeAnimatedEnabled()) null
else NativeAnimatedModule(reactContext)
NetworkingModule.NAME -> NetworkingModule(reactContext)
PermissionsModule.NAME -> PermissionsModule(reactContext)
ShareModule.NAME -> ShareModule(reactContext)
@@ -228,30 +231,33 @@ constructor(private val config: MainPackageConfig? = null) :
// We fall back to creating this by hand
val moduleList: Array<Class<*>> =
arrayOf(
AccessibilityInfoModule::class.java,
AppearanceModule::class.java,
AppStateModule::class.java,
BlobModule::class.java,
DevLoadingModule::class.java,
FileReaderModule::class.java,
ClipboardModule::class.java,
DialogModule::class.java,
FrescoModule::class.java,
I18nManagerModule::class.java,
ImageLoaderModule::class.java,
ImageStoreManager::class.java,
IntentModule::class.java,
NativeAnimatedModule::class.java,
NetworkingModule::class.java,
PermissionsModule::class.java,
ReactDevToolsSettingsManagerModule::class.java,
ReactDevToolsRuntimeSettingsModule::class.java,
ShareModule::class.java,
StatusBarModule::class.java,
SoundManagerModule::class.java,
ToastModule::class.java,
VibrationModule::class.java,
WebSocketModule::class.java)
AccessibilityInfoModule::class.java,
AppearanceModule::class.java,
AppStateModule::class.java,
BlobModule::class.java,
DevLoadingModule::class.java,
FileReaderModule::class.java,
ClipboardModule::class.java,
DialogModule::class.java,
FrescoModule::class.java,
I18nManagerModule::class.java,
ImageLoaderModule::class.java,
ImageStoreManager::class.java,
IntentModule::class.java,
if (ReactNativeFeatureFlags.cxxNativeAnimatedEnabled()) null
else NativeAnimatedModule::class.java,
NetworkingModule::class.java,
PermissionsModule::class.java,
ReactDevToolsSettingsManagerModule::class.java,
ReactDevToolsRuntimeSettingsModule::class.java,
ShareModule::class.java,
StatusBarModule::class.java,
SoundManagerModule::class.java,
ToastModule::class.java,
VibrationModule::class.java,
WebSocketModule::class.java)
.filterNotNull()
.toTypedArray()
val moduleMap =
moduleList
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<86e118b823d49cb08bfb204788fa7f73>>
* @generated SignedSource<<2e1dacd320fd57c091996e3e8e2843a9>>
*/
/**
@@ -51,6 +51,12 @@ class ReactNativeFeatureFlagsJavaProvider
return method(javaProvider_);
}
bool cxxNativeAnimatedEnabled() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("cxxNativeAnimatedEnabled");
return method(javaProvider_);
}
bool disableMountItemReorderingAndroid() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("disableMountItemReorderingAndroid");
@@ -299,6 +305,11 @@ bool JReactNativeFeatureFlagsCxxInterop::animatedShouldSignalBatch(
return ReactNativeFeatureFlags::animatedShouldSignalBatch();
}
bool JReactNativeFeatureFlagsCxxInterop::cxxNativeAnimatedEnabled(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::cxxNativeAnimatedEnabled();
}
bool JReactNativeFeatureFlagsCxxInterop::disableMountItemReorderingAndroid(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::disableMountItemReorderingAndroid();
@@ -531,6 +542,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"animatedShouldSignalBatch",
JReactNativeFeatureFlagsCxxInterop::animatedShouldSignalBatch),
makeNativeMethod(
"cxxNativeAnimatedEnabled",
JReactNativeFeatureFlagsCxxInterop::cxxNativeAnimatedEnabled),
makeNativeMethod(
"disableMountItemReorderingAndroid",
JReactNativeFeatureFlagsCxxInterop::disableMountItemReorderingAndroid),
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<d6d24b5374dd661de4917bcc6f4ec53b>>
* @generated SignedSource<<d0b8fdd82018fab8e5532123d5254cf4>>
*/
/**
@@ -36,6 +36,9 @@ class JReactNativeFeatureFlagsCxxInterop
static bool animatedShouldSignalBatch(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool cxxNativeAnimatedEnabled(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool disableMountItemReorderingAndroid(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<3a47a14617ae6faad151ecd64a4613ff>>
* @generated SignedSource<<ae8953b9c5b0efae6fe67b9b799426d7>>
*/
/**
@@ -34,6 +34,10 @@ bool ReactNativeFeatureFlags::animatedShouldSignalBatch() {
return getAccessor().animatedShouldSignalBatch();
}
bool ReactNativeFeatureFlags::cxxNativeAnimatedEnabled() {
return getAccessor().cxxNativeAnimatedEnabled();
}
bool ReactNativeFeatureFlags::disableMountItemReorderingAndroid() {
return getAccessor().disableMountItemReorderingAndroid();
}
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<eeb0afc2cc447a5ba26300a7ce5cee12>>
* @generated SignedSource<<cc7536e8280fdc7d3f2106486439676a>>
*/
/**
@@ -49,6 +49,11 @@ class ReactNativeFeatureFlags {
*/
RN_EXPORT static bool animatedShouldSignalBatch();
/**
* Use a C++ implementation of Native Animated instead of the platform implementation.
*/
RN_EXPORT static bool cxxNativeAnimatedEnabled();
/**
* Prevent FabricMountingManager from reordering mountItems, which may lead to invalid state on the UI thread
*/
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<9e24f368394601004adbb2eaf2243d69>>
* @generated SignedSource<<fa53620e4c4351bcaa153aebfd1b4d50>>
*/
/**
@@ -65,6 +65,24 @@ bool ReactNativeFeatureFlagsAccessor::animatedShouldSignalBatch() {
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::cxxNativeAnimatedEnabled() {
auto flagValue = cxxNativeAnimatedEnabled_.load();
if (!flagValue.has_value()) {
// This block is not exclusive but it is not necessary.
// If multiple threads try to initialize the feature flag, we would only
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(2, "cxxNativeAnimatedEnabled");
flagValue = currentProvider_->cxxNativeAnimatedEnabled();
cxxNativeAnimatedEnabled_ = flagValue;
}
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::disableMountItemReorderingAndroid() {
auto flagValue = disableMountItemReorderingAndroid_.load();
@@ -74,7 +92,7 @@ bool ReactNativeFeatureFlagsAccessor::disableMountItemReorderingAndroid() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(2, "disableMountItemReorderingAndroid");
markFlagAsAccessed(3, "disableMountItemReorderingAndroid");
flagValue = currentProvider_->disableMountItemReorderingAndroid();
disableMountItemReorderingAndroid_ = flagValue;
@@ -92,7 +110,7 @@ bool ReactNativeFeatureFlagsAccessor::enableAccumulatedUpdatesInRawPropsAndroid(
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(3, "enableAccumulatedUpdatesInRawPropsAndroid");
markFlagAsAccessed(4, "enableAccumulatedUpdatesInRawPropsAndroid");
flagValue = currentProvider_->enableAccumulatedUpdatesInRawPropsAndroid();
enableAccumulatedUpdatesInRawPropsAndroid_ = flagValue;
@@ -110,7 +128,7 @@ bool ReactNativeFeatureFlagsAccessor::enableBridgelessArchitecture() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(4, "enableBridgelessArchitecture");
markFlagAsAccessed(5, "enableBridgelessArchitecture");
flagValue = currentProvider_->enableBridgelessArchitecture();
enableBridgelessArchitecture_ = flagValue;
@@ -128,7 +146,7 @@ bool ReactNativeFeatureFlagsAccessor::enableCppPropsIteratorSetter() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(5, "enableCppPropsIteratorSetter");
markFlagAsAccessed(6, "enableCppPropsIteratorSetter");
flagValue = currentProvider_->enableCppPropsIteratorSetter();
enableCppPropsIteratorSetter_ = flagValue;
@@ -146,7 +164,7 @@ bool ReactNativeFeatureFlagsAccessor::enableEagerRootViewAttachment() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(6, "enableEagerRootViewAttachment");
markFlagAsAccessed(7, "enableEagerRootViewAttachment");
flagValue = currentProvider_->enableEagerRootViewAttachment();
enableEagerRootViewAttachment_ = flagValue;
@@ -164,7 +182,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricLogs() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(7, "enableFabricLogs");
markFlagAsAccessed(8, "enableFabricLogs");
flagValue = currentProvider_->enableFabricLogs();
enableFabricLogs_ = flagValue;
@@ -182,7 +200,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricRenderer() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(8, "enableFabricRenderer");
markFlagAsAccessed(9, "enableFabricRenderer");
flagValue = currentProvider_->enableFabricRenderer();
enableFabricRenderer_ = flagValue;
@@ -200,7 +218,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSViewClipToPaddingBox() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(9, "enableIOSViewClipToPaddingBox");
markFlagAsAccessed(10, "enableIOSViewClipToPaddingBox");
flagValue = currentProvider_->enableIOSViewClipToPaddingBox();
enableIOSViewClipToPaddingBox_ = flagValue;
@@ -218,7 +236,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingAndroid() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(10, "enableImagePrefetchingAndroid");
markFlagAsAccessed(11, "enableImagePrefetchingAndroid");
flagValue = currentProvider_->enableImagePrefetchingAndroid();
enableImagePrefetchingAndroid_ = flagValue;
@@ -236,7 +254,7 @@ bool ReactNativeFeatureFlagsAccessor::enableJSRuntimeGCOnMemoryPressureOnIOS() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(11, "enableJSRuntimeGCOnMemoryPressureOnIOS");
markFlagAsAccessed(12, "enableJSRuntimeGCOnMemoryPressureOnIOS");
flagValue = currentProvider_->enableJSRuntimeGCOnMemoryPressureOnIOS();
enableJSRuntimeGCOnMemoryPressureOnIOS_ = flagValue;
@@ -254,7 +272,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnAndroid() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(12, "enableLayoutAnimationsOnAndroid");
markFlagAsAccessed(13, "enableLayoutAnimationsOnAndroid");
flagValue = currentProvider_->enableLayoutAnimationsOnAndroid();
enableLayoutAnimationsOnAndroid_ = flagValue;
@@ -272,7 +290,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnIOS() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(13, "enableLayoutAnimationsOnIOS");
markFlagAsAccessed(14, "enableLayoutAnimationsOnIOS");
flagValue = currentProvider_->enableLayoutAnimationsOnIOS();
enableLayoutAnimationsOnIOS_ = flagValue;
@@ -290,7 +308,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLongTaskAPI() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(14, "enableLongTaskAPI");
markFlagAsAccessed(15, "enableLongTaskAPI");
flagValue = currentProvider_->enableLongTaskAPI();
enableLongTaskAPI_ = flagValue;
@@ -308,7 +326,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMainQueueModulesOnIOS() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(15, "enableMainQueueModulesOnIOS");
markFlagAsAccessed(16, "enableMainQueueModulesOnIOS");
flagValue = currentProvider_->enableMainQueueModulesOnIOS();
enableMainQueueModulesOnIOS_ = flagValue;
@@ -326,7 +344,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNativeCSSParsing() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(16, "enableNativeCSSParsing");
markFlagAsAccessed(17, "enableNativeCSSParsing");
flagValue = currentProvider_->enableNativeCSSParsing();
enableNativeCSSParsing_ = flagValue;
@@ -344,7 +362,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNewBackgroundAndBorderDrawables() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(17, "enableNewBackgroundAndBorderDrawables");
markFlagAsAccessed(18, "enableNewBackgroundAndBorderDrawables");
flagValue = currentProvider_->enableNewBackgroundAndBorderDrawables();
enableNewBackgroundAndBorderDrawables_ = flagValue;
@@ -362,7 +380,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePropsUpdateReconciliationAndroid() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(18, "enablePropsUpdateReconciliationAndroid");
markFlagAsAccessed(19, "enablePropsUpdateReconciliationAndroid");
flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid();
enablePropsUpdateReconciliationAndroid_ = flagValue;
@@ -380,7 +398,7 @@ bool ReactNativeFeatureFlagsAccessor::enableReportEventPaintTime() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(19, "enableReportEventPaintTime");
markFlagAsAccessed(20, "enableReportEventPaintTime");
flagValue = currentProvider_->enableReportEventPaintTime();
enableReportEventPaintTime_ = flagValue;
@@ -398,7 +416,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSynchronousStateUpdates() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(20, "enableSynchronousStateUpdates");
markFlagAsAccessed(21, "enableSynchronousStateUpdates");
flagValue = currentProvider_->enableSynchronousStateUpdates();
enableSynchronousStateUpdates_ = flagValue;
@@ -416,7 +434,7 @@ bool ReactNativeFeatureFlagsAccessor::enableUIConsistency() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(21, "enableUIConsistency");
markFlagAsAccessed(22, "enableUIConsistency");
flagValue = currentProvider_->enableUIConsistency();
enableUIConsistency_ = flagValue;
@@ -434,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewCulling() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(22, "enableViewCulling");
markFlagAsAccessed(23, "enableViewCulling");
flagValue = currentProvider_->enableViewCulling();
enableViewCulling_ = flagValue;
@@ -452,7 +470,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecycling() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(23, "enableViewRecycling");
markFlagAsAccessed(24, "enableViewRecycling");
flagValue = currentProvider_->enableViewRecycling();
enableViewRecycling_ = flagValue;
@@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForText() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(24, "enableViewRecyclingForText");
markFlagAsAccessed(25, "enableViewRecyclingForText");
flagValue = currentProvider_->enableViewRecyclingForText();
enableViewRecyclingForText_ = flagValue;
@@ -488,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForView() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(25, "enableViewRecyclingForView");
markFlagAsAccessed(26, "enableViewRecyclingForView");
flagValue = currentProvider_->enableViewRecyclingForView();
enableViewRecyclingForView_ = flagValue;
@@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAn
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(26, "fixMappingOfEventPrioritiesBetweenFabricAndReact");
markFlagAsAccessed(27, "fixMappingOfEventPrioritiesBetweenFabricAndReact");
flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact();
fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue;
@@ -524,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMountingCoordinatorReportedPendingTrans
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(27, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid");
markFlagAsAccessed(28, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid");
flagValue = currentProvider_->fixMountingCoordinatorReportedPendingTransactionsOnAndroid();
fixMountingCoordinatorReportedPendingTransactionsOnAndroid_ = flagValue;
@@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledRelease() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(28, "fuseboxEnabledRelease");
markFlagAsAccessed(29, "fuseboxEnabledRelease");
flagValue = currentProvider_->fuseboxEnabledRelease();
fuseboxEnabledRelease_ = flagValue;
@@ -560,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxNetworkInspectionEnabled() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(29, "fuseboxNetworkInspectionEnabled");
markFlagAsAccessed(30, "fuseboxNetworkInspectionEnabled");
flagValue = currentProvider_->fuseboxNetworkInspectionEnabled();
fuseboxNetworkInspectionEnabled_ = flagValue;
@@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::removeTurboModuleManagerDelegateMutex() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(30, "removeTurboModuleManagerDelegateMutex");
markFlagAsAccessed(31, "removeTurboModuleManagerDelegateMutex");
flagValue = currentProvider_->removeTurboModuleManagerDelegateMutex();
removeTurboModuleManagerDelegateMutex_ = flagValue;
@@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::throwExceptionInsteadOfDeadlockOnTurboModu
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(31, "throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS");
markFlagAsAccessed(32, "throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS");
flagValue = currentProvider_->throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS();
throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS_ = flagValue;
@@ -614,7 +632,7 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(32, "traceTurboModulePromiseRejectionsOnAndroid");
markFlagAsAccessed(33, "traceTurboModulePromiseRejectionsOnAndroid");
flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid();
traceTurboModulePromiseRejectionsOnAndroid_ = flagValue;
@@ -632,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(33, "useAlwaysAvailableJSErrorHandling");
markFlagAsAccessed(34, "useAlwaysAvailableJSErrorHandling");
flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling();
useAlwaysAvailableJSErrorHandling_ = flagValue;
@@ -650,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::useEditTextStockAndroidFocusBehavior() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(34, "useEditTextStockAndroidFocusBehavior");
markFlagAsAccessed(35, "useEditTextStockAndroidFocusBehavior");
flagValue = currentProvider_->useEditTextStockAndroidFocusBehavior();
useEditTextStockAndroidFocusBehavior_ = flagValue;
@@ -668,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(35, "useFabricInterop");
markFlagAsAccessed(36, "useFabricInterop");
flagValue = currentProvider_->useFabricInterop();
useFabricInterop_ = flagValue;
@@ -686,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(36, "useNativeViewConfigsInBridgelessMode");
markFlagAsAccessed(37, "useNativeViewConfigsInBridgelessMode");
flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode();
useNativeViewConfigsInBridgelessMode_ = flagValue;
@@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedEventBatchingOnAndroid() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(37, "useOptimizedEventBatchingOnAndroid");
markFlagAsAccessed(38, "useOptimizedEventBatchingOnAndroid");
flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid();
useOptimizedEventBatchingOnAndroid_ = flagValue;
@@ -722,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::useRawPropsJsiValue() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(38, "useRawPropsJsiValue");
markFlagAsAccessed(39, "useRawPropsJsiValue");
flagValue = currentProvider_->useRawPropsJsiValue();
useRawPropsJsiValue_ = flagValue;
@@ -740,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(39, "useTurboModuleInterop");
markFlagAsAccessed(40, "useTurboModuleInterop");
flagValue = currentProvider_->useTurboModuleInterop();
useTurboModuleInterop_ = flagValue;
@@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModules() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(40, "useTurboModules");
markFlagAsAccessed(41, "useTurboModules");
flagValue = currentProvider_->useTurboModules();
useTurboModules_ = flagValue;
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<812efbb5dc0dddf0a03dec30921bfe3f>>
* @generated SignedSource<<ca15768ea69f30904f9f6453287ca834>>
*/
/**
@@ -34,6 +34,7 @@ class ReactNativeFeatureFlagsAccessor {
bool commonTestFlag();
bool animatedShouldSignalBatch();
bool cxxNativeAnimatedEnabled();
bool disableMountItemReorderingAndroid();
bool enableAccumulatedUpdatesInRawPropsAndroid();
bool enableBridgelessArchitecture();
@@ -84,10 +85,11 @@ class ReactNativeFeatureFlagsAccessor {
std::unique_ptr<ReactNativeFeatureFlagsProvider> currentProvider_;
bool wasOverridden_;
std::array<std::atomic<const char*>, 41> accessedFeatureFlags_;
std::array<std::atomic<const char*>, 42> accessedFeatureFlags_;
std::atomic<std::optional<bool>> commonTestFlag_;
std::atomic<std::optional<bool>> animatedShouldSignalBatch_;
std::atomic<std::optional<bool>> cxxNativeAnimatedEnabled_;
std::atomic<std::optional<bool>> disableMountItemReorderingAndroid_;
std::atomic<std::optional<bool>> enableAccumulatedUpdatesInRawPropsAndroid_;
std::atomic<std::optional<bool>> enableBridgelessArchitecture_;
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<f645ab08e2783763a91d685e8c1ddd02>>
* @generated SignedSource<<988e6c024f8526a676dd586cab91c98e>>
*/
/**
@@ -35,6 +35,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
return false;
}
bool cxxNativeAnimatedEnabled() override {
return false;
}
bool disableMountItemReorderingAndroid() override {
return false;
}
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<c600cb99e75a2c71e5241e4cc3ab7d35>>
* @generated SignedSource<<03140604c630ec88815c53be4177f2c1>>
*/
/**
@@ -63,6 +63,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef
return ReactNativeFeatureFlagsDefaults::animatedShouldSignalBatch();
}
bool cxxNativeAnimatedEnabled() override {
auto value = values_["cxxNativeAnimatedEnabled"];
if (!value.isNull()) {
return value.getBool();
}
return ReactNativeFeatureFlagsDefaults::cxxNativeAnimatedEnabled();
}
bool disableMountItemReorderingAndroid() override {
auto value = values_["disableMountItemReorderingAndroid"];
if (!value.isNull()) {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<89298319752a8693d0c3e0a22ba88011>>
* @generated SignedSource<<072a24fe2750a87888dba8d93ae0dd7b>>
*/
/**
@@ -35,6 +35,8 @@ class ReactNativeFeatureFlagsOverridesOSSCanary : public ReactNativeFeatureFlags
bool enableBridgelessArchitecture() override {
return true;
}
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<25f75edcfc62e5ce24c2d1bd10244e40>>
* @generated SignedSource<<ddf338308d0390152ddbec172c0ad40e>>
*/
/**
@@ -105,6 +105,8 @@ class ReactNativeFeatureFlagsOverridesOSSExperimental : public ReactNativeFeatur
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<6e544b793e8c7d01298b428c43af0463>>
* @generated SignedSource<<cef4c40e8e1b2064065f5c835b940db2>>
*/
/**
@@ -27,6 +27,7 @@ class ReactNativeFeatureFlagsProvider {
virtual bool commonTestFlag() = 0;
virtual bool animatedShouldSignalBatch() = 0;
virtual bool cxxNativeAnimatedEnabled() = 0;
virtual bool disableMountItemReorderingAndroid() = 0;
virtual bool enableAccumulatedUpdatesInRawPropsAndroid() = 0;
virtual bool enableBridgelessArchitecture() = 0;
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<2871e5ea1c6d695af6af757b27fbd54c>>
* @generated SignedSource<<99503a6bd2dd6143eb93717293574b7c>>
*/
/**
@@ -54,6 +54,11 @@ bool NativeReactNativeFeatureFlags::animatedShouldSignalBatch(
return ReactNativeFeatureFlags::animatedShouldSignalBatch();
}
bool NativeReactNativeFeatureFlags::cxxNativeAnimatedEnabled(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::cxxNativeAnimatedEnabled();
}
bool NativeReactNativeFeatureFlags::disableMountItemReorderingAndroid(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::disableMountItemReorderingAndroid();
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<0e7396f960e18680d4384f8db501472b>>
* @generated SignedSource<<1465adf7db643faefb579cafd9ef9dcf>>
*/
/**
@@ -41,6 +41,8 @@ class NativeReactNativeFeatureFlags
bool animatedShouldSignalBatch(jsi::Runtime& runtime);
bool cxxNativeAnimatedEnabled(jsi::Runtime& runtime);
bool disableMountItemReorderingAndroid(jsi::Runtime& runtime);
bool enableAccumulatedUpdatesInRawPropsAndroid(jsi::Runtime& runtime);
@@ -70,6 +70,17 @@ const definitions: FeatureFlagDefinitions = {
},
ossReleaseStage: 'none',
},
cxxNativeAnimatedEnabled: {
defaultValue: false,
metadata: {
dateAdded: '2025-03-14',
description:
'Use a C++ implementation of Native Animated instead of the platform implementation.',
expectedReleaseValue: true,
purpose: 'experimentation',
},
ossReleaseStage: 'none',
},
disableMountItemReorderingAndroid: {
defaultValue: false,
metadata: {
@@ -57,7 +57,9 @@ const eventListenerAnimationFinishedCallbacks: {
let globalEventEmitterGetValueListener: ?EventSubscription = null;
let globalEventEmitterAnimationFinishedListener: ?EventSubscription = null;
const shouldSignalBatch = ReactNativeFeatureFlags.animatedShouldSignalBatch();
const shouldSignalBatch =
ReactNativeFeatureFlags.animatedShouldSignalBatch() ||
ReactNativeFeatureFlags.cxxNativeAnimatedEnabled();
function createNativeOperations(): $NonMaybeType<typeof NativeAnimatedModule> {
const methodNames = [
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<adb29ea8a9fe70bb16af9a46d394c68d>>
* @generated SignedSource<<bb1c3b4c3d3d20ab463e4d0131efc3d9>>
* @flow strict
*/
@@ -49,6 +49,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{
commonTestFlag: Getter<boolean>,
commonTestFlagWithoutNativeImplementation: Getter<boolean>,
animatedShouldSignalBatch: Getter<boolean>,
cxxNativeAnimatedEnabled: Getter<boolean>,
disableMountItemReorderingAndroid: Getter<boolean>,
enableAccumulatedUpdatesInRawPropsAndroid: Getter<boolean>,
enableBridgelessArchitecture: Getter<boolean>,
@@ -167,6 +168,10 @@ export const commonTestFlagWithoutNativeImplementation: Getter<boolean> = create
* Enables start- and finishOperationBatch on any platform.
*/
export const animatedShouldSignalBatch: Getter<boolean> = createNativeFlagGetter('animatedShouldSignalBatch', false);
/**
* Use a C++ implementation of Native Animated instead of the platform implementation.
*/
export const cxxNativeAnimatedEnabled: Getter<boolean> = createNativeFlagGetter('cxxNativeAnimatedEnabled', false);
/**
* Prevent FabricMountingManager from reordering mountItems, which may lead to invalid state on the UI thread
*/
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<2418847290f10d51945f9593dcb03eb2>>
* @generated SignedSource<<8a9e88c68d78cde54e51477a0f06c643>>
* @flow strict
*/
@@ -26,6 +26,7 @@ export interface Spec extends TurboModule {
+commonTestFlag?: () => boolean;
+commonTestFlagWithoutNativeImplementation?: () => boolean;
+animatedShouldSignalBatch?: () => boolean;
+cxxNativeAnimatedEnabled?: () => boolean;
+disableMountItemReorderingAndroid?: () => boolean;
+enableAccumulatedUpdatesInRawPropsAndroid?: () => boolean;
+enableBridgelessArchitecture?: () => boolean;