mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Set up experiment to fix race conditions when doing Fabric state updates on Android (#45236)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/45236 Changelog: [internal] ## Context We're currently observing inconsistencies between the state of the UI on Android and the propagated state in Fabric. When investigating the issue, we saw that there are some state updates that were going to be dispatched from scroll views to Fabric were skipped because the state object in native was deallocated. The reason for that is a race condition between: 1. Dispatching new state updates from the UI thread 2. Updating the state previously dispatched from the UI thread on the JS thread. {F1735383134} ## Changes This creates a new feature flag to replace the weak reference with a strong one, so when the previous state is deallocated we can still access it to set new state. The use of weak references was introduced in D44472121 to avoid holding onto JSI references (which could be contained in the state) when the runtime was deallocated, but we later introduced an explicit clean up mechanism in D45905628 that would make that unnecessary. Reviewed By: javache Differential Revision: D59233070 fbshipit-source-id: 018d8935f506430ecab96df0f7a998a37ee0f556
This commit is contained in:
committed by
Facebook GitHub Bot
parent
c25246044f
commit
818e70f7eb
+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<<9a33a6bc10cdb2b0f9fcb15805a06982>>
|
||||
* @generated SignedSource<<e031aebb1124ba925f1d725d267043c4>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -100,6 +100,12 @@ public object ReactNativeFeatureFlags {
|
||||
@JvmStatic
|
||||
public fun fixMappingOfEventPrioritiesBetweenFabricAndReact(): Boolean = accessor.fixMappingOfEventPrioritiesBetweenFabricAndReact()
|
||||
|
||||
/**
|
||||
* Enables a fix to prevent the possibility of state updates in Fabric being missed due to race conditions with previous state updates.
|
||||
*/
|
||||
@JvmStatic
|
||||
public fun fixMissedFabricStateUpdatesOnAndroid(): Boolean = accessor.fixMissedFabricStateUpdatesOnAndroid()
|
||||
|
||||
/**
|
||||
* Fixes a leak in SurfaceMountingManager.mRemoveDeleteTreeUIFrameCallback
|
||||
*/
|
||||
|
||||
+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<<5d67280406c16b01ba71b7b75e814a79>>
|
||||
* @generated SignedSource<<92ebcb510939039fc157e0f85b08073e>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -32,6 +32,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
|
||||
private var enableSynchronousStateUpdatesCache: Boolean? = null
|
||||
private var enableUIConsistencyCache: Boolean? = null
|
||||
private var fixMappingOfEventPrioritiesBetweenFabricAndReactCache: Boolean? = null
|
||||
private var fixMissedFabricStateUpdatesOnAndroidCache: Boolean? = null
|
||||
private var fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeakCache: Boolean? = null
|
||||
private var forceBatchingMountItemsOnAndroidCache: Boolean? = null
|
||||
private var fuseboxEnabledDebugCache: Boolean? = null
|
||||
@@ -154,6 +155,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun fixMissedFabricStateUpdatesOnAndroid(): Boolean {
|
||||
var cached = fixMissedFabricStateUpdatesOnAndroidCache
|
||||
if (cached == null) {
|
||||
cached = ReactNativeFeatureFlagsCxxInterop.fixMissedFabricStateUpdatesOnAndroid()
|
||||
fixMissedFabricStateUpdatesOnAndroidCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak(): Boolean {
|
||||
var cached = fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeakCache
|
||||
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<<154baea748cdf7b8e05a1e4448053673>>
|
||||
* @generated SignedSource<<2434a09bc40a30291c642a26453f939f>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -52,6 +52,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun fixMappingOfEventPrioritiesBetweenFabricAndReact(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun fixMissedFabricStateUpdatesOnAndroid(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun forceBatchingMountItemsOnAndroid(): 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<<34bbd584a612fa88cc6adf2d2bc51b92>>
|
||||
* @generated SignedSource<<b2e96bbb47ac02eac2216200ecb12f17>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -47,6 +47,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
|
||||
|
||||
override fun fixMappingOfEventPrioritiesBetweenFabricAndReact(): Boolean = false
|
||||
|
||||
override fun fixMissedFabricStateUpdatesOnAndroid(): Boolean = false
|
||||
|
||||
override fun fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak(): Boolean = false
|
||||
|
||||
override fun forceBatchingMountItemsOnAndroid(): 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<<d991cac9311ee91e5e9401b143b69145>>
|
||||
* @generated SignedSource<<65a88218f057b56211d84b6d473e8a90>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -36,6 +36,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
|
||||
private var enableSynchronousStateUpdatesCache: Boolean? = null
|
||||
private var enableUIConsistencyCache: Boolean? = null
|
||||
private var fixMappingOfEventPrioritiesBetweenFabricAndReactCache: Boolean? = null
|
||||
private var fixMissedFabricStateUpdatesOnAndroidCache: Boolean? = null
|
||||
private var fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeakCache: Boolean? = null
|
||||
private var forceBatchingMountItemsOnAndroidCache: Boolean? = null
|
||||
private var fuseboxEnabledDebugCache: Boolean? = null
|
||||
@@ -170,6 +171,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun fixMissedFabricStateUpdatesOnAndroid(): Boolean {
|
||||
var cached = fixMissedFabricStateUpdatesOnAndroidCache
|
||||
if (cached == null) {
|
||||
cached = currentProvider.fixMissedFabricStateUpdatesOnAndroid()
|
||||
accessedFeatureFlags.add("fixMissedFabricStateUpdatesOnAndroid")
|
||||
fixMissedFabricStateUpdatesOnAndroidCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak(): Boolean {
|
||||
var cached = fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeakCache
|
||||
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<<aae9b8936680c1cd6db2c1c0135e1cef>>
|
||||
* @generated SignedSource<<3a0f547e2b68072a76b1eabc28c371cb>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -47,6 +47,8 @@ public interface ReactNativeFeatureFlagsProvider {
|
||||
|
||||
@DoNotStrip public fun fixMappingOfEventPrioritiesBetweenFabricAndReact(): Boolean
|
||||
|
||||
@DoNotStrip public fun fixMissedFabricStateUpdatesOnAndroid(): Boolean
|
||||
|
||||
@DoNotStrip public fun fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak(): Boolean
|
||||
|
||||
@DoNotStrip public fun forceBatchingMountItemsOnAndroid(): Boolean
|
||||
|
||||
+3
-3
@@ -540,7 +540,7 @@ void FabricMountingManager::executeMount(
|
||||
if (mountItem.newChildShadowView.state != nullptr) {
|
||||
javaStateWrapper = StateWrapperImpl::newObjectJavaArgs();
|
||||
StateWrapperImpl* cStateWrapper = cthis(javaStateWrapper);
|
||||
cStateWrapper->state_ = mountItem.newChildShadowView.state;
|
||||
cStateWrapper->setState(mountItem.newChildShadowView.state);
|
||||
}
|
||||
|
||||
// Do not hold a reference to javaEventEmitter from the C++ side.
|
||||
@@ -615,7 +615,7 @@ void FabricMountingManager::executeMount(
|
||||
if (state != nullptr) {
|
||||
javaStateWrapper = StateWrapperImpl::newObjectJavaArgs();
|
||||
StateWrapperImpl* cStateWrapper = cthis(javaStateWrapper);
|
||||
cStateWrapper->state_ = state;
|
||||
cStateWrapper->setState(state);
|
||||
}
|
||||
|
||||
(*objBufferArray)[objBufferPosition++] =
|
||||
@@ -823,7 +823,7 @@ void FabricMountingManager::preallocateShadowView(
|
||||
if (shadowView.state != nullptr) {
|
||||
javaStateWrapper = StateWrapperImpl::newObjectJavaArgs();
|
||||
StateWrapperImpl* cStateWrapper = cthis(javaStateWrapper);
|
||||
cStateWrapper->state_ = shadowView.state;
|
||||
cStateWrapper->setState(shadowView.state);
|
||||
}
|
||||
|
||||
// Do not hold a reference to javaEventEmitter from the C++ side.
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "StateWrapperImpl.h"
|
||||
#include <fbjni/fbjni.h>
|
||||
#include <react/featureflags/ReactNativeFeatureFlags.h>
|
||||
#include <react/jni/ReadableNativeMap.h>
|
||||
#include <react/renderer/mapbuffer/MapBuffer.h>
|
||||
#include <react/renderer/mapbuffer/MapBufferBuilder.h>
|
||||
@@ -25,30 +26,65 @@ jni::local_ref<StateWrapperImpl::jhybriddata> StateWrapperImpl::initHybrid(
|
||||
|
||||
jni::local_ref<ReadableNativeMap::jhybridobject>
|
||||
StateWrapperImpl::getStateDataImpl() {
|
||||
if (auto state = state_.lock()) {
|
||||
folly::dynamic map = state->getDynamic();
|
||||
return ReadableNativeMap::newObjectCxxArgs(std::move(map));
|
||||
if (ReactNativeFeatureFlags::fixMissedFabricStateUpdatesOnAndroid()) {
|
||||
if (state_) {
|
||||
folly::dynamic map = state_->getDynamic();
|
||||
return ReadableNativeMap::newObjectCxxArgs(std::move(map));
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
return nullptr;
|
||||
if (auto state = weakState_.lock()) {
|
||||
folly::dynamic map = state->getDynamic();
|
||||
return ReadableNativeMap::newObjectCxxArgs(std::move(map));
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jni::local_ref<JReadableMapBuffer::jhybridobject>
|
||||
StateWrapperImpl::getStateMapBufferDataImpl() {
|
||||
if (auto state = state_.lock()) {
|
||||
MapBuffer map = state->getMapBuffer();
|
||||
return JReadableMapBuffer::createWithContents(std::move(map));
|
||||
if (ReactNativeFeatureFlags::fixMissedFabricStateUpdatesOnAndroid()) {
|
||||
if (state_) {
|
||||
MapBuffer map = state_->getMapBuffer();
|
||||
return JReadableMapBuffer::createWithContents(std::move(map));
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
return nullptr;
|
||||
if (auto state = weakState_.lock()) {
|
||||
MapBuffer map = state->getMapBuffer();
|
||||
return JReadableMapBuffer::createWithContents(std::move(map));
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StateWrapperImpl::updateStateImpl(NativeMap* map) {
|
||||
if (auto state = state_.lock()) {
|
||||
// Get folly::dynamic from map
|
||||
auto dynamicMap = map->consume();
|
||||
// Set state
|
||||
state->updateState(std::move(dynamicMap));
|
||||
if (ReactNativeFeatureFlags::fixMissedFabricStateUpdatesOnAndroid()) {
|
||||
if (state_) {
|
||||
// Get folly::dynamic from map
|
||||
auto dynamicMap = map->consume();
|
||||
// Set state
|
||||
state_->updateState(std::move(dynamicMap));
|
||||
}
|
||||
} else {
|
||||
if (auto state = weakState_.lock()) {
|
||||
// Get folly::dynamic from map
|
||||
auto dynamicMap = map->consume();
|
||||
// Set state
|
||||
state->updateState(std::move(dynamicMap));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StateWrapperImpl::setState(std::shared_ptr<const State> state) {
|
||||
if (ReactNativeFeatureFlags::fixMissedFabricStateUpdatesOnAndroid()) {
|
||||
state_ = state;
|
||||
} else {
|
||||
weakState_ = state;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,11 +28,12 @@ class StateWrapperImpl : public jni::HybridClass<StateWrapperImpl> {
|
||||
jni::local_ref<JReadableMapBuffer::jhybridobject> getStateMapBufferDataImpl();
|
||||
jni::local_ref<ReadableNativeMap::jhybridobject> getStateDataImpl();
|
||||
void updateStateImpl(NativeMap* map);
|
||||
|
||||
std::weak_ptr<const State> state_;
|
||||
void setState(std::shared_ptr<const State> state);
|
||||
|
||||
private:
|
||||
jni::alias_ref<StateWrapperImpl::jhybriddata> jhybridobject_;
|
||||
std::weak_ptr<const State> weakState_;
|
||||
std::shared_ptr<const State> state_;
|
||||
|
||||
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>);
|
||||
};
|
||||
|
||||
+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<<88f5b83b8a3d7902eaab333246b59ed3>>
|
||||
* @generated SignedSource<<f245741c5e9986bc1e2a4c53613fe000>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -111,6 +111,12 @@ class ReactNativeFeatureFlagsProviderHolder
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
bool fixMissedFabricStateUpdatesOnAndroid() override {
|
||||
static const auto method =
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("fixMissedFabricStateUpdatesOnAndroid");
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
bool fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak() override {
|
||||
static const auto method =
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak");
|
||||
@@ -253,6 +259,11 @@ bool JReactNativeFeatureFlagsCxxInterop::fixMappingOfEventPrioritiesBetweenFabri
|
||||
return ReactNativeFeatureFlags::fixMappingOfEventPrioritiesBetweenFabricAndReact();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::fixMissedFabricStateUpdatesOnAndroid(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
|
||||
return ReactNativeFeatureFlags::fixMissedFabricStateUpdatesOnAndroid();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
|
||||
return ReactNativeFeatureFlags::fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak();
|
||||
@@ -371,6 +382,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
|
||||
makeNativeMethod(
|
||||
"fixMappingOfEventPrioritiesBetweenFabricAndReact",
|
||||
JReactNativeFeatureFlagsCxxInterop::fixMappingOfEventPrioritiesBetweenFabricAndReact),
|
||||
makeNativeMethod(
|
||||
"fixMissedFabricStateUpdatesOnAndroid",
|
||||
JReactNativeFeatureFlagsCxxInterop::fixMissedFabricStateUpdatesOnAndroid),
|
||||
makeNativeMethod(
|
||||
"fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak",
|
||||
JReactNativeFeatureFlagsCxxInterop::fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak),
|
||||
|
||||
+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<<66b47850d8e211f78b3e3dd40b6cc37e>>
|
||||
* @generated SignedSource<<7e9c48995f6a5f4e0a56c0f2ec784def>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -66,6 +66,9 @@ class JReactNativeFeatureFlagsCxxInterop
|
||||
static bool fixMappingOfEventPrioritiesBetweenFabricAndReact(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool fixMissedFabricStateUpdatesOnAndroid(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak(
|
||||
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<<dd5872a21f84a41bea247e137541ddfc>>
|
||||
* @generated SignedSource<<91a56189178d461874bfff11b14ca318>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -69,6 +69,10 @@ bool ReactNativeFeatureFlags::fixMappingOfEventPrioritiesBetweenFabricAndReact()
|
||||
return getAccessor().fixMappingOfEventPrioritiesBetweenFabricAndReact();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlags::fixMissedFabricStateUpdatesOnAndroid() {
|
||||
return getAccessor().fixMissedFabricStateUpdatesOnAndroid();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlags::fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak() {
|
||||
return getAccessor().fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak();
|
||||
}
|
||||
|
||||
@@ -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<<e45c35dee2c9e2135995ccf2c8a6def3>>
|
||||
* @generated SignedSource<<6683bcf499d88e4449f570f38b7d8b2f>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -97,6 +97,11 @@ class ReactNativeFeatureFlags {
|
||||
*/
|
||||
RN_EXPORT static bool fixMappingOfEventPrioritiesBetweenFabricAndReact();
|
||||
|
||||
/**
|
||||
* Enables a fix to prevent the possibility of state updates in Fabric being missed due to race conditions with previous state updates.
|
||||
*/
|
||||
RN_EXPORT static bool fixMissedFabricStateUpdatesOnAndroid();
|
||||
|
||||
/**
|
||||
* Fixes a leak in SurfaceMountingManager.mRemoveDeleteTreeUIFrameCallback
|
||||
*/
|
||||
|
||||
+32
-14
@@ -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<<44087cc6e946a05884c8761987878183>>
|
||||
* @generated SignedSource<<e6fb2d4186ceec77a58ce6156f1cefad>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -245,6 +245,24 @@ bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAn
|
||||
return flagValue.value();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlagsAccessor::fixMissedFabricStateUpdatesOnAndroid() {
|
||||
auto flagValue = fixMissedFabricStateUpdatesOnAndroid_.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(12, "fixMissedFabricStateUpdatesOnAndroid");
|
||||
|
||||
flagValue = currentProvider_->fixMissedFabricStateUpdatesOnAndroid();
|
||||
fixMissedFabricStateUpdatesOnAndroid_ = flagValue;
|
||||
}
|
||||
|
||||
return flagValue.value();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlagsAccessor::fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak() {
|
||||
auto flagValue = fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak_.load();
|
||||
|
||||
@@ -254,7 +272,7 @@ bool ReactNativeFeatureFlagsAccessor::fixStoppedSurfaceRemoveDeleteTreeUIFrameCa
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(12, "fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak");
|
||||
markFlagAsAccessed(13, "fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak");
|
||||
|
||||
flagValue = currentProvider_->fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak();
|
||||
fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak_ = flagValue;
|
||||
@@ -272,7 +290,7 @@ bool ReactNativeFeatureFlagsAccessor::forceBatchingMountItemsOnAndroid() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(13, "forceBatchingMountItemsOnAndroid");
|
||||
markFlagAsAccessed(14, "forceBatchingMountItemsOnAndroid");
|
||||
|
||||
flagValue = currentProvider_->forceBatchingMountItemsOnAndroid();
|
||||
forceBatchingMountItemsOnAndroid_ = flagValue;
|
||||
@@ -290,7 +308,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(14, "fuseboxEnabledDebug");
|
||||
markFlagAsAccessed(15, "fuseboxEnabledDebug");
|
||||
|
||||
flagValue = currentProvider_->fuseboxEnabledDebug();
|
||||
fuseboxEnabledDebug_ = flagValue;
|
||||
@@ -308,7 +326,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(15, "fuseboxEnabledRelease");
|
||||
markFlagAsAccessed(16, "fuseboxEnabledRelease");
|
||||
|
||||
flagValue = currentProvider_->fuseboxEnabledRelease();
|
||||
fuseboxEnabledRelease_ = flagValue;
|
||||
@@ -326,7 +344,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(16, "lazyAnimationCallbacks");
|
||||
markFlagAsAccessed(17, "lazyAnimationCallbacks");
|
||||
|
||||
flagValue = currentProvider_->lazyAnimationCallbacks();
|
||||
lazyAnimationCallbacks_ = flagValue;
|
||||
@@ -344,7 +362,7 @@ bool ReactNativeFeatureFlagsAccessor::preventDoubleTextMeasure() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(17, "preventDoubleTextMeasure");
|
||||
markFlagAsAccessed(18, "preventDoubleTextMeasure");
|
||||
|
||||
flagValue = currentProvider_->preventDoubleTextMeasure();
|
||||
preventDoubleTextMeasure_ = flagValue;
|
||||
@@ -362,7 +380,7 @@ bool ReactNativeFeatureFlagsAccessor::setAndroidLayoutDirection() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(18, "setAndroidLayoutDirection");
|
||||
markFlagAsAccessed(19, "setAndroidLayoutDirection");
|
||||
|
||||
flagValue = currentProvider_->setAndroidLayoutDirection();
|
||||
setAndroidLayoutDirection_ = flagValue;
|
||||
@@ -380,7 +398,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(19, "useImmediateExecutorInAndroidBridgeless");
|
||||
markFlagAsAccessed(20, "useImmediateExecutorInAndroidBridgeless");
|
||||
|
||||
flagValue = currentProvider_->useImmediateExecutorInAndroidBridgeless();
|
||||
useImmediateExecutorInAndroidBridgeless_ = flagValue;
|
||||
@@ -398,7 +416,7 @@ bool ReactNativeFeatureFlagsAccessor::useModernRuntimeScheduler() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(20, "useModernRuntimeScheduler");
|
||||
markFlagAsAccessed(21, "useModernRuntimeScheduler");
|
||||
|
||||
flagValue = currentProvider_->useModernRuntimeScheduler();
|
||||
useModernRuntimeScheduler_ = flagValue;
|
||||
@@ -416,7 +434,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(21, "useNativeViewConfigsInBridgelessMode");
|
||||
markFlagAsAccessed(22, "useNativeViewConfigsInBridgelessMode");
|
||||
|
||||
flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode();
|
||||
useNativeViewConfigsInBridgelessMode_ = flagValue;
|
||||
@@ -434,7 +452,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(22, "useRuntimeShadowNodeReferenceUpdate");
|
||||
markFlagAsAccessed(23, "useRuntimeShadowNodeReferenceUpdate");
|
||||
|
||||
flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdate();
|
||||
useRuntimeShadowNodeReferenceUpdate_ = flagValue;
|
||||
@@ -452,7 +470,7 @@ bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdateOnLayou
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(23, "useRuntimeShadowNodeReferenceUpdateOnLayout");
|
||||
markFlagAsAccessed(24, "useRuntimeShadowNodeReferenceUpdateOnLayout");
|
||||
|
||||
flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdateOnLayout();
|
||||
useRuntimeShadowNodeReferenceUpdateOnLayout_ = flagValue;
|
||||
@@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::useStateAlignmentMechanism() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(24, "useStateAlignmentMechanism");
|
||||
markFlagAsAccessed(25, "useStateAlignmentMechanism");
|
||||
|
||||
flagValue = currentProvider_->useStateAlignmentMechanism();
|
||||
useStateAlignmentMechanism_ = 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<<45258896e458cce165b403e043356eb9>>
|
||||
* @generated SignedSource<<c4afa05f0c2a175476d82a52d47c3b91>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -43,6 +43,7 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
bool enableSynchronousStateUpdates();
|
||||
bool enableUIConsistency();
|
||||
bool fixMappingOfEventPrioritiesBetweenFabricAndReact();
|
||||
bool fixMissedFabricStateUpdatesOnAndroid();
|
||||
bool fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak();
|
||||
bool forceBatchingMountItemsOnAndroid();
|
||||
bool fuseboxEnabledDebug();
|
||||
@@ -66,7 +67,7 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
std::unique_ptr<ReactNativeFeatureFlagsProvider> currentProvider_;
|
||||
bool wasOverridden_;
|
||||
|
||||
std::array<std::atomic<const char*>, 25> accessedFeatureFlags_;
|
||||
std::array<std::atomic<const char*>, 26> accessedFeatureFlags_;
|
||||
|
||||
std::atomic<std::optional<bool>> commonTestFlag_;
|
||||
std::atomic<std::optional<bool>> allowCollapsableChildren_;
|
||||
@@ -80,6 +81,7 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
std::atomic<std::optional<bool>> enableSynchronousStateUpdates_;
|
||||
std::atomic<std::optional<bool>> enableUIConsistency_;
|
||||
std::atomic<std::optional<bool>> fixMappingOfEventPrioritiesBetweenFabricAndReact_;
|
||||
std::atomic<std::optional<bool>> fixMissedFabricStateUpdatesOnAndroid_;
|
||||
std::atomic<std::optional<bool>> fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak_;
|
||||
std::atomic<std::optional<bool>> forceBatchingMountItemsOnAndroid_;
|
||||
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<<0f6ca616cc516096ec250d61be440952>>
|
||||
* @generated SignedSource<<cb2b8b9fc0efdcde70d12724a2ac6768>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -75,6 +75,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fixMissedFabricStateUpdatesOnAndroid() override {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak() 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<<3da295d89796e905588eb863a51c2054>>
|
||||
* @generated SignedSource<<57b9e4f683df27a7a5770633e88f8b22>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -37,6 +37,7 @@ class ReactNativeFeatureFlagsProvider {
|
||||
virtual bool enableSynchronousStateUpdates() = 0;
|
||||
virtual bool enableUIConsistency() = 0;
|
||||
virtual bool fixMappingOfEventPrioritiesBetweenFabricAndReact() = 0;
|
||||
virtual bool fixMissedFabricStateUpdatesOnAndroid() = 0;
|
||||
virtual bool fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak() = 0;
|
||||
virtual bool forceBatchingMountItemsOnAndroid() = 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<<82399968da4f450b87c908031466a38a>>
|
||||
* @generated SignedSource<<58b0c0c49dc6cf2ecdbc2c3038395e4e>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -97,6 +97,11 @@ bool NativeReactNativeFeatureFlags::fixMappingOfEventPrioritiesBetweenFabricAndR
|
||||
return ReactNativeFeatureFlags::fixMappingOfEventPrioritiesBetweenFabricAndReact();
|
||||
}
|
||||
|
||||
bool NativeReactNativeFeatureFlags::fixMissedFabricStateUpdatesOnAndroid(
|
||||
jsi::Runtime& /*runtime*/) {
|
||||
return ReactNativeFeatureFlags::fixMissedFabricStateUpdatesOnAndroid();
|
||||
}
|
||||
|
||||
bool NativeReactNativeFeatureFlags::fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak(
|
||||
jsi::Runtime& /*runtime*/) {
|
||||
return ReactNativeFeatureFlags::fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak();
|
||||
|
||||
+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<<6b8504e42d72611f4d4b6606d69c42aa>>
|
||||
* @generated SignedSource<<eadc2ecdbe5e95fe92224d031733d3b4>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -59,6 +59,8 @@ class NativeReactNativeFeatureFlags
|
||||
|
||||
bool fixMappingOfEventPrioritiesBetweenFabricAndReact(jsi::Runtime& runtime);
|
||||
|
||||
bool fixMissedFabricStateUpdatesOnAndroid(jsi::Runtime& runtime);
|
||||
|
||||
bool fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak(jsi::Runtime& runtime);
|
||||
|
||||
bool forceBatchingMountItemsOnAndroid(jsi::Runtime& runtime);
|
||||
|
||||
@@ -93,6 +93,11 @@ const definitions: FeatureFlagDefinitions = {
|
||||
description:
|
||||
'Uses the default event priority instead of the discreet event priority by default when dispatching events from Fabric to React.',
|
||||
},
|
||||
fixMissedFabricStateUpdatesOnAndroid: {
|
||||
defaultValue: false,
|
||||
description:
|
||||
'Enables a fix to prevent the possibility of state updates in Fabric being missed due to race conditions with previous state updates.',
|
||||
},
|
||||
fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak: {
|
||||
defaultValue: false,
|
||||
description:
|
||||
|
||||
@@ -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<<522f11a571457cb932f451cf81bd384a>>
|
||||
* @generated SignedSource<<95a692d91055d05301a06fd33636d3fa>>
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
@@ -53,6 +53,7 @@ export type ReactNativeFeatureFlags = {
|
||||
enableSynchronousStateUpdates: Getter<boolean>,
|
||||
enableUIConsistency: Getter<boolean>,
|
||||
fixMappingOfEventPrioritiesBetweenFabricAndReact: Getter<boolean>,
|
||||
fixMissedFabricStateUpdatesOnAndroid: Getter<boolean>,
|
||||
fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak: Getter<boolean>,
|
||||
forceBatchingMountItemsOnAndroid: Getter<boolean>,
|
||||
fuseboxEnabledDebug: Getter<boolean>,
|
||||
@@ -161,6 +162,10 @@ export const enableUIConsistency: Getter<boolean> = createNativeFlagGetter('enab
|
||||
* Uses the default event priority instead of the discreet event priority by default when dispatching events from Fabric to React.
|
||||
*/
|
||||
export const fixMappingOfEventPrioritiesBetweenFabricAndReact: Getter<boolean> = createNativeFlagGetter('fixMappingOfEventPrioritiesBetweenFabricAndReact', false);
|
||||
/**
|
||||
* Enables a fix to prevent the possibility of state updates in Fabric being missed due to race conditions with previous state updates.
|
||||
*/
|
||||
export const fixMissedFabricStateUpdatesOnAndroid: Getter<boolean> = createNativeFlagGetter('fixMissedFabricStateUpdatesOnAndroid', false);
|
||||
/**
|
||||
* Fixes a leak in SurfaceMountingManager.mRemoveDeleteTreeUIFrameCallback
|
||||
*/
|
||||
|
||||
+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<<6715ba4954b31464c591597c53a2a0de>>
|
||||
* @generated SignedSource<<cd704035749b46f1be6f940806c88df5>>
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
@@ -35,6 +35,7 @@ export interface Spec extends TurboModule {
|
||||
+enableSynchronousStateUpdates?: () => boolean;
|
||||
+enableUIConsistency?: () => boolean;
|
||||
+fixMappingOfEventPrioritiesBetweenFabricAndReact?: () => boolean;
|
||||
+fixMissedFabricStateUpdatesOnAndroid?: () => boolean;
|
||||
+fixStoppedSurfaceRemoveDeleteTreeUIFrameCallbackLeak?: () => boolean;
|
||||
+forceBatchingMountItemsOnAndroid?: () => boolean;
|
||||
+fuseboxEnabledDebug?: () => boolean;
|
||||
|
||||
Reference in New Issue
Block a user