mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Fix differentiator emitting updates with incorrect parentTag (#48055)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/48055 Address the test-case identified in D66557919, where Differentiator could emit updates for views referencing an incorrect parentTag. The longer-term fix here is to avoid emitting any updates for nodes which are being reparented, but that requires bigger changes, including to the LayoutAnimation system. As a short-term patch, we're passing through an explicit `parentShadowViewForUpdate` which will be used as the current parent for update purposes. {F1971278019} Changelog: [Android][Fixed] Fix Fabric mutations sometimes triggering a `getViewState` crash when referencing an invalid parentTag. Reviewed By: rubennorte Differential Revision: D66654293 fbshipit-source-id: cd5b3e577ad1eede1b6dea834582ac6d750cbb81
This commit is contained in:
committed by
Facebook GitHub Bot
parent
21c9491926
commit
34901d4861
+7
-1
@@ -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<<6d8d8f4b81d7be882b315d0960499dcb>>
|
||||
* @generated SignedSource<<4a219bb47b1b9d988a164bca19eb4fa9>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -202,6 +202,12 @@ public object ReactNativeFeatureFlags {
|
||||
@JvmStatic
|
||||
public fun excludeYogaFromRawProps(): Boolean = accessor.excludeYogaFromRawProps()
|
||||
|
||||
/**
|
||||
* Fixes a bug in Differentiator where parent views may be referenced before they're created
|
||||
*/
|
||||
@JvmStatic
|
||||
public fun fixDifferentiatorEmittingUpdatesWithWrongParentTag(): Boolean = accessor.fixDifferentiatorEmittingUpdatesWithWrongParentTag()
|
||||
|
||||
/**
|
||||
* Uses the default event priority instead of the discreet event priority by default when dispatching events from Fabric to React.
|
||||
*/
|
||||
|
||||
+11
-1
@@ -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<<031fce8e8b4c20a3e3d6dbecf94d138a>>
|
||||
* @generated SignedSource<<d75efd6beee8dd9d38b5d648fbecbcda>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -49,6 +49,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
|
||||
private var enableUIConsistencyCache: Boolean? = null
|
||||
private var enableViewRecyclingCache: Boolean? = null
|
||||
private var excludeYogaFromRawPropsCache: Boolean? = null
|
||||
private var fixDifferentiatorEmittingUpdatesWithWrongParentTagCache: Boolean? = null
|
||||
private var fixMappingOfEventPrioritiesBetweenFabricAndReactCache: Boolean? = null
|
||||
private var fixMountingCoordinatorReportedPendingTransactionsOnAndroidCache: Boolean? = null
|
||||
private var fuseboxEnabledDebugCache: Boolean? = null
|
||||
@@ -328,6 +329,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun fixDifferentiatorEmittingUpdatesWithWrongParentTag(): Boolean {
|
||||
var cached = fixDifferentiatorEmittingUpdatesWithWrongParentTagCache
|
||||
if (cached == null) {
|
||||
cached = ReactNativeFeatureFlagsCxxInterop.fixDifferentiatorEmittingUpdatesWithWrongParentTag()
|
||||
fixDifferentiatorEmittingUpdatesWithWrongParentTagCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun fixMappingOfEventPrioritiesBetweenFabricAndReact(): Boolean {
|
||||
var cached = fixMappingOfEventPrioritiesBetweenFabricAndReactCache
|
||||
if (cached == null) {
|
||||
|
||||
+3
-1
@@ -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<<35811667ac2543e1f64e27bbdb483ec1>>
|
||||
* @generated SignedSource<<7454ab19a01cfbb0a54f14bd83fc3a90>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -86,6 +86,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun excludeYogaFromRawProps(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun fixDifferentiatorEmittingUpdatesWithWrongParentTag(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun fixMappingOfEventPrioritiesBetweenFabricAndReact(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun fixMountingCoordinatorReportedPendingTransactionsOnAndroid(): Boolean
|
||||
|
||||
+3
-1
@@ -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<<9d829c58e49164a0b2b6b66bc0ce088a>>
|
||||
* @generated SignedSource<<70d951b2956759280afae4af8f9a2869>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -81,6 +81,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
|
||||
|
||||
override fun excludeYogaFromRawProps(): Boolean = false
|
||||
|
||||
override fun fixDifferentiatorEmittingUpdatesWithWrongParentTag(): Boolean = true
|
||||
|
||||
override fun fixMappingOfEventPrioritiesBetweenFabricAndReact(): Boolean = false
|
||||
|
||||
override fun fixMountingCoordinatorReportedPendingTransactionsOnAndroid(): Boolean = false
|
||||
|
||||
+12
-1
@@ -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<<0121e113410a5b0e14eaf74a3076df2f>>
|
||||
* @generated SignedSource<<f60000cb58a9632c3aa193854be3de4e>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -53,6 +53,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
|
||||
private var enableUIConsistencyCache: Boolean? = null
|
||||
private var enableViewRecyclingCache: Boolean? = null
|
||||
private var excludeYogaFromRawPropsCache: Boolean? = null
|
||||
private var fixDifferentiatorEmittingUpdatesWithWrongParentTagCache: Boolean? = null
|
||||
private var fixMappingOfEventPrioritiesBetweenFabricAndReactCache: Boolean? = null
|
||||
private var fixMountingCoordinatorReportedPendingTransactionsOnAndroidCache: Boolean? = null
|
||||
private var fuseboxEnabledDebugCache: Boolean? = null
|
||||
@@ -361,6 +362,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun fixDifferentiatorEmittingUpdatesWithWrongParentTag(): Boolean {
|
||||
var cached = fixDifferentiatorEmittingUpdatesWithWrongParentTagCache
|
||||
if (cached == null) {
|
||||
cached = currentProvider.fixDifferentiatorEmittingUpdatesWithWrongParentTag()
|
||||
accessedFeatureFlags.add("fixDifferentiatorEmittingUpdatesWithWrongParentTag")
|
||||
fixDifferentiatorEmittingUpdatesWithWrongParentTagCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun fixMappingOfEventPrioritiesBetweenFabricAndReact(): Boolean {
|
||||
var cached = fixMappingOfEventPrioritiesBetweenFabricAndReactCache
|
||||
if (cached == null) {
|
||||
|
||||
+3
-1
@@ -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<<2787d9027695dd14ec6b917a32a1a6de>>
|
||||
* @generated SignedSource<<d62af893c5d18a2152f098ff305ae41e>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -81,6 +81,8 @@ public interface ReactNativeFeatureFlagsProvider {
|
||||
|
||||
@DoNotStrip public fun excludeYogaFromRawProps(): Boolean
|
||||
|
||||
@DoNotStrip public fun fixDifferentiatorEmittingUpdatesWithWrongParentTag(): Boolean
|
||||
|
||||
@DoNotStrip public fun fixMappingOfEventPrioritiesBetweenFabricAndReact(): Boolean
|
||||
|
||||
@DoNotStrip public fun fixMountingCoordinatorReportedPendingTransactionsOnAndroid(): Boolean
|
||||
|
||||
+15
-1
@@ -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<<902b269e45fcb4970c6f8a86818e1940>>
|
||||
* @generated SignedSource<<640630d7a40b53f7d507569aa6409f69>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -213,6 +213,12 @@ class ReactNativeFeatureFlagsProviderHolder
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
bool fixDifferentiatorEmittingUpdatesWithWrongParentTag() override {
|
||||
static const auto method =
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("fixDifferentiatorEmittingUpdatesWithWrongParentTag");
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
bool fixMappingOfEventPrioritiesBetweenFabricAndReact() override {
|
||||
static const auto method =
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("fixMappingOfEventPrioritiesBetweenFabricAndReact");
|
||||
@@ -464,6 +470,11 @@ bool JReactNativeFeatureFlagsCxxInterop::excludeYogaFromRawProps(
|
||||
return ReactNativeFeatureFlags::excludeYogaFromRawProps();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::fixDifferentiatorEmittingUpdatesWithWrongParentTag(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
|
||||
return ReactNativeFeatureFlags::fixDifferentiatorEmittingUpdatesWithWrongParentTag();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::fixMappingOfEventPrioritiesBetweenFabricAndReact(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
|
||||
return ReactNativeFeatureFlags::fixMappingOfEventPrioritiesBetweenFabricAndReact();
|
||||
@@ -667,6 +678,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
|
||||
makeNativeMethod(
|
||||
"excludeYogaFromRawProps",
|
||||
JReactNativeFeatureFlagsCxxInterop::excludeYogaFromRawProps),
|
||||
makeNativeMethod(
|
||||
"fixDifferentiatorEmittingUpdatesWithWrongParentTag",
|
||||
JReactNativeFeatureFlagsCxxInterop::fixDifferentiatorEmittingUpdatesWithWrongParentTag),
|
||||
makeNativeMethod(
|
||||
"fixMappingOfEventPrioritiesBetweenFabricAndReact",
|
||||
JReactNativeFeatureFlagsCxxInterop::fixMappingOfEventPrioritiesBetweenFabricAndReact),
|
||||
|
||||
+4
-1
@@ -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<<17da0d7937c5c0c533293b86c8cdc9be>>
|
||||
* @generated SignedSource<<4218168e779a2241d0752771c1f51b12>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -117,6 +117,9 @@ class JReactNativeFeatureFlagsCxxInterop
|
||||
static bool excludeYogaFromRawProps(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool fixDifferentiatorEmittingUpdatesWithWrongParentTag(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool fixMappingOfEventPrioritiesBetweenFabricAndReact(
|
||||
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<<ef215623465d45c563030d724287b1c9>>
|
||||
* @generated SignedSource<<2409869111055ff0b32c1f40c10042d7>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -142,6 +142,10 @@ bool ReactNativeFeatureFlags::excludeYogaFromRawProps() {
|
||||
return getAccessor().excludeYogaFromRawProps();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlags::fixDifferentiatorEmittingUpdatesWithWrongParentTag() {
|
||||
return getAccessor().fixDifferentiatorEmittingUpdatesWithWrongParentTag();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlags::fixMappingOfEventPrioritiesBetweenFabricAndReact() {
|
||||
return getAccessor().fixMappingOfEventPrioritiesBetweenFabricAndReact();
|
||||
}
|
||||
|
||||
@@ -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<<f741660e4cf2528defe0ab1f61858aab>>
|
||||
* @generated SignedSource<<e628af8109a1d8bb6425515d824852a3>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -184,6 +184,11 @@ class ReactNativeFeatureFlags {
|
||||
*/
|
||||
RN_EXPORT static bool excludeYogaFromRawProps();
|
||||
|
||||
/**
|
||||
* Fixes a bug in Differentiator where parent views may be referenced before they're created
|
||||
*/
|
||||
RN_EXPORT static bool fixDifferentiatorEmittingUpdatesWithWrongParentTag();
|
||||
|
||||
/**
|
||||
* Uses the default event priority instead of the discreet event priority by default when dispatching events from Fabric to React.
|
||||
*/
|
||||
|
||||
+36
-18
@@ -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<<4c3956150bbf826c2abf4f8daf569b88>>
|
||||
* @generated SignedSource<<1e5b87b564e880cfb1423a85692092ba>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -551,6 +551,24 @@ bool ReactNativeFeatureFlagsAccessor::excludeYogaFromRawProps() {
|
||||
return flagValue.value();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlagsAccessor::fixDifferentiatorEmittingUpdatesWithWrongParentTag() {
|
||||
auto flagValue = fixDifferentiatorEmittingUpdatesWithWrongParentTag_.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(29, "fixDifferentiatorEmittingUpdatesWithWrongParentTag");
|
||||
|
||||
flagValue = currentProvider_->fixDifferentiatorEmittingUpdatesWithWrongParentTag();
|
||||
fixDifferentiatorEmittingUpdatesWithWrongParentTag_ = flagValue;
|
||||
}
|
||||
|
||||
return flagValue.value();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAndReact() {
|
||||
auto flagValue = fixMappingOfEventPrioritiesBetweenFabricAndReact_.load();
|
||||
|
||||
@@ -560,7 +578,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(29, "fixMappingOfEventPrioritiesBetweenFabricAndReact");
|
||||
markFlagAsAccessed(30, "fixMappingOfEventPrioritiesBetweenFabricAndReact");
|
||||
|
||||
flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact();
|
||||
fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue;
|
||||
@@ -578,7 +596,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(30, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid");
|
||||
markFlagAsAccessed(31, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid");
|
||||
|
||||
flagValue = currentProvider_->fixMountingCoordinatorReportedPendingTransactionsOnAndroid();
|
||||
fixMountingCoordinatorReportedPendingTransactionsOnAndroid_ = flagValue;
|
||||
@@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledDebug() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(31, "fuseboxEnabledDebug");
|
||||
markFlagAsAccessed(32, "fuseboxEnabledDebug");
|
||||
|
||||
flagValue = currentProvider_->fuseboxEnabledDebug();
|
||||
fuseboxEnabledDebug_ = flagValue;
|
||||
@@ -614,7 +632,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(32, "fuseboxEnabledRelease");
|
||||
markFlagAsAccessed(33, "fuseboxEnabledRelease");
|
||||
|
||||
flagValue = currentProvider_->fuseboxEnabledRelease();
|
||||
fuseboxEnabledRelease_ = flagValue;
|
||||
@@ -632,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::initEagerTurboModulesOnNativeModulesQueueA
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(33, "initEagerTurboModulesOnNativeModulesQueueAndroid");
|
||||
markFlagAsAccessed(34, "initEagerTurboModulesOnNativeModulesQueueAndroid");
|
||||
|
||||
flagValue = currentProvider_->initEagerTurboModulesOnNativeModulesQueueAndroid();
|
||||
initEagerTurboModulesOnNativeModulesQueueAndroid_ = flagValue;
|
||||
@@ -650,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::lazyAnimationCallbacks() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(34, "lazyAnimationCallbacks");
|
||||
markFlagAsAccessed(35, "lazyAnimationCallbacks");
|
||||
|
||||
flagValue = currentProvider_->lazyAnimationCallbacks();
|
||||
lazyAnimationCallbacks_ = flagValue;
|
||||
@@ -668,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::loadVectorDrawablesOnImages() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(35, "loadVectorDrawablesOnImages");
|
||||
markFlagAsAccessed(36, "loadVectorDrawablesOnImages");
|
||||
|
||||
flagValue = currentProvider_->loadVectorDrawablesOnImages();
|
||||
loadVectorDrawablesOnImages_ = flagValue;
|
||||
@@ -686,7 +704,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(36, "traceTurboModulePromiseRejectionsOnAndroid");
|
||||
markFlagAsAccessed(37, "traceTurboModulePromiseRejectionsOnAndroid");
|
||||
|
||||
flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid();
|
||||
traceTurboModulePromiseRejectionsOnAndroid_ = flagValue;
|
||||
@@ -704,7 +722,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(37, "useAlwaysAvailableJSErrorHandling");
|
||||
markFlagAsAccessed(38, "useAlwaysAvailableJSErrorHandling");
|
||||
|
||||
flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling();
|
||||
useAlwaysAvailableJSErrorHandling_ = flagValue;
|
||||
@@ -722,7 +740,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(38, "useFabricInterop");
|
||||
markFlagAsAccessed(39, "useFabricInterop");
|
||||
|
||||
flagValue = currentProvider_->useFabricInterop();
|
||||
useFabricInterop_ = flagValue;
|
||||
@@ -740,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::useImmediateExecutorInAndroidBridgeless()
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(39, "useImmediateExecutorInAndroidBridgeless");
|
||||
markFlagAsAccessed(40, "useImmediateExecutorInAndroidBridgeless");
|
||||
|
||||
flagValue = currentProvider_->useImmediateExecutorInAndroidBridgeless();
|
||||
useImmediateExecutorInAndroidBridgeless_ = flagValue;
|
||||
@@ -758,7 +776,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(40, "useNativeViewConfigsInBridgelessMode");
|
||||
markFlagAsAccessed(41, "useNativeViewConfigsInBridgelessMode");
|
||||
|
||||
flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode();
|
||||
useNativeViewConfigsInBridgelessMode_ = flagValue;
|
||||
@@ -776,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimisedViewPreallocationOnAndroid() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(41, "useOptimisedViewPreallocationOnAndroid");
|
||||
markFlagAsAccessed(42, "useOptimisedViewPreallocationOnAndroid");
|
||||
|
||||
flagValue = currentProvider_->useOptimisedViewPreallocationOnAndroid();
|
||||
useOptimisedViewPreallocationOnAndroid_ = flagValue;
|
||||
@@ -794,7 +812,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(42, "useOptimizedEventBatchingOnAndroid");
|
||||
markFlagAsAccessed(43, "useOptimizedEventBatchingOnAndroid");
|
||||
|
||||
flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid();
|
||||
useOptimizedEventBatchingOnAndroid_ = flagValue;
|
||||
@@ -812,7 +830,7 @@ bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdate() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(43, "useRuntimeShadowNodeReferenceUpdate");
|
||||
markFlagAsAccessed(44, "useRuntimeShadowNodeReferenceUpdate");
|
||||
|
||||
flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdate();
|
||||
useRuntimeShadowNodeReferenceUpdate_ = flagValue;
|
||||
@@ -830,7 +848,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(44, "useTurboModuleInterop");
|
||||
markFlagAsAccessed(45, "useTurboModuleInterop");
|
||||
|
||||
flagValue = currentProvider_->useTurboModuleInterop();
|
||||
useTurboModuleInterop_ = flagValue;
|
||||
@@ -848,7 +866,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(45, "useTurboModules");
|
||||
markFlagAsAccessed(46, "useTurboModules");
|
||||
|
||||
flagValue = currentProvider_->useTurboModules();
|
||||
useTurboModules_ = flagValue;
|
||||
|
||||
+4
-2
@@ -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<<3d98085a73dfc51541342dbb42ed89ab>>
|
||||
* @generated SignedSource<<eb44aabe7e352481267aa9a6bf035ff1>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -61,6 +61,7 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
bool enableUIConsistency();
|
||||
bool enableViewRecycling();
|
||||
bool excludeYogaFromRawProps();
|
||||
bool fixDifferentiatorEmittingUpdatesWithWrongParentTag();
|
||||
bool fixMappingOfEventPrioritiesBetweenFabricAndReact();
|
||||
bool fixMountingCoordinatorReportedPendingTransactionsOnAndroid();
|
||||
bool fuseboxEnabledDebug();
|
||||
@@ -89,7 +90,7 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
std::unique_ptr<ReactNativeFeatureFlagsProvider> currentProvider_;
|
||||
bool wasOverridden_;
|
||||
|
||||
std::array<std::atomic<const char*>, 46> accessedFeatureFlags_;
|
||||
std::array<std::atomic<const char*>, 47> accessedFeatureFlags_;
|
||||
|
||||
std::atomic<std::optional<bool>> commonTestFlag_;
|
||||
std::atomic<std::optional<bool>> completeReactInstanceCreationOnBgThreadOnAndroid_;
|
||||
@@ -120,6 +121,7 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
std::atomic<std::optional<bool>> enableUIConsistency_;
|
||||
std::atomic<std::optional<bool>> enableViewRecycling_;
|
||||
std::atomic<std::optional<bool>> excludeYogaFromRawProps_;
|
||||
std::atomic<std::optional<bool>> fixDifferentiatorEmittingUpdatesWithWrongParentTag_;
|
||||
std::atomic<std::optional<bool>> fixMappingOfEventPrioritiesBetweenFabricAndReact_;
|
||||
std::atomic<std::optional<bool>> fixMountingCoordinatorReportedPendingTransactionsOnAndroid_;
|
||||
std::atomic<std::optional<bool>> fuseboxEnabledDebug_;
|
||||
|
||||
+5
-1
@@ -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<<aff3c46b8d2db3bde519e1392569d53d>>
|
||||
* @generated SignedSource<<ee899be30798eb6d386b44bc6bc027ea>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -143,6 +143,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fixDifferentiatorEmittingUpdatesWithWrongParentTag() override {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool fixMappingOfEventPrioritiesBetweenFabricAndReact() override {
|
||||
return false;
|
||||
}
|
||||
|
||||
+2
-1
@@ -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<<8f8c7a372cdf9a3c06bc0d71f1ed85ad>>
|
||||
* @generated SignedSource<<e5d1c60102f7444332bd34627c02eddd>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -54,6 +54,7 @@ class ReactNativeFeatureFlagsProvider {
|
||||
virtual bool enableUIConsistency() = 0;
|
||||
virtual bool enableViewRecycling() = 0;
|
||||
virtual bool excludeYogaFromRawProps() = 0;
|
||||
virtual bool fixDifferentiatorEmittingUpdatesWithWrongParentTag() = 0;
|
||||
virtual bool fixMappingOfEventPrioritiesBetweenFabricAndReact() = 0;
|
||||
virtual bool fixMountingCoordinatorReportedPendingTransactionsOnAndroid() = 0;
|
||||
virtual bool fuseboxEnabledDebug() = 0;
|
||||
|
||||
+6
-1
@@ -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<<4808c1455f8e17c42036055dd6a81d7d>>
|
||||
* @generated SignedSource<<4055a9b5e34ff6740a99d4e08853fe7d>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -189,6 +189,11 @@ bool NativeReactNativeFeatureFlags::excludeYogaFromRawProps(
|
||||
return ReactNativeFeatureFlags::excludeYogaFromRawProps();
|
||||
}
|
||||
|
||||
bool NativeReactNativeFeatureFlags::fixDifferentiatorEmittingUpdatesWithWrongParentTag(
|
||||
jsi::Runtime& /*runtime*/) {
|
||||
return ReactNativeFeatureFlags::fixDifferentiatorEmittingUpdatesWithWrongParentTag();
|
||||
}
|
||||
|
||||
bool NativeReactNativeFeatureFlags::fixMappingOfEventPrioritiesBetweenFabricAndReact(
|
||||
jsi::Runtime& /*runtime*/) {
|
||||
return ReactNativeFeatureFlags::fixMappingOfEventPrioritiesBetweenFabricAndReact();
|
||||
|
||||
+3
-1
@@ -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<<6b4909879b76908792d89e3f24c1453a>>
|
||||
* @generated SignedSource<<9541abe6da92d991557ca6d2f1e36a9a>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -95,6 +95,8 @@ class NativeReactNativeFeatureFlags
|
||||
|
||||
bool excludeYogaFromRawProps(jsi::Runtime& runtime);
|
||||
|
||||
bool fixDifferentiatorEmittingUpdatesWithWrongParentTag(jsi::Runtime& runtime);
|
||||
|
||||
bool fixMappingOfEventPrioritiesBetweenFabricAndReact(jsi::Runtime& runtime);
|
||||
|
||||
bool fixMountingCoordinatorReportedPendingTransactionsOnAndroid(jsi::Runtime& runtime);
|
||||
|
||||
+9
-1
@@ -13,7 +13,7 @@
|
||||
|
||||
#include <react/debug/flags.h>
|
||||
#include <react/debug/react_native_assert.h>
|
||||
|
||||
#include <react/featureflags/ReactNativeFeatureFlags.h>
|
||||
#include <react/renderer/animations/conversions.h>
|
||||
#include <react/renderer/animations/utils.h>
|
||||
#include <react/renderer/components/image/ImageProps.h>
|
||||
@@ -392,6 +392,14 @@ LayoutAnimationKeyFrameManager::pullTransaction(
|
||||
if (keyframe.type == AnimationConfigurationType::Update &&
|
||||
mutation.newChildShadowView.tag > 0) {
|
||||
keyframe.viewPrev = mutation.newChildShadowView;
|
||||
if (ReactNativeFeatureFlags::
|
||||
fixDifferentiatorEmittingUpdatesWithWrongParentTag()) {
|
||||
keyframe.parentView = mutation.parentShadowView;
|
||||
react_native_assert(
|
||||
keyframe.finalMutationsForKeyFrame.size() == 1);
|
||||
keyframe.finalMutationsForKeyFrame[0].parentShadowView =
|
||||
mutation.parentShadowView;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,6 +403,7 @@ static void calculateShadowViewMutationsFlattener(
|
||||
const ShadowView& parentShadowView,
|
||||
TinyMap<Tag, ShadowViewNodePair*>& unvisitedOtherNodes,
|
||||
const ShadowViewNodePair& node,
|
||||
const ShadowView& parentShadowViewForUpdate,
|
||||
TinyMap<Tag, ShadowViewNodePair*>* parentSubVisitedOtherNewNodes = nullptr,
|
||||
TinyMap<Tag, ShadowViewNodePair*>* parentSubVisitedOtherOldNodes = nullptr);
|
||||
|
||||
@@ -450,7 +451,8 @@ static void updateMatchedPairSubtrees(
|
||||
mutationContainer,
|
||||
parentShadowView,
|
||||
newRemainingPairs,
|
||||
oldPair);
|
||||
oldPair,
|
||||
oldPair.shadowView);
|
||||
}
|
||||
// Unflattening
|
||||
else {
|
||||
@@ -480,7 +482,8 @@ static void updateMatchedPairSubtrees(
|
||||
mutationContainer,
|
||||
parentShadowView,
|
||||
unvisitedOldChildPairs,
|
||||
newPair);
|
||||
newPair,
|
||||
parentShadowView);
|
||||
|
||||
// If old nodes were not visited, we know that we can delete
|
||||
// them now. They will be removed from the hierarchy by the
|
||||
@@ -621,6 +624,10 @@ static void updateMatchedPair(
|
||||
* performed in the subtree. If it *is* in the map, it means the node is not
|
||||
* in the Tree, and should be Deleted/Created **after this function is
|
||||
* called**, by the caller.
|
||||
*
|
||||
* @param parentShadowView shadowView under which nodes should be mounted
|
||||
* @param parentShadowViewForUpdate current parent in which node is mounted,
|
||||
* used for update mutations
|
||||
*/
|
||||
static void calculateShadowViewMutationsFlattener(
|
||||
ViewNodePairScope& scope,
|
||||
@@ -629,6 +636,7 @@ static void calculateShadowViewMutationsFlattener(
|
||||
const ShadowView& parentShadowView,
|
||||
TinyMap<Tag, ShadowViewNodePair*>& unvisitedOtherNodes,
|
||||
const ShadowViewNodePair& node,
|
||||
const ShadowView& parentShadowViewForUpdate,
|
||||
TinyMap<Tag, ShadowViewNodePair*>* parentSubVisitedOtherNewNodes,
|
||||
TinyMap<Tag, ShadowViewNodePair*>* parentSubVisitedOtherOldNodes) {
|
||||
DEBUG_LOGS({
|
||||
@@ -838,11 +846,18 @@ static void calculateShadowViewMutationsFlattener(
|
||||
// ShadowNode.
|
||||
if (newTreeNodePair.shadowView != oldTreeNodePair.shadowView &&
|
||||
newTreeNodePair.isConcreteView && oldTreeNodePair.isConcreteView) {
|
||||
// We execute updates before creates, so pass the current parent in when
|
||||
// unflattening.
|
||||
// TODO: whenever we insert, we already update the relevant properties,
|
||||
// so this update is redundant. We should remove this.
|
||||
mutationContainer.updateMutations.push_back(
|
||||
ShadowViewMutation::UpdateMutation(
|
||||
oldTreeNodePair.shadowView,
|
||||
newTreeNodePair.shadowView,
|
||||
node.shadowView));
|
||||
ReactNativeFeatureFlags::
|
||||
fixDifferentiatorEmittingUpdatesWithWrongParentTag()
|
||||
? parentShadowViewForUpdate
|
||||
: node.shadowView));
|
||||
}
|
||||
|
||||
// Update children if appropriate.
|
||||
@@ -877,6 +892,9 @@ static void calculateShadowViewMutationsFlattener(
|
||||
: newTreeNodePair.shadowView),
|
||||
unvisitedOtherNodes,
|
||||
treeChildPair,
|
||||
(reparentMode == ReparentMode::Flatten
|
||||
? oldTreeNodePair.shadowView
|
||||
: parentShadowView),
|
||||
subVisitedNewMap,
|
||||
subVisitedOldMap);
|
||||
} else {
|
||||
@@ -918,6 +936,9 @@ static void calculateShadowViewMutationsFlattener(
|
||||
: newTreeNodePair.shadowView),
|
||||
unvisitedRecursiveChildPairs,
|
||||
oldTreeNodePair,
|
||||
(reparentMode == ReparentMode::Flatten
|
||||
? oldTreeNodePair.shadowView
|
||||
: parentShadowView),
|
||||
subVisitedNewMap,
|
||||
subVisitedOldMap);
|
||||
}
|
||||
@@ -933,6 +954,9 @@ static void calculateShadowViewMutationsFlattener(
|
||||
: newTreeNodePair.shadowView),
|
||||
unvisitedRecursiveChildPairs,
|
||||
newTreeNodePair,
|
||||
(reparentMode == ReparentMode::Flatten
|
||||
? oldTreeNodePair.shadowView
|
||||
: parentShadowView),
|
||||
subVisitedNewMap,
|
||||
subVisitedOldMap);
|
||||
|
||||
|
||||
@@ -221,6 +221,11 @@ void StubViewTree::mutate(const ShadowViewMutationList& mutations) {
|
||||
react_native_assert(hasTag(mutation.newChildShadowView.tag));
|
||||
auto oldStubView = registry_[mutation.newChildShadowView.tag];
|
||||
react_native_assert(oldStubView->tag != 0);
|
||||
if (mutation.parentShadowView.tag != 0) {
|
||||
react_native_assert(hasTag(mutation.parentShadowView.tag));
|
||||
react_native_assert(
|
||||
oldStubView->parentTag == mutation.parentShadowView.tag);
|
||||
}
|
||||
if ((ShadowView)(*oldStubView) != mutation.oldChildShadowView) {
|
||||
LOG(ERROR)
|
||||
<< "StubView: ASSERT FAILURE: UPDATE mutation assertion failure: oldChildShadowView does not match oldStubView: ["
|
||||
|
||||
@@ -558,8 +558,7 @@ TEST(MountingTest, testViewReparentingInstructionGeneration) {
|
||||
EXPECT_EQ(mutations1[0].oldChildShadowView.tag, childG->getTag());
|
||||
EXPECT_EQ(mutations1[1].type, ShadowViewMutation::Update);
|
||||
EXPECT_EQ(mutations1[1].oldChildShadowView.tag, reparentedViewA->getTag());
|
||||
// This is incorrect! ChildH does not exist yet at this point
|
||||
EXPECT_EQ(mutations1[1].parentShadowView.tag, childH->getTag());
|
||||
EXPECT_EQ(mutations1[1].parentShadowView.tag, childG->getTag());
|
||||
EXPECT_EQ(mutations1[2].type, ShadowViewMutation::Remove);
|
||||
EXPECT_EQ(mutations1[2].oldChildShadowView.tag, reparentedViewA->getTag());
|
||||
EXPECT_EQ(mutations1[3].type, ShadowViewMutation::Create);
|
||||
|
||||
@@ -292,6 +292,14 @@ const definitions: FeatureFlagDefinitions = {
|
||||
purpose: 'experimentation',
|
||||
},
|
||||
},
|
||||
fixDifferentiatorEmittingUpdatesWithWrongParentTag: {
|
||||
defaultValue: true,
|
||||
metadata: {
|
||||
description:
|
||||
"Fixes a bug in Differentiator where parent views may be referenced before they're created",
|
||||
purpose: 'release',
|
||||
},
|
||||
},
|
||||
fixMappingOfEventPrioritiesBetweenFabricAndReact: {
|
||||
defaultValue: false,
|
||||
metadata: {
|
||||
|
||||
@@ -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<<38ad29621eeb29a9f82735dc187c13d4>>
|
||||
* @generated SignedSource<<ceb682684f8c9df33a3f432033ab266a>>
|
||||
* @flow strict
|
||||
*/
|
||||
|
||||
@@ -80,6 +80,7 @@ export type ReactNativeFeatureFlags = {
|
||||
enableUIConsistency: Getter<boolean>,
|
||||
enableViewRecycling: Getter<boolean>,
|
||||
excludeYogaFromRawProps: Getter<boolean>,
|
||||
fixDifferentiatorEmittingUpdatesWithWrongParentTag: Getter<boolean>,
|
||||
fixMappingOfEventPrioritiesBetweenFabricAndReact: Getter<boolean>,
|
||||
fixMountingCoordinatorReportedPendingTransactionsOnAndroid: Getter<boolean>,
|
||||
fuseboxEnabledDebug: Getter<boolean>,
|
||||
@@ -304,6 +305,10 @@ export const enableViewRecycling: Getter<boolean> = createNativeFlagGetter('enab
|
||||
* When enabled, rawProps in Props will not include Yoga specific props.
|
||||
*/
|
||||
export const excludeYogaFromRawProps: Getter<boolean> = createNativeFlagGetter('excludeYogaFromRawProps', false);
|
||||
/**
|
||||
* Fixes a bug in Differentiator where parent views may be referenced before they're created
|
||||
*/
|
||||
export const fixDifferentiatorEmittingUpdatesWithWrongParentTag: Getter<boolean> = createNativeFlagGetter('fixDifferentiatorEmittingUpdatesWithWrongParentTag', true);
|
||||
/**
|
||||
* Uses the default event priority instead of the discreet event priority by default when dispatching events from Fabric to React.
|
||||
*/
|
||||
|
||||
+2
-1
@@ -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<<17c0e677f7b308795e836c558b15d1d1>>
|
||||
* @generated SignedSource<<b36732a4a633b239ebd6d12d1ef460cb>>
|
||||
* @flow strict
|
||||
*/
|
||||
|
||||
@@ -53,6 +53,7 @@ export interface Spec extends TurboModule {
|
||||
+enableUIConsistency?: () => boolean;
|
||||
+enableViewRecycling?: () => boolean;
|
||||
+excludeYogaFromRawProps?: () => boolean;
|
||||
+fixDifferentiatorEmittingUpdatesWithWrongParentTag?: () => boolean;
|
||||
+fixMappingOfEventPrioritiesBetweenFabricAndReact?: () => boolean;
|
||||
+fixMountingCoordinatorReportedPendingTransactionsOnAndroid?: () => boolean;
|
||||
+fuseboxEnabledDebug?: () => boolean;
|
||||
|
||||
Reference in New Issue
Block a user